Browse Source

Merge branch 'master' of https://github.com/RT-Thread/rt-thread into fixed

weety 9 năm trước cách đây
mục cha
commit
94e1935f1f
100 tập tin đã thay đổi với 1206 bổ sung13262 xóa
  1. 58 5
      bsp/stm32f10x/drivers/gpio.c
  2. 226 90
      bsp/stm32f10x/drivers/usart.c
  3. 1 1
      components/dfs/filesystems/net/SConscript
  4. 0 0
      components/dfs/filesystems/net/arpa/inet.h
  5. 22 21
      components/dfs/filesystems/net/dfs_net.c
  6. 8 7
      components/dfs/filesystems/net/dfs_net.h
  7. 0 0
      components/dfs/filesystems/net/net_netdb.c
  8. 2 2
      components/dfs/filesystems/net/net_select.c
  9. 16 16
      components/dfs/filesystems/net/net_sockets.c
  10. 0 0
      components/dfs/filesystems/net/netdb.h
  11. 0 0
      components/dfs/filesystems/net/netinet/in.h
  12. 0 0
      components/dfs/filesystems/net/netinet/tcp.h
  13. 0 0
      components/dfs/filesystems/net/netinet/udp.h
  14. 0 0
      components/dfs/filesystems/net/sys/select.h
  15. 0 0
      components/dfs/filesystems/net/sys/socket.h
  16. 4 0
      components/drivers/include/drivers/mmcsd_core.h
  17. 14 12
      components/drivers/include/drivers/serial.h
  18. 28 2
      components/drivers/sdio/mmcsd_core.c
  19. 201 56
      components/drivers/serial/serial.c
  20. 3 0
      components/drivers/spi/SConscript
  21. 1 1
      components/drivers/spi/enc28j60.c
  22. 36 0
      components/drivers/spi/spi_flash.h
  23. 14 4
      components/drivers/spi/spi_flash_at45dbxx.c
  24. 24 0
      components/drivers/spi/spi_flash_at45dbxx.h
  25. 346 0
      components/drivers/spi/spi_flash_gd.c
  26. 32 0
      components/drivers/spi/spi_flash_gd.h
  27. 14 4
      components/drivers/spi/spi_flash_sst25vfxx.c
  28. 14 4
      components/drivers/spi/spi_flash_sst25vfxx.h
  29. 17 6
      components/drivers/spi/spi_flash_w25qxx.c
  30. 13 13
      components/drivers/spi/spi_flash_w25qxx.h
  31. 2 4
      components/external/cairo/SConscript
  32. 2 3
      components/external/lzo/SConscript
  33. 2 3
      components/external/nanopb/SConscript
  34. 3 0
      components/libc/SConscript
  35. 3 3
      components/libc/libdl/SConscript
  36. 0 0
      components/libc/libdl/dlclose.c
  37. 0 0
      components/libc/libdl/dlerror.c
  38. 0 0
      components/libc/libdl/dlfcn.h
  39. 0 0
      components/libc/libdl/dlopen.c
  40. 0 0
      components/libc/libdl/dlsym.c
  41. 15 0
      components/libc/newlib/syscalls.c
  42. 3 2
      components/libc/pthreads/SConscript
  43. 0 0
      components/libc/pthreads/clock_time.c
  44. 0 0
      components/libc/pthreads/mqueue.c
  45. 0 0
      components/libc/pthreads/mqueue.h
  46. 0 0
      components/libc/pthreads/posix_types.h
  47. 0 0
      components/libc/pthreads/pthread.c
  48. 14 0
      components/libc/pthreads/pthread.h
  49. 0 0
      components/libc/pthreads/pthread_attr.c
  50. 0 0
      components/libc/pthreads/pthread_barrier.c
  51. 0 0
      components/libc/pthreads/pthread_cond.c
  52. 0 0
      components/libc/pthreads/pthread_internal.h
  53. 0 0
      components/libc/pthreads/pthread_mutex.c
  54. 0 0
      components/libc/pthreads/pthread_rwlock.c
  55. 0 0
      components/libc/pthreads/pthread_spin.c
  56. 0 0
      components/libc/pthreads/pthread_tls.c
  57. 0 0
      components/libc/pthreads/sched.c
  58. 0 0
      components/libc/pthreads/sched.h
  59. 0 0
      components/libc/pthreads/semaphore.c
  60. 0 0
      components/libc/pthreads/semaphore.h
  61. 3 2
      components/net/SConscript
  62. 1 1
      components/net/lwip-1.4.1/src/arch/include/arch/cc.h
  63. 6 0
      components/net/lwip-1.4.1/src/core/tcp_out.c
  64. 1 0
      components/net/lwip-1.4.1/src/include/netif/etharp.h
  65. 57 4
      components/net/lwip-1.4.1/src/lwipopts.h
  66. 0 3050
      components/net/lwip/CHANGELOG
  67. 0 33
      components/net/lwip/COPYING
  68. 0 4
      components/net/lwip/FILES
  69. 0 89
      components/net/lwip/README
  70. 0 87
      components/net/lwip/SConscript
  71. 0 144
      components/net/lwip/UPGRADING
  72. 0 7
      components/net/lwip/apps/SConscript
  73. 0 216
      components/net/lwip/apps/chargen.c
  74. 0 985
      components/net/lwip/apps/ftpd.c
  75. 0 370
      components/net/lwip/apps/netio.c
  76. 0 180
      components/net/lwip/apps/ping.c
  77. 0 213
      components/net/lwip/apps/sntp.c
  78. 0 68
      components/net/lwip/apps/tcpecho.c
  79. 0 206
      components/net/lwip/apps/tftp.c
  80. 0 56
      components/net/lwip/apps/udpecho.c
  81. 0 6
      components/net/lwip/doc/FILES
  82. 0 63
      components/net/lwip/doc/contrib.txt
  83. 0 505
      components/net/lwip/doc/rawapi.txt
  84. 0 135
      components/net/lwip/doc/savannah.txt
  85. 0 181
      components/net/lwip/doc/snmp_agent.txt
  86. 0 216
      components/net/lwip/doc/sys_arch.txt
  87. 0 26
      components/net/lwip/src/.hgignore
  88. 0 13
      components/net/lwip/src/FILES
  89. 0 740
      components/net/lwip/src/api/api_lib.c
  90. 0 1535
      components/net/lwip/src/api/api_msg.c
  91. 0 75
      components/net/lwip/src/api/err.c
  92. 0 245
      components/net/lwip/src/api/netbuf.c
  93. 0 352
      components/net/lwip/src/api/netdb.c
  94. 0 160
      components/net/lwip/src/api/netifapi.c
  95. 0 2347
      components/net/lwip/src/api/sockets.c
  96. 0 460
      components/net/lwip/src/api/tcpip.c
  97. 0 35
      components/net/lwip/src/arch/include/arch/bpstruct.h
  98. 0 107
      components/net/lwip/src/arch/include/arch/cc.h
  99. 0 35
      components/net/lwip/src/arch/include/arch/epstruct.h
  100. 0 52
      components/net/lwip/src/arch/include/arch/perf.h

+ 58 - 5
bsp/stm32f10x/drivers/gpio.c

@@ -8,8 +8,9 @@
  * http://www.rt-thread.org/license/LICENSE
  *
  * Change Logs:
- * Date           Author       Notes
- * 2015-03-24     Bright      the first version
+ * Date           Author            Notes
+ * 2015-03-24     Bright            the first version
+ * 2016-05-23     Margguo@gmail.com Add  48 pins IC define
  */
 
 #include <rthw.h>
@@ -19,7 +20,7 @@
 
 #ifdef RT_USING_PIN
 
-#define STM32F10X_PIN_NUMBERS 100 //[ 64, 100, 144 ]
+#define STM32F10X_PIN_NUMBERS 100 //[48, 64, 100, 144 ]
 
 #define __STM32_PIN(index, rcc, gpio, gpio_index) { 0, RCC_##rcc##Periph_GPIO##gpio, GPIO##gpio, GPIO_Pin_##gpio_index}
 #define __STM32_PIN_DEFAULT {-1, 0, 0, 0}
@@ -35,6 +36,58 @@ struct pin_index
 
 static const struct pin_index pins[] =
 {
+#if (STM32F10X_PIN_NUMBERS == 48)
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN(2, APB2, C, 13),
+    __STM32_PIN(3, APB2, C, 14),
+    __STM32_PIN(4, APB2, C, 15),
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN(10, APB2, A, 0),
+    __STM32_PIN(11, APB2, A, 1),
+    __STM32_PIN(12, APB2, A, 2),
+    __STM32_PIN(13, APB2, A, 3),
+    __STM32_PIN(14, APB2, A, 4),
+    __STM32_PIN(15, APB2, A, 5),
+    __STM32_PIN(16, APB2, A, 6),
+    __STM32_PIN(17, APB2, A, 7),
+    __STM32_PIN(18, APB2, B, 0),
+    __STM32_PIN(19, APB2, B, 1),
+    __STM32_PIN(20, APB2, B, 2),
+    __STM32_PIN(21, APB2, B, 10),
+    __STM32_PIN(22, APB2, B, 11),
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN(25, APB2, B, 12),
+    __STM32_PIN(26, APB2, B, 13),
+    __STM32_PIN(27, APB2, B, 14),
+    __STM32_PIN(28, APB2, B, 15),
+    __STM32_PIN(29, APB2, A, 8),
+    __STM32_PIN(30, APB2, A, 9),
+    __STM32_PIN(31, APB2, A, 10),
+    __STM32_PIN(32, APB2, A, 11),
+    __STM32_PIN(33, APB2, A, 12),
+    __STM32_PIN(34, APB2, A, 13),
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN(37, APB2, A, 14),
+    __STM32_PIN(38, APB2, A, 15),
+    __STM32_PIN(39, APB2, B, 3),
+    __STM32_PIN(40, APB2, B, 4),
+    __STM32_PIN(41, APB2, B, 5),
+    __STM32_PIN(42, APB2, B, 6),
+    __STM32_PIN(43, APB2, B, 7),
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN(45, APB2, B, 8),
+    __STM32_PIN(46, APB2, B, 9),
+    __STM32_PIN_DEFAULT,
+    __STM32_PIN_DEFAULT,
+
+#endif
 #if (STM32F10X_PIN_NUMBERS == 64)
     __STM32_PIN_DEFAULT,
     __STM32_PIN_DEFAULT,
@@ -216,7 +269,7 @@ static const struct pin_index pins[] =
     __STM32_PIN(7, APB2, C, 13),
     __STM32_PIN(8, APB2, C, 14),
     __STM32_PIN(9, APB2, C, 15),
-    
+
     __STM32_PIN(10, APB2, F, 0),
     __STM32_PIN(11, APB2, F, 1),
     __STM32_PIN(12, APB2, F, 2),
@@ -472,7 +525,7 @@ const static struct rt_pin_ops _stm32_pin_ops =
 int stm32_hw_pin_init(void)
 {
     int result;
-    
+
     result = rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
     return result;
 }

+ 226 - 90
bsp/stm32f10x/drivers/usart.c

@@ -13,6 +13,7 @@
  * 2010-03-29     Bernard      remove interrupt Tx and DMA Rx mode
  * 2013-05-13     aozima       update for kehong-lingtai.
  * 2015-01-31     armink       make sure the serial transmit complete in putc()
+ * 2016-05-13     armink       add DMA Rx mode
  */
 
 #include "stm32f10x.h"
@@ -44,10 +45,22 @@
 /* STM32 uart driver */
 struct stm32_uart
 {
-    USART_TypeDef* uart_device;
+    USART_TypeDef *uart_device;
     IRQn_Type irq;
+    struct stm32_uart_dma {
+        /* dma channel */
+        DMA_Channel_TypeDef *rx_ch;
+        /* dma global flag */
+        uint32_t rx_gl_flag;
+        /* dma irq channel */
+        uint8_t rx_irq_ch;
+        /* last receive index */
+        rt_size_t last_recv_len;
+    } dma;
 };
 
+static void DMA_Configuration(struct rt_serial_device *serial);
+
 static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
 {
     struct stm32_uart* uart;
@@ -93,6 +106,7 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c
 static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *arg)
 {
     struct stm32_uart* uart;
+    rt_uint32_t ctrl_arg = (rt_uint32_t)(arg);
 
     RT_ASSERT(serial != RT_NULL);
     uart = (struct stm32_uart *)serial->parent.user_data;
@@ -113,8 +127,13 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
         /* enable interrupt */
         USART_ITConfig(uart->uart_device, USART_IT_RXNE, ENABLE);
         break;
+        /* USART config */
+    case RT_DEVICE_CTRL_CONFIG :
+        if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) {
+            DMA_Configuration(serial);
+        }
+        break;
     }
-
     return RT_EOK;
 }
 
@@ -148,6 +167,91 @@ static int stm32_getc(struct rt_serial_device *serial)
     return ch;
 }
 
+/**
+ * Serial port receive idle process. This need add to uart idle ISR.
+ *
+ * @param serial serial device
+ */
+static void dma_uart_rx_idle_isr(struct rt_serial_device *serial) {
+    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;
+    rt_size_t recv_total_len, recv_len;
+    /* disable dma, stop receive data */
+    DMA_Cmd(uart->dma.rx_ch, DISABLE);
+
+    recv_total_len = serial->config.bufsz - DMA_GetCurrDataCounter(uart->dma.rx_ch);
+    if (recv_total_len > uart->dma.last_recv_len) {
+        recv_len = recv_total_len - uart->dma.last_recv_len;
+    } else {
+        recv_len = recv_total_len;
+    }
+    uart->dma.last_recv_len = recv_total_len;
+
+    rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
+
+    /* read a data for clear receive idle interrupt flag */
+    USART_ReceiveData(uart->uart_device);
+    DMA_ClearFlag(uart->dma.rx_gl_flag);
+    DMA_Cmd(uart->dma.rx_ch, ENABLE);
+}
+
+/**
+ * DMA receive done process. This need add to DMA receive done ISR.
+ *
+ * @param serial serial device
+ */
+static void dma_rx_done_isr(struct rt_serial_device *serial) {
+    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;
+    rt_size_t recv_total_len, recv_len;
+    /* disable dma, stop receive data */
+    DMA_Cmd(uart->dma.rx_ch, DISABLE);
+
+    recv_total_len = serial->config.bufsz - DMA_GetCurrDataCounter(uart->dma.rx_ch);
+    if (recv_total_len > uart->dma.last_recv_len) {
+        recv_len = recv_total_len - uart->dma.last_recv_len;
+    } else {
+        recv_len = recv_total_len;
+    }
+    uart->dma.last_recv_len = recv_total_len;
+
+    rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
+
+    DMA_ClearFlag(uart->dma.rx_gl_flag);
+    /* reload */
+    DMA_SetCurrDataCounter(uart->dma.rx_ch, serial->config.bufsz);
+    DMA_Cmd(uart->dma.rx_ch, ENABLE);
+}
+
+/**
+ * Uart common interrupt process. This need add to uart ISR.
+ *
+ * @param serial serial device
+ */
+static void uart_isr(struct rt_serial_device *serial) {
+    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;
+
+    RT_ASSERT(uart != RT_NULL);
+
+    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
+    {
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+        /* clear interrupt */
+        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
+    }
+    if(USART_GetITStatus(uart->uart_device, USART_IT_IDLE) != RESET)
+    {
+        dma_uart_rx_idle_isr(serial);
+    }
+    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
+    {
+        /* clear interrupt */
+        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
+    }
+    if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
+    {
+        stm32_getc(serial);
+    }
+}
+
 static const struct rt_uart_ops stm32_uart_ops =
 {
     stm32_configure,
@@ -162,70 +266,68 @@ struct stm32_uart uart1 =
 {
     USART1,
     USART1_IRQn,
+    {
+        DMA1_Channel5,
+        DMA1_FLAG_GL5,
+        DMA1_Channel5_IRQn,
+        0,
+    },
 };
 struct rt_serial_device serial1;
 
 void USART1_IRQHandler(void)
 {
-    struct stm32_uart* uart;
+    /* enter interrupt */
+    rt_interrupt_enter();
 
-    uart = &uart1;
+    uart_isr(&serial1);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
 
+void DMA1_Channel5_IRQHandler(void) {
     /* enter interrupt */
     rt_interrupt_enter();
-    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
-    {
-        rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
-    }
 
-    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
-    {
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
-    }
-    if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
-    {
-        stm32_getc(&serial1);
-    }
+    dma_rx_done_isr(&serial1);
+
     /* leave interrupt */
     rt_interrupt_leave();
 }
 #endif /* RT_USING_UART1 */
 
 #if defined(RT_USING_UART2)
-/* UART1 device driver structure */
+/* UART2 device driver structure */
 struct stm32_uart uart2 =
 {
     USART2,
     USART2_IRQn,
+    {
+        DMA1_Channel6,
+        DMA1_FLAG_GL6,
+        DMA1_Channel6_IRQn,
+        0,
+    },
 };
 struct rt_serial_device serial2;
 
 void USART2_IRQHandler(void)
 {
-    struct stm32_uart* uart;
+    /* enter interrupt */
+    rt_interrupt_enter();
 
-    uart = &uart2;
+    uart_isr(&serial2);
 
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+void DMA1_Channel6_IRQHandler(void) {
     /* enter interrupt */
     rt_interrupt_enter();
-    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
-    {
-        rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
-    }
-    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
-    {
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
-    }
-    if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
-    {
-        stm32_getc(&serial2);
-    }
+
+    dma_rx_done_isr(&serial2);
 
     /* leave interrupt */
     rt_interrupt_leave();
@@ -238,32 +340,31 @@ struct stm32_uart uart3 =
 {
     USART3,
     USART3_IRQn,
+    {
+        DMA1_Channel3,
+        DMA1_FLAG_GL3,
+        DMA1_Channel3_IRQn,
+        0,
+    },
 };
 struct rt_serial_device serial3;
 
 void USART3_IRQHandler(void)
 {
-    struct stm32_uart* uart;
+    /* enter interrupt */
+    rt_interrupt_enter();
 
-    uart = &uart3;
+    uart_isr(&serial3);
 
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+void DMA1_Channel3_IRQHandler(void) {
     /* enter interrupt */
     rt_interrupt_enter();
-    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
-    {
-        rt_hw_serial_isr(&serial3, RT_SERIAL_EVENT_RX_IND);
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
-    }
-    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
-    {
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
-    }
-    if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
-    {
-        stm32_getc(&serial3);
-    }
+
+    dma_rx_done_isr(&serial3);
 
     /* leave interrupt */
     rt_interrupt_leave();
@@ -276,69 +377,66 @@ struct stm32_uart uart4 =
 {
     UART4,
     UART4_IRQn,
+    {
+        DMA2_Channel3,
+        DMA2_FLAG_GL3,
+        DMA2_Channel3_IRQn,
+        0,
+    },
 };
 struct rt_serial_device serial4;
 
 void UART4_IRQHandler(void)
 {
-    struct stm32_uart* uart;
+    /* enter interrupt */
+    rt_interrupt_enter();
 
-    uart = &uart4;
+    uart_isr(&serial4);
 
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+void DMA2_Channel3_IRQHandler(void) {
     /* enter interrupt */
     rt_interrupt_enter();
-    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
-    {
-        rt_hw_serial_isr(&serial4, RT_SERIAL_EVENT_RX_IND);
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
-    }
-    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
-    {
-        /* clear interrupt */
-        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
-    }
-    if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
-    {
-        stm32_getc(&serial4);
-    }
+
+    dma_rx_done_isr(&serial4);
 
     /* leave interrupt */
     rt_interrupt_leave();
 }
-#endif /* RT_USING_UART3 */
-
+#endif /* RT_USING_UART4 */
 
 static void RCC_Configuration(void)
 {
 #if defined(RT_USING_UART1)
     /* Enable UART GPIO clocks */
-    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
     /* Enable UART clock */
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
 #endif /* RT_USING_UART1 */
 
 #if defined(RT_USING_UART2)
     /* Enable UART GPIO clocks */
-    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
     /* Enable UART clock */
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
 #endif /* RT_USING_UART2 */
 
 #if defined(RT_USING_UART3)
     /* Enable UART GPIO clocks */
-    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
     /* Enable UART clock */
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
 #endif /* RT_USING_UART3 */
 
 #if defined(RT_USING_UART4)
     /* Enable UART GPIO clocks */
-    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
     /* Enable UART clock */
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
 #endif /* RT_USING_UART4 */
-
 }
 
 static void GPIO_Configuration(void)
@@ -390,7 +488,6 @@ static void GPIO_Configuration(void)
     GPIO_InitStructure.GPIO_Pin = UART4_GPIO_TX;
     GPIO_Init(UART4_GPIO, &GPIO_InitStructure);
 #endif /* RT_USING_UART4 */
-
 }
 
 static void NVIC_Configuration(struct stm32_uart* uart)
@@ -405,6 +502,46 @@ static void NVIC_Configuration(struct stm32_uart* uart)
     NVIC_Init(&NVIC_InitStructure);
 }
 
+static void DMA_Configuration(struct rt_serial_device *serial) {
+    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;
+    struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
+    DMA_InitTypeDef DMA_InitStructure;
+    NVIC_InitTypeDef NVIC_InitStructure;
+
+    /* enable transmit idle interrupt */
+    USART_ITConfig(uart->uart_device, USART_IT_IDLE , ENABLE);
+
+    /* DMA clock enable */
+    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
+    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
+
+    /* rx dma config */
+    DMA_DeInit(uart->dma.rx_ch);
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(uart->uart_device->DR);
+    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) rx_fifo->buffer;
+    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
+    DMA_InitStructure.DMA_BufferSize = serial->config.bufsz;
+    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
+    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
+    DMA_Init(uart->dma.rx_ch, &DMA_InitStructure);
+    DMA_ClearFlag(uart->dma.rx_gl_flag);
+    DMA_ITConfig(uart->dma.rx_ch, DMA_IT_TC, ENABLE);
+    USART_DMACmd(uart->uart_device, USART_DMAReq_Rx, ENABLE);
+    DMA_Cmd(uart->dma.rx_ch, ENABLE);
+
+    /* rx dma interrupt config */
+    NVIC_InitStructure.NVIC_IRQChannel = uart->dma.rx_irq_ch;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+}
+
 void rt_hw_usart_init(void)
 {
     struct stm32_uart* uart;
@@ -420,11 +557,11 @@ void rt_hw_usart_init(void)
     serial1.ops    = &stm32_uart_ops;
     serial1.config = config;
 
-    NVIC_Configuration(&uart1);
+    NVIC_Configuration(uart);
 
     /* register UART1 device */
     rt_hw_serial_register(&serial1, "uart1",
-                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX ,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX,
                           uart);
 #endif /* RT_USING_UART1 */
 
@@ -435,11 +572,11 @@ void rt_hw_usart_init(void)
     serial2.ops    = &stm32_uart_ops;
     serial2.config = config;
 
-    NVIC_Configuration(&uart2);
+    NVIC_Configuration(uart);
 
-    /* register UART1 device */
+    /* register UART2 device */
     rt_hw_serial_register(&serial2, "uart2",
-                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX,
                           uart);
 #endif /* RT_USING_UART2 */
 
@@ -451,11 +588,11 @@ void rt_hw_usart_init(void)
     serial3.ops    = &stm32_uart_ops;
     serial3.config = config;
 
-    NVIC_Configuration(&uart3);
+    NVIC_Configuration(uart);
 
-    /* register UART1 device */
+    /* register UART3 device */
     rt_hw_serial_register(&serial3, "uart3",
-                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX,
                           uart);
 #endif /* RT_USING_UART3 */
 
@@ -467,12 +604,11 @@ void rt_hw_usart_init(void)
     serial4.ops    = &stm32_uart_ops;
     serial4.config = config;
 
-    NVIC_Configuration(&uart4);
+    NVIC_Configuration(uart);
 
     /* register UART4 device */
     rt_hw_serial_register(&serial4, "uart4",
-                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX,
                           uart);
 #endif /* RT_USING_UART4 */
-
 }

+ 1 - 1
components/dfs/filesystems/lwip/SConscript → components/dfs/filesystems/net/SConscript

@@ -6,6 +6,6 @@ cwd = GetCurrentDir()
 src = Glob('*.c')
 CPPPATH = [cwd]
 
-group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_LWIP'], CPPPATH = CPPPATH)
+group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_NET'], CPPPATH = CPPPATH)
 
 Return('group')

+ 0 - 0
components/dfs/filesystems/lwip/arpa/inet.h → components/dfs/filesystems/net/arpa/inet.h


+ 22 - 21
components/dfs/filesystems/lwip/dfs_lwip.c → components/dfs/filesystems/net/dfs_net.c

@@ -1,7 +1,7 @@
 /*
- * File      : dfs_lwip.c
+ * File      : dfs_net.c
  * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2015, RT-Thread Development Team
+ * COPYRIGHT (C) 2015-2016, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -20,15 +20,16 @@
  * Change Logs:
  * Date           Author       Notes
  * 2015-02-17     Bernard      First version
+ * 2016-05-07     Bernard      Rename dfs_lwip to dfs_net
  */
 
 #include <rtthread.h>
 #include <dfs.h>
 #include <dfs_fs.h>
 
-#include "dfs_lwip.h"
+#include "dfs_net.h"
 
-int dfs_lwip_getsocket(int fd)
+int dfs_net_getsocket(int fd)
 {
     struct dfs_fd *_dfs_fd; 
     
@@ -40,12 +41,12 @@ int dfs_lwip_getsocket(int fd)
     return (int)_dfs_fd->data;
 }
 
-int dfs_lwip_ioctl(struct dfs_fd* file, int cmd, void* args)
+int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args)
 {
     return -DFS_STATUS_EIO;
 }
 
-int dfs_lwip_read(struct dfs_fd* file, void *buf, rt_size_t count)
+int dfs_net_read(struct dfs_fd* file, void *buf, rt_size_t count)
 {
     int sock;
 
@@ -55,7 +56,7 @@ int dfs_lwip_read(struct dfs_fd* file, void *buf, rt_size_t count)
     return count;
 }
 
-int dfs_lwip_write(struct dfs_fd *file, const void *buf, rt_size_t count)
+int dfs_net_write(struct dfs_fd *file, const void *buf, rt_size_t count)
 {
     int sock;
     
@@ -65,7 +66,7 @@ int dfs_lwip_write(struct dfs_fd *file, const void *buf, rt_size_t count)
     return count;
 }
 
-int dfs_lwip_close(struct dfs_fd* file)
+int dfs_net_close(struct dfs_fd* file)
 {
     int sock;
     int result;
@@ -78,9 +79,9 @@ int dfs_lwip_close(struct dfs_fd* file)
     return -result;
 }
 
-static const struct dfs_filesystem_operation _lwip_fs_ops = 
+static const struct dfs_filesystem_operation _net_fs_ops = 
 {
-    "lwip",
+    "net",
     DFS_FS_FLAG_DEFAULT,
     RT_NULL,    /* mount    */
     RT_NULL,    /* unmont   */
@@ -88,10 +89,10 @@ static const struct dfs_filesystem_operation _lwip_fs_ops =
     RT_NULL,    /* statfs   */
 
     RT_NULL,    /* open     */
-    dfs_lwip_close,
-    dfs_lwip_ioctl,
-    dfs_lwip_read,
-    dfs_lwip_write,
+    dfs_net_close,
+    dfs_net_ioctl,
+    dfs_net_read,
+    dfs_net_write,
     RT_NULL,
     RT_NULL,    /* lseek    */
     RT_NULL,    /* getdents */
@@ -100,28 +101,28 @@ static const struct dfs_filesystem_operation _lwip_fs_ops =
     RT_NULL,    /* rename   */
 };
 
-static struct dfs_filesystem _lwip_fs = 
+static struct dfs_filesystem _net_fs = 
 {
     0,              /* dev_id */
     RT_NULL,        /* path */
-    &_lwip_fs_ops,
+    &_net_fs_ops,
     RT_NULL         /* data */
 };
 
-struct dfs_filesystem* dfs_lwip_get_fs(void)
+struct dfs_filesystem* dfs_net_get_fs(void)
 {
-    return &_lwip_fs;
+    return &_net_fs;
 }
 
 /*
 NOTE: Beause we don't need to mount lwIP file system, the filesystem_ops is not 
 registered to the system. 
 
-int dfs_lwip_system_init(void)
+int dfs_net_system_init(void)
 {
-    dfs_register(&_lwip_fs_ops);
+    dfs_register(&_net_fs_ops);
     
     return 0;
 }
-INIT_FS_EXPORT(dfs_lwip_system_init);
+INIT_FS_EXPORT(dfs_net_system_init);
 */

+ 8 - 7
components/dfs/filesystems/lwip/dfs_lwip.h → components/dfs/filesystems/net/dfs_net.h

@@ -1,7 +1,7 @@
 /*
- * File      : dfs_lwip.h
+ * File      : dfs_net.h
  * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2015, RT-Thread Development Team
+ * COPYRIGHT (C) 2015-2016, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -20,10 +20,11 @@
  * Change Logs:
  * Date           Author       Notes
  * 2015-02-17     Bernard      First version
+ * 2016-05-05     Bernard      rename dfs_lwip to dfs_net.
  */
 
-#ifndef DFS_LWIP_H__
-#define DFS_LWIP_H__
+#ifndef DFS_NET_H__
+#define DFS_NET_H__
 
 #ifdef __cplusplus
 extern "C" {
@@ -31,10 +32,10 @@ extern "C" {
 
 #include <lwip/sockets.h>
 
-struct dfs_filesystem* dfs_lwip_get_fs(void);
-int dfs_lwip_getsocket(int fd);
+struct dfs_filesystem* dfs_net_get_fs(void);
+int dfs_net_getsocket(int fd);
 
-int dfs_lwip_system_init(void);
+int dfs_net_system_init(void);
 
 #ifdef __cplusplus
 }

+ 0 - 0
components/dfs/filesystems/lwip/lwip_netdb.c → components/dfs/filesystems/net/net_netdb.c


+ 2 - 2
components/dfs/filesystems/lwip/lwip_select.c → components/dfs/filesystems/net/net_select.c

@@ -27,7 +27,7 @@
 
 #ifdef RT_USING_LWIP
 
-#include "dfs_lwip.h"
+#include "dfs_net.h"
 
 int
 select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
@@ -48,7 +48,7 @@ select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
     for (index = 0; index < maxfdp1; index ++)
     {
         /* convert fd to sock */
-        sock = dfs_lwip_getsocket(index);
+        sock = dfs_net_getsocket(index);
         if (sock == -1) continue;
 
         if (sock > maxfd) maxfd = sock;

+ 16 - 16
components/dfs/filesystems/lwip/lwip_sockets.c → components/dfs/filesystems/net/net_sockets.c

@@ -28,12 +28,12 @@
 
 #include <sys/socket.h>
 
-#include "dfs_lwip.h"
+#include "dfs_net.h"
 
 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 {
     int new_client = -1;
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     new_client = lwip_accept(sock, addr, addrlen);
     if (new_client != -1)
@@ -58,7 +58,7 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
         d->type = FT_SOCKET;
         d->path = RT_NULL;
 
-        d->fs = dfs_lwip_get_fs();
+        d->fs = dfs_net_get_fs();
 
         d->flags = DFS_O_RDWR; /* set flags as read and write */
         d->size = 0;
@@ -79,7 +79,7 @@ RTM_EXPORT(accept);
 
 int bind(int s, const struct sockaddr *name, socklen_t namelen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_bind(sock, name, namelen);
 }
@@ -98,7 +98,7 @@ int shutdown(int s, int how)
         return -1;
     }
 
-    sock = dfs_lwip_getsocket(s);
+    sock = dfs_net_getsocket(s);
     if (lwip_shutdown(sock, how) == 0)
     {
         /* socket has been closed, delete it from file system fd */
@@ -114,7 +114,7 @@ RTM_EXPORT(shutdown);
 
 int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_getpeername(sock, name, namelen);
 }
@@ -122,7 +122,7 @@ RTM_EXPORT(getpeername);
 
 int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_getsockname(sock, name, namelen);
 }
@@ -130,7 +130,7 @@ RTM_EXPORT(getsockname);
 
 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_getsockopt(sock, level, optname, optval, optlen);
 }
@@ -138,7 +138,7 @@ RTM_EXPORT(getsockopt);
 
 int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_setsockopt(sock, level, optname, optval, optlen);
 }
@@ -146,7 +146,7 @@ RTM_EXPORT(setsockopt);
 
 int connect(int s, const struct sockaddr *name, socklen_t namelen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_connect(sock, name, namelen);
 }
@@ -154,7 +154,7 @@ RTM_EXPORT(connect);
 
 int listen(int s, int backlog)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_listen(sock, backlog);
 }
@@ -162,7 +162,7 @@ RTM_EXPORT(listen);
 
 int recv(int s, void *mem, size_t len, int flags)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_recv(sock, mem, len, flags);
 }
@@ -171,7 +171,7 @@ RTM_EXPORT(recv);
 int recvfrom(int s, void *mem, size_t len, int flags,
              struct sockaddr *from, socklen_t *fromlen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_recvfrom(sock, mem, len, flags, from, fromlen);
 }
@@ -179,7 +179,7 @@ RTM_EXPORT(recvfrom);
 
 int send(int s, const void *dataptr, size_t size, int flags)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_send(sock, dataptr, size, flags);
 }
@@ -188,7 +188,7 @@ RTM_EXPORT(send);
 int sendto(int s, const void *dataptr, size_t size, int flags,
            const struct sockaddr *to, socklen_t tolen)
 {
-    int sock = dfs_lwip_getsocket(s);
+    int sock = dfs_net_getsocket(s);
 
     return lwip_sendto(sock, dataptr, size, flags, to, tolen);
 }
@@ -219,7 +219,7 @@ int socket(int domain, int type, int protocol)
         d->type = FT_SOCKET;
         d->path = RT_NULL;
 
-        d->fs = dfs_lwip_get_fs();
+        d->fs = dfs_net_get_fs();
 
         d->flags = DFS_O_RDWR; /* set flags as read and write */
         d->size = 0;

+ 0 - 0
components/dfs/filesystems/lwip/netdb.h → components/dfs/filesystems/net/netdb.h


+ 0 - 0
components/dfs/filesystems/lwip/netinet/in.h → components/dfs/filesystems/net/netinet/in.h


+ 0 - 0
components/dfs/filesystems/lwip/netinet/tcp.h → components/dfs/filesystems/net/netinet/tcp.h


+ 0 - 0
components/dfs/filesystems/lwip/netinet/udp.h → components/dfs/filesystems/net/netinet/udp.h


+ 0 - 0
components/dfs/filesystems/lwip/sys/select.h → components/dfs/filesystems/net/sys/select.h


+ 0 - 0
components/dfs/filesystems/lwip/sys/socket.h → components/dfs/filesystems/net/sys/socket.h


+ 4 - 0
components/drivers/include/drivers/mmcsd_core.h

@@ -220,6 +220,10 @@ rt_inline rt_uint32_t fls(rt_uint32_t val)
 	return bit;
 }
 
+#define MMCSD_HOST_PLUGED       0
+#define MMCSD_HOST_UNPLUGED     1
+
+int mmcsd_wait_cd_changed(rt_int32_t timeout);
 void mmcsd_host_lock(struct rt_mmcsd_host *host);
 void mmcsd_host_unlock(struct rt_mmcsd_host *host);
 void mmcsd_req_complete(struct rt_mmcsd_host *host);

+ 14 - 12
components/drivers/include/drivers/serial.h

@@ -33,12 +33,15 @@
 #define BAUD_RATE_2400                  2400
 #define BAUD_RATE_4800                  4800
 #define BAUD_RATE_9600                  9600
+#define BAUD_RATE_19200                 19200
 #define BAUD_RATE_38400                 38400
 #define BAUD_RATE_57600                 57600
 #define BAUD_RATE_115200                115200
 #define BAUD_RATE_230400                230400
 #define BAUD_RATE_460800                460800
 #define BAUD_RATE_921600                921600
+#define BAUD_RATE_2000000               2000000
+#define BAUD_RATE_3000000               3000000
 
 #define DATA_BITS_5                     5
 #define DATA_BITS_6                     6
@@ -106,7 +109,7 @@ struct serial_configure
     rt_uint32_t parity                  :2;
     rt_uint32_t bit_order               :1;
     rt_uint32_t invert                  :1;
-	rt_uint32_t bufsz					:16;
+    rt_uint32_t bufsz                   :16;
     rt_uint32_t reserved                :4;
 };
 
@@ -115,15 +118,15 @@ struct serial_configure
  */
 struct rt_serial_rx_fifo
 {
-	/* software fifo */
-	rt_uint8_t *buffer;
+    /* software fifo */
+    rt_uint8_t *buffer;
 
-	rt_uint16_t put_index, get_index;
+    rt_uint16_t put_index, get_index;
 };
 
 struct rt_serial_tx_fifo
 {
-	struct rt_completion completion;
+    struct rt_completion completion;
 };
 
 /* 
@@ -131,13 +134,13 @@ struct rt_serial_tx_fifo
  */
 struct rt_serial_rx_dma
 {
-	rt_bool_t activated;
+    rt_bool_t activated;
 };
 
 struct rt_serial_tx_dma
 {
-	rt_bool_t activated;
-	struct rt_data_queue data_queue;
+    rt_bool_t activated;
+    struct rt_data_queue data_queue;
 };
 
 struct rt_serial_device
@@ -147,8 +150,8 @@ struct rt_serial_device
     const struct rt_uart_ops *ops;
     struct serial_configure   config;
 
-	void *serial_rx;
-	void *serial_tx;
+    void *serial_rx;
+    void *serial_tx;
 };
 typedef struct rt_serial_device rt_serial_t;
 
@@ -163,7 +166,7 @@ struct rt_uart_ops
     int (*putc)(struct rt_serial_device *serial, char c);
     int (*getc)(struct rt_serial_device *serial);
 
-    rt_size_t (*dma_transmit)(struct rt_serial_device *serial, const rt_uint8_t *buf, rt_size_t size, int direction);
+    rt_size_t (*dma_transmit)(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
 };
 
 void rt_hw_serial_isr(struct rt_serial_device *serial, int event);
@@ -174,4 +177,3 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
                                void                    *data);
 
 #endif
-

+ 28 - 2
components/drivers/sdio/mmcsd_core.c

@@ -44,6 +44,8 @@ static struct rt_thread mmcsd_detect_thread;
 static rt_uint8_t mmcsd_stack[RT_MMCSD_STACK_SIZE];
 static struct rt_mailbox  mmcsd_detect_mb;
 static rt_uint32_t mmcsd_detect_mb_pool[4];
+static struct rt_mailbox mmcsd_hotpluge_mb;
+static rt_uint32_t mmcsd_hotpluge_mb_pool[4];
 
 void mmcsd_host_lock(struct rt_mmcsd_host *host)
 {
@@ -594,6 +596,24 @@ static void mmcsd_power_off(struct rt_mmcsd_host *host)
     mmcsd_set_iocfg(host);
 }
 
+int mmcsd_wait_cd_changed(rt_int32_t timeout)
+{
+    struct rt_mmcsd_host *host;
+    if (rt_mb_recv(&mmcsd_hotpluge_mb, (rt_uint32_t*)&host, timeout) == RT_EOK)
+    {
+        if(host->card == RT_NULL)
+        {
+            return MMCSD_HOST_UNPLUGED;
+        }
+        else
+        {
+            return MMCSD_HOST_PLUGED;
+        }
+    }
+    return -RT_ETIMEOUT;
+}
+RTM_EXPORT(mmcsd_wait_cd_changed);
+
 void mmcsd_change(struct rt_mmcsd_host *host)
 {
     rt_mb_send(&mmcsd_detect_mb, (rt_uint32_t)host);
@@ -647,6 +667,7 @@ void mmcsd_detect(void *param)
                     if (init_mmc(host, ocr))
                         mmcsd_power_off(host);
                     mmcsd_host_unlock(host);
+                    rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
                     continue;
                 }
                 mmcsd_host_unlock(host);
@@ -667,6 +688,7 @@ void mmcsd_detect(void *param)
             		host->card = RT_NULL;
             	}
             	mmcsd_host_unlock(host);
+            	rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
             }
         }
     }
@@ -711,11 +733,15 @@ void rt_mmcsd_core_init(void)
     /* initialize detect SD cart thread */
     /* initialize mailbox and create detect SD card thread */
     ret = rt_mb_init(&mmcsd_detect_mb, "mmcsdmb",
-        &mmcsd_detect_mb_pool[0], sizeof(mmcsd_detect_mb_pool),
+        &mmcsd_detect_mb_pool[0], sizeof(mmcsd_detect_mb_pool) / sizeof(mmcsd_detect_mb_pool[0]),
         RT_IPC_FLAG_FIFO);
     RT_ASSERT(ret == RT_EOK);
 
-    ret = rt_thread_init(&mmcsd_detect_thread, "mmcsd_detect", mmcsd_detect, RT_NULL, 
+   ret = rt_mb_init(&mmcsd_hotpluge_mb, "mmcsdhotplugmb",
+        &mmcsd_hotpluge_mb_pool[0], sizeof(mmcsd_hotpluge_mb_pool) / sizeof(mmcsd_hotpluge_mb_pool[0]),
+        RT_IPC_FLAG_FIFO);
+    RT_ASSERT(ret == RT_EOK);
+     ret = rt_thread_init(&mmcsd_detect_thread, "mmcsd_detect", mmcsd_detect, RT_NULL, 
                  &mmcsd_stack[0], RT_MMCSD_STACK_SIZE, RT_MMCSD_THREAD_PREORITY, 20);
     if (ret == RT_EOK) 
     {

+ 201 - 56
components/drivers/serial/serial.c

@@ -27,9 +27,10 @@
  *                             the size of ring buffer.
  * 2014-07-10     bernard      rewrite serial framework
  * 2014-12-31     bernard      use open_flag for poll_tx stream mode.
- * 2015-05-19     Quintin      fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG 
+ * 2015-05-19     Quintin      fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG
  *                             in open function.
  * 2015-11-10     bernard      fix the poll rx issue when there is no data.
+ * 2016-05-10     armink       add fifo mode to DMA rx when serial->config.bufsz != 0.
  */
 
 #include <rthw.h>
@@ -37,13 +38,13 @@
 #include <rtdevice.h>
 
 /*
- * Serial poll routines 
+ * Serial poll routines
  */
 rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
 {
     int ch;
     int size;
-    
+
     RT_ASSERT(serial != RT_NULL);
     size = length;
 
@@ -52,7 +53,7 @@ rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data,
         ch = serial->ops->getc(serial);
         if (ch == -1) break;
 
-        *data = ch; 
+        *data = ch;
         data ++; length --;
 
         if (ch == '\n') break;
@@ -77,9 +78,9 @@ rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t
         {
             serial->ops->putc(serial, '\r');
         }
-    
+
         serial->ops->putc(serial, *data);
-    
+
         ++ data;
         -- length;
     }
@@ -96,8 +97,8 @@ rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data,
     struct rt_serial_rx_fifo* rx_fifo;
 
     RT_ASSERT(serial != RT_NULL);
-    size = length; 
-    
+    size = length;
+
     rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx;
     RT_ASSERT(rx_fifo != RT_NULL);
 
@@ -136,7 +137,7 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *
 {
     int size;
     struct rt_serial_tx_fifo *tx;
-    
+
     RT_ASSERT(serial != RT_NULL);
 
     size = length;
@@ -157,32 +158,136 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *
     return size - length;
 }
 
+/**
+ * Calculate DMA received data length.
+ *
+ * @param serial serial device
+ *
+ * @return length
+ */
+static rt_size_t rt_dma_calc_recved_len(struct rt_serial_device *serial) {
+    static rt_size_t rx_length;
+    struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
+
+    RT_ASSERT(rx_fifo != RT_NULL);
+
+    rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):
+                        (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
+    return rx_length;
+}
+
+/**
+ * Read data finish by DMA mode then update the gut index for receive fifo.
+ *
+ * @param serial serial device
+ * @param len get data length for this operate
+ */
+static void rt_dma_recv_update_get_index(struct rt_serial_device *serial, rt_size_t len) {
+    struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
+
+    RT_ASSERT(rx_fifo != RT_NULL);
+    RT_ASSERT(len <= rt_dma_calc_recved_len(serial));
+
+    rx_fifo->get_index += len;
+    if (rx_fifo->get_index > serial->config.bufsz ) {
+        rx_fifo->get_index -= serial->config.bufsz;
+    }
+}
+
+/**
+ * DMA received finish then update put index for receive fifo.
+ *
+ * @param serial serial device
+ * @param len received length for this transmit
+ */
+static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_size_t len) {
+    struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
+    rt_size_t i;
+
+    RT_ASSERT(rx_fifo != RT_NULL);
+
+    if (rx_fifo->get_index <= rx_fifo->put_index) {
+        rx_fifo->put_index += len;
+        /* beyond the fifo end */
+        if (rx_fifo->put_index >= serial->config.bufsz) {
+            for (i = 0; i <= len / serial->config.bufsz; i++) {
+                rx_fifo->put_index -= serial->config.bufsz;
+            }
+            /* force overwrite get index */
+            if (rx_fifo->put_index >= rx_fifo->get_index) {
+                rx_fifo->get_index = rx_fifo->put_index + 1;
+            }
+        }
+    } else {
+        rx_fifo->put_index += len;
+        if(rx_fifo->put_index >= rx_fifo->get_index) {
+            /* beyond the fifo end */
+            if(rx_fifo->put_index >= serial->config.bufsz) {
+                for (i = 0; i <= len / serial->config.bufsz; i++) {
+                    rx_fifo->put_index -= serial->config.bufsz;
+                }
+            }
+            /* force overwrite get index */
+            rx_fifo->get_index = rx_fifo->put_index + 1;
+        }
+    }
+}
+
 /*
  * Serial DMA routines
  */
 rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
 {
     rt_base_t level;
-    int result = RT_EOK;
-    struct rt_serial_rx_dma *rx_dma;
 
     RT_ASSERT((serial != RT_NULL) && (data != RT_NULL));
-    rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
-    RT_ASSERT(rx_dma != RT_NULL);
 
     level = rt_hw_interrupt_disable();
-    if (rx_dma->activated != RT_TRUE)
-    {
-        rx_dma->activated = RT_TRUE;
-        serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX);
-    }
-    else result = -RT_EBUSY;
-    rt_hw_interrupt_enable(level);
 
-    if (result == RT_EOK) return length;
+    if (serial->config.bufsz == 0) {
+        int result = RT_EOK;
+        struct rt_serial_rx_dma *rx_dma;
+
+        rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
+        RT_ASSERT(rx_dma != RT_NULL);
+
+        if (rx_dma->activated != RT_TRUE)
+        {
+            rx_dma->activated = RT_TRUE;
+            RT_ASSERT(serial->ops->dma_transmit != RT_NULL);
+            serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX);
+        }
+        else result = -RT_EBUSY;
+        rt_hw_interrupt_enable(level);
+
+        if (result == RT_EOK) return length;
+
+        rt_set_errno(result);
+        return 0;
+    } else {
+        struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
+        rt_size_t recv_len = 0, fifo_recved_len = rt_dma_calc_recved_len(serial);
+
+        RT_ASSERT(rx_fifo != RT_NULL);
 
-    rt_set_errno(result);
-    return 0;
+        if (length < fifo_recved_len) {
+            recv_len = length;
+        } else {
+            recv_len = fifo_recved_len;
+        }
+
+        if (rx_fifo->get_index + recv_len < serial->config.bufsz) {
+            rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, recv_len);
+        } else {
+            rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index,
+                    serial->config.bufsz - rx_fifo->get_index);
+            rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer,
+                    recv_len + rx_fifo->get_index - serial->config.bufsz);
+        }
+        rt_dma_recv_update_get_index(serial, recv_len);
+        rt_hw_interrupt_enable(level);
+        return recv_len;
+    }
 }
 
 rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
@@ -192,8 +297,8 @@ rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *
     struct rt_serial_tx_dma *tx_dma;
 
     tx_dma = (struct rt_serial_tx_dma*)(serial->serial_tx);
-    
-    result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER); 
+
+    result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER);
     if (result == RT_EOK)
     {
         level = rt_hw_interrupt_disable();
@@ -203,7 +308,7 @@ rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *
             rt_hw_interrupt_enable(level);
 
             /* make a DMA transfer */
-            serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_TX);
+            serial->ops->dma_transmit(serial, (rt_uint8_t *)data, length, RT_SERIAL_DMA_TX);
         }
         else
         {
@@ -250,7 +355,7 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
     serial = (struct rt_serial_device *)dev;
 
     /* check device flag with the open flag */
-    if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX)) 
+    if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
         return -RT_EIO;
     if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
         return -RT_EIO;
@@ -261,26 +366,41 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
 
     /* get open flags */
     dev->open_flag = oflag & 0xff;
-    
+
     /* initialize the Rx/Tx structure according to open flag */
     if (serial->serial_rx == RT_NULL)
     {
         if (oflag & RT_DEVICE_FLAG_DMA_RX)
         {
-            struct rt_serial_rx_dma* rx_dma;
-
-            rx_dma = (struct rt_serial_rx_dma*) rt_malloc (sizeof(struct rt_serial_rx_dma));
-            RT_ASSERT(rx_dma != RT_NULL);
-            rx_dma->activated = RT_FALSE;
-
-            serial->serial_rx = rx_dma;
+            if (serial->config.bufsz == 0) {
+                struct rt_serial_rx_dma* rx_dma;
+
+                rx_dma = (struct rt_serial_rx_dma*) rt_malloc (sizeof(struct rt_serial_rx_dma));
+                RT_ASSERT(rx_dma != RT_NULL);
+                rx_dma->activated = RT_FALSE;
+
+                serial->serial_rx = rx_dma;
+            } else {
+                struct rt_serial_rx_fifo* rx_fifo;
+
+                rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
+                    serial->config.bufsz);
+                RT_ASSERT(rx_fifo != RT_NULL);
+                rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
+                rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
+                rx_fifo->put_index = 0;
+                rx_fifo->get_index = 0;
+                serial->serial_rx = rx_fifo;
+                /* configure fifo address and length to low level device */
+                serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *) RT_DEVICE_FLAG_DMA_RX);
+            }
             dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
         }
         else if (oflag & RT_DEVICE_FLAG_INT_RX)
         {
             struct rt_serial_rx_fifo* rx_fifo;
 
-            rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) + 
+            rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
                 serial->config.bufsz);
             RT_ASSERT(rx_fifo != RT_NULL);
             rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
@@ -308,7 +428,7 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
             tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma));
             RT_ASSERT(tx_dma != RT_NULL);
             tx_dma->activated = RT_FALSE;
-            
+
             rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL);
             serial->serial_tx = tx_dma;
 
@@ -346,7 +466,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
 
     /* this device has more reference count */
     if (dev->ref_count > 1) return RT_EOK;
-    
+
     if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
     {
         struct rt_serial_rx_fifo* rx_fifo;
@@ -362,12 +482,23 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
     }
     else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
     {
-        struct rt_serial_rx_dma* rx_dma;
+        if (serial->config.bufsz == 0) {
+            struct rt_serial_rx_dma* rx_dma;
 
-        rx_dma = (struct rt_serial_rx_dma*)serial->serial_tx;
-        RT_ASSERT(rx_dma != RT_NULL);
+            rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
+            RT_ASSERT(rx_dma != RT_NULL);
+
+            rt_free(rx_dma);
+        } else {
+            struct rt_serial_rx_fifo* rx_fifo;
 
-        rt_free(rx_dma);
+            rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
+            RT_ASSERT(rx_fifo != RT_NULL);
+
+            rt_free(rx_fifo);
+        }
+        /* configure low level device */
+        serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_RX);
         serial->serial_rx = RT_NULL;
         dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
     }
@@ -376,7 +507,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
     {
         struct rt_serial_tx_fifo* tx_fifo;
 
-        tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_rx;
+        tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
         RT_ASSERT(tx_fifo != RT_NULL);
 
         rt_free(tx_fifo);
@@ -534,30 +665,30 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
                 ch = serial->ops->getc(serial);
                 if (ch == -1) break;
 
-                
+
                 /* disable interrupt */
                 level = rt_hw_interrupt_disable();
-                
+
                 rx_fifo->buffer[rx_fifo->put_index] = ch;
                 rx_fifo->put_index += 1;
                 if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;
-                
+
                 /* if the next position is read index, discard this 'read char' */
                 if (rx_fifo->put_index == rx_fifo->get_index)
                 {
                     rx_fifo->get_index += 1;
                     if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
                 }
-                
+
                 /* enable interrupt */
                 rt_hw_interrupt_enable(level);
             }
-            
+
             /* invoke callback */
             if (serial->parent.rx_indicate != RT_NULL)
             {
                 rt_size_t rx_length;
-            
+
                 /* get rx length */
                 level = rt_hw_interrupt_disable();
                 rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):
@@ -584,19 +715,19 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
             struct rt_serial_tx_dma* tx_dma;
 
             tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx;
-            
+
             rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0);
             if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK)
             {
                 /* transmit next data node */
                 tx_dma->activated = RT_TRUE;
-                serial->ops->dma_transmit(serial, data_ptr, data_size, RT_SERIAL_DMA_TX);
+                serial->ops->dma_transmit(serial, (rt_uint8_t *)data_ptr, data_size, RT_SERIAL_DMA_TX);
             }
             else
             {
                 tx_dma->activated = RT_FALSE;
             }
-            
+
             /* invoke callback */
             if (serial->parent.tx_complete != RT_NULL)
             {
@@ -607,13 +738,27 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
         case RT_SERIAL_EVENT_RX_DMADONE:
         {
             int length;
-            struct rt_serial_rx_dma* rx_dma;
 
-            rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
             /* get DMA rx length */
             length = (event & (~0xff)) >> 8;
-            serial->parent.rx_indicate(&(serial->parent), length);
-            rx_dma->activated = RT_FALSE;
+
+            if (serial->config.bufsz == 0) {
+                struct rt_serial_rx_dma* rx_dma;
+
+                rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
+                RT_ASSERT(rx_dma != RT_NULL);
+
+                RT_ASSERT(serial->parent.rx_indicate != RT_NULL);
+                serial->parent.rx_indicate(&(serial->parent), length);
+                rx_dma->activated = RT_FALSE;
+            } else {
+                /* update fifo put index */
+                rt_dma_recv_update_put_index(serial, length);
+                /* invoke callback */
+                if (serial->parent.rx_indicate != RT_NULL) {
+                    serial->parent.rx_indicate(&(serial->parent), rt_dma_calc_recved_len(serial));
+                }
+            }
             break;
         }
     }

+ 3 - 0
components/drivers/spi/SConscript

@@ -21,6 +21,9 @@ if GetDepend('RT_USING_AT45DBXX'):
 if GetDepend('RT_USING_SST25VFXX'):
     src_device += ['spi_flash_sst25vfxx.c']
 
+if GetDepend('RT_USING_GD'):
+    src_device += ['spi_flash_gd.c']
+
 src += src_device
 
 group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SPI'], CPPPATH = CPPPATH)

+ 1 - 1
components/drivers/spi/enc28j60.c

@@ -675,7 +675,7 @@ static struct pbuf *enc28j60_rx(rt_device_t dev)
         else
         {
             /* allocation pbuf */
-            p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
+            p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL);
             if (p != RT_NULL)
             {
                 struct pbuf* q;

+ 36 - 0
components/drivers/spi/spi_flash.h

@@ -0,0 +1,36 @@
+/*
+ * File      : spi_flash.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2016/5/20      bernard      the first version
+ */
+
+#ifndef SPI_FLASH_H__
+#define SPI_FLASH_H__
+
+struct spi_flash_device
+{
+    struct rt_device                flash_device;
+    struct rt_device_blk_geometry   geometry;
+    struct rt_spi_device *          rt_spi_device;
+    struct rt_mutex                 lock;
+};
+
+#endif

+ 14 - 4
components/drivers/spi/spi_flash_at45dbxx.c

@@ -1,11 +1,21 @@
 /*
- * File      : rtdef.h
+ * File      : spi_flash_at45dbxx.c
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 24 - 0
components/drivers/spi/spi_flash_at45dbxx.h

@@ -1,3 +1,27 @@
+/*
+ * File      : spi_flash_at45dbxx.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-12-16     aozima       the first version
+ */
+
 #ifndef SPI_FLASH_AT45DBXX_H_INCLUDED
 #define SPI_FLASH_AT45DBXX_H_INCLUDED
 

+ 346 - 0
components/drivers/spi/spi_flash_gd.c

@@ -0,0 +1,346 @@
+/*
+ * File      : spi_flash_gd.c
+ * This file is part of RT-Thread RTOS
+ *  Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd. 
+ *  All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2015-10-11     fullhan      copy from winbond flash
+ */
+
+#include <stdint.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "spi_flash.h"
+#include "spi_flash_gd.h"
+
+#define FLASH_DEBUG
+
+#ifdef FLASH_DEBUG
+#define FLASH_TRACE         rt_kprintf
+#else
+#define FLASH_TRACE(...)
+#endif /* #ifdef FLASH_DEBUG */
+
+#define PAGE_SIZE           4096
+
+/* JEDEC Manufacturer's ID */
+#define MF_ID           (0xC8)
+/* JEDEC Device ID: Memory type and Capacity */
+#define MTC_GD25Q128                (0x4018)
+
+/* command list */
+#define CMD_WRSR                    (0x01)  /* Write Status Register */
+#define CMD_PP                      (0x02)  /* Page Program */
+#define CMD_READ                    (0x03)  /* Read Data */
+#define CMD_WRDI                    (0x04)  /* Write Disable */
+#define CMD_RDSR1                   (0x05)  /* Read Status Register-1 */
+#define CMD_WREN                    (0x06)  /* Write Enable */
+#define CMD_FAST_READ               (0x0B)  /* Fast Read */
+#define CMD_ERASE_4K                (0x20)  /* Sector Erase:4K */
+#define CMD_RDSR2                   (0x35)  /* Read Status Register-2 */
+#define CMD_ERASE_32K               (0x52)  /* 32KB Block Erase */
+#define CMD_JEDEC_ID                (0x9F)  /* Read JEDEC ID */
+#define CMD_ERASE_full              (0xC7)  /* Chip Erase */
+#define CMD_ERASE_64K               (0xD8)  /* 64KB Block Erase */
+
+#define DUMMY                       (0xFF)
+
+static struct spi_flash_device  spi_flash_device;
+
+static void flash_lock(struct spi_flash_device * flash_device)
+{
+    rt_mutex_take(&flash_device->lock, RT_WAITING_FOREVER);
+}
+
+static void flash_unlock(struct spi_flash_device * flash_device)
+{
+    rt_mutex_release(&flash_device->lock);
+}
+
+static uint8_t w25qxx_read_status(void)
+{
+    return rt_spi_sendrecv8(spi_flash_device.rt_spi_device, CMD_RDSR1);
+}
+
+static void w25qxx_wait_busy(void)
+{
+    while( w25qxx_read_status() & (0x01));
+}
+
+/** \brief read [size] byte from [offset] to [buffer]
+ *
+ * \param offset uint32_t unit : byte
+ * \param buffer uint8_t*
+ * \param size uint32_t   unit : byte
+ * \return uint32_t byte for read
+ *
+ */
+static uint32_t w25qxx_read(uint32_t offset, uint8_t * buffer, uint32_t size)
+{
+    uint8_t send_buffer[4];
+
+    send_buffer[0] = CMD_WRDI;
+    rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
+
+    send_buffer[0] = CMD_READ;
+    send_buffer[1] = (uint8_t)(offset>>16);
+    send_buffer[2] = (uint8_t)(offset>>8);
+    send_buffer[3] = (uint8_t)(offset);
+
+    rt_spi_send_then_recv(spi_flash_device.rt_spi_device,
+                          send_buffer, 4,
+                          buffer, size);
+
+    return size;
+}
+
+/** \brief write N page on [page]
+ *
+ * \param page_addr uint32_t unit : byte (4096 * N,1 page = 4096byte)
+ * \param buffer const uint8_t*
+ * \return uint32_t
+ *
+ */
+static uint32_t w25qxx_page_write(uint32_t page_addr, const uint8_t* buffer)
+{
+    uint32_t index;
+    uint8_t send_buffer[4];
+
+    RT_ASSERT((page_addr&0xFF) == 0); /* page addr must align to 256byte. */
+
+    send_buffer[0] = CMD_WREN;
+    rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
+
+    send_buffer[0] = CMD_ERASE_4K;
+    send_buffer[1] = (page_addr >> 16);
+    send_buffer[2] = (page_addr >> 8);
+    send_buffer[3] = (page_addr);
+    rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 4);
+
+    w25qxx_wait_busy(); // wait erase done.
+
+    for(index=0; index < (PAGE_SIZE / 256); index++)
+    {
+        send_buffer[0] = CMD_WREN;
+        rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
+
+        send_buffer[0] = CMD_PP;
+        send_buffer[1] = (uint8_t)(page_addr >> 16);
+        send_buffer[2] = (uint8_t)(page_addr >> 8);
+        send_buffer[3] = (uint8_t)(page_addr);
+
+        rt_spi_send_then_send(spi_flash_device.rt_spi_device,
+                              send_buffer,
+                              4,
+                              buffer,
+                              256);
+
+        buffer += 256;
+        page_addr += 256;
+        w25qxx_wait_busy();
+    }
+
+    send_buffer[0] = CMD_WRDI;
+    rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
+
+    return PAGE_SIZE;
+}
+
+/* RT-Thread device interface */
+static rt_err_t w25qxx_flash_init(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t w25qxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    uint8_t send_buffer[3];
+
+    flash_lock((struct spi_flash_device *)dev);
+
+    send_buffer[0] = CMD_WREN;
+    rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
+
+    send_buffer[0] = CMD_WRSR;
+    send_buffer[1] = 0;
+    send_buffer[2] = 0;
+    rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 3);
+
+    w25qxx_wait_busy();
+
+    flash_unlock((struct spi_flash_device *)dev);
+
+    return RT_EOK;
+}
+
+static rt_err_t w25qxx_flash_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t w25qxx_flash_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+    RT_ASSERT(dev != RT_NULL);
+
+    if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
+    {
+        struct rt_device_blk_geometry *geometry;
+
+        geometry = (struct rt_device_blk_geometry *)args;
+        if (geometry == RT_NULL) return -RT_ERROR;
+
+        geometry->bytes_per_sector = spi_flash_device.geometry.bytes_per_sector;
+        geometry->sector_count = spi_flash_device.geometry.sector_count;
+        geometry->block_size = spi_flash_device.geometry.block_size;
+    }
+
+    return RT_EOK;
+}
+
+static rt_size_t w25qxx_flash_read(rt_device_t dev,
+                                   rt_off_t pos,
+                                   void* buffer,
+                                   rt_size_t size)
+{
+    flash_lock((struct spi_flash_device *)dev);
+
+    w25qxx_read(pos*spi_flash_device.geometry.bytes_per_sector,
+                buffer,
+                size*spi_flash_device.geometry.bytes_per_sector);
+
+    flash_unlock((struct spi_flash_device *)dev);
+
+    return size;
+}
+
+static rt_size_t w25qxx_flash_write(rt_device_t dev,
+                                    rt_off_t pos,
+                                    const void* buffer,
+                                    rt_size_t size)
+{
+    rt_size_t i = 0;
+    rt_size_t block = size;
+    const uint8_t * ptr = buffer;
+
+    flash_lock((struct spi_flash_device *)dev);
+
+    while(block--)
+    {
+        w25qxx_page_write((pos + i)*spi_flash_device.geometry.bytes_per_sector,
+                          ptr);
+        ptr += PAGE_SIZE;
+        i++;
+    }
+
+    flash_unlock((struct spi_flash_device *)dev);
+
+    return size;
+}
+
+rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name)
+{
+    struct rt_spi_device * rt_spi_device;
+
+    /* initialize mutex */
+    if (rt_mutex_init(&spi_flash_device.lock, spi_device_name, RT_IPC_FLAG_FIFO) != RT_EOK)
+    {
+        rt_kprintf("init sd lock mutex failed\n");
+        return -RT_ENOSYS;
+    }
+
+    rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
+    if(rt_spi_device == RT_NULL)
+    {
+        FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
+        return -RT_ENOSYS;
+    }
+    spi_flash_device.rt_spi_device = rt_spi_device;
+
+    /* config spi */
+    {
+        struct rt_spi_configuration cfg;
+        cfg.data_width = 8;
+        cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
+        cfg.max_hz = 50 * 1000 * 1000; /* 50M */
+        rt_spi_configure(spi_flash_device.rt_spi_device, &cfg);
+    }
+
+    /* init flash */
+    {
+        rt_uint8_t cmd;
+        rt_uint8_t id_recv[3];
+        uint16_t memory_type_capacity;
+
+        flash_lock(&spi_flash_device);
+
+        cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
+        rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
+
+        cmd = CMD_WRDI;
+        rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
+
+        /* read flash id */
+        cmd = CMD_JEDEC_ID;
+        rt_spi_send_then_recv(spi_flash_device.rt_spi_device, &cmd, 1, id_recv, 3);
+
+        flash_unlock(&spi_flash_device);
+
+        if(id_recv[0] != MF_ID)
+        {
+            FLASH_TRACE("Manufacturers ID error!\r\n");
+            FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
+            return -RT_ENOSYS;
+        }
+
+        spi_flash_device.geometry.bytes_per_sector = 4096;
+        spi_flash_device.geometry.block_size = 4096; /* block erase: 4k */
+
+        /* get memory type and capacity */
+        memory_type_capacity = id_recv[1];
+        memory_type_capacity = (memory_type_capacity << 8) | id_recv[2];
+
+        if(memory_type_capacity == MTC_GD25Q128)
+        {
+            FLASH_TRACE("GD128 detection\r\n");
+            spi_flash_device.geometry.sector_count = 4096;
+        }
+        else
+        {
+            FLASH_TRACE("Memory Capacity error!\r\n");
+            return -RT_ENOSYS;
+        }
+    }
+
+    /* register device */
+    spi_flash_device.flash_device.type    = RT_Device_Class_Block;
+    spi_flash_device.flash_device.init    = w25qxx_flash_init;
+    spi_flash_device.flash_device.open    = w25qxx_flash_open;
+    spi_flash_device.flash_device.close   = w25qxx_flash_close;
+    spi_flash_device.flash_device.read    = w25qxx_flash_read;
+    spi_flash_device.flash_device.write   = w25qxx_flash_write;
+    spi_flash_device.flash_device.control = w25qxx_flash_control;
+    /* no private */
+    spi_flash_device.flash_device.user_data = RT_NULL;
+
+    rt_device_register(&spi_flash_device.flash_device, flash_device_name,
+                       RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
+
+    return RT_EOK;
+}

+ 32 - 0
components/drivers/spi/spi_flash_gd.h

@@ -0,0 +1,32 @@
+/*
+ * File      : spi_flash_gd.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2015-10-11     fullhan      copy from winbond flash
+ */
+
+#ifndef SPI_FLASH_GD_H_
+#define SPI_FLASH_GD_H_
+
+#include <rtthread.h>
+
+extern rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name);
+
+#endif /* SPI_FLASH_GD_H_ */

+ 14 - 4
components/drivers/spi/spi_flash_sst25vfxx.c

@@ -1,11 +1,21 @@
 /*
- * File      : rtdef.h
+ * File      : spi_flash_sst25vfxx.c
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 14 - 4
components/drivers/spi/spi_flash_sst25vfxx.h

@@ -1,11 +1,21 @@
 /*
- * File      : rtdef.h
+ * File      : spi_flash_sst25vxx.h
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 17 - 6
components/drivers/spi/spi_flash_w25qxx.c

@@ -3,9 +3,19 @@
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -13,10 +23,12 @@
  * 2012-05-06     aozima       can page write.
  * 2012-08-23     aozima       add flash lock.
  * 2012-08-24     aozima       fixed write status register BUG.
- * 2015-05-13     bernard      add GD25Q flash ID.
  */
 
 #include <stdint.h>
+#include <rtdevice.h>
+
+#include "spi_flash.h"
 #include "spi_flash_w25qxx.h"
 
 #define FLASH_DEBUG
@@ -31,7 +43,6 @@
 
 /* JEDEC Manufacturer��s ID */
 #define MF_ID           (0xEF)
-#define GD_ID           (0xC8)
 
 /* JEDEC Device ID: Memory type and Capacity */
 #define MTC_W25Q80_BV         (0x4014) /* W25Q80BV */
@@ -301,7 +312,7 @@ rt_err_t w25qxx_init(const char * flash_device_name, const char * spi_device_nam
 
         flash_unlock(&spi_flash_device);
 
-        if(id_recv[0] != MF_ID && id_recv[0] != GD_ID)
+        if(id_recv[0] != MF_ID)
         {
             FLASH_TRACE("Manufacturers ID error!\r\n");
             FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);

+ 13 - 13
components/drivers/spi/spi_flash_w25qxx.h

@@ -3,9 +3,19 @@
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -17,18 +27,8 @@
 #define SPI_FLASH_W25QXX_H_INCLUDED
 
 #include <rtthread.h>
-#include <drivers/spi.h>
-
-struct spi_flash_device
-{
-    struct rt_device                flash_device;
-    struct rt_device_blk_geometry   geometry;
-    struct rt_spi_device *          rt_spi_device;
-    struct rt_mutex                 lock;
-};
 
 extern rt_err_t w25qxx_init(const char * flash_device_name,
                             const char * spi_device_name);
 
-
 #endif // SPI_FLASH_W25QXX_H_INCLUDED

+ 2 - 4
components/external/cairo/SConscript

@@ -1,11 +1,9 @@
-Import('RTT_ROOT')
-Import('rtconfig')
-
 from building import *
 import os
 
 CAIRO_VERSION = '1.10.2'
 CAIRO_PATH = 'cairo-' + CAIRO_VERSION
+cwd = GetCurrentDir()
 
 if GetDepend('RT_USING_CAIRO') and not os.path.exists(CAIRO_PATH):
     print '================ERROR============================'
@@ -99,7 +97,7 @@ cairo.c
 for item in range(len(src)):
     src[item] = CAIRO_PATH + '/src/' + src[item]
 
-CPPPATH = [RTT_ROOT + '/components/external/cairo/' + CAIRO_PATH + '/src', RTT_ROOT + '/components/external/cairo/']
+CPPPATH = [cwd + '/' + CAIRO_PATH + '/src', cwd]
 group = DefineGroup('cairo', src, depend = ['RT_USING_CAIRO', 'RT_USING_NEWLIB', 'RTGUI_IMAGE_PNG', 'RT_USING_PTHREADS'], CPPPATH = CPPPATH)
 
 Return('group')

+ 2 - 3
components/external/lzo/SConscript

@@ -1,12 +1,11 @@
-Import('RTT_ROOT')
-Import('rtconfig')
 from building import *
 
+cwd = GetCurrentDir()
 src	= Split('''
 minilzo.c
 lzo.c
 ''')
-CPPPATH = [RTT_ROOT + '/components/external/lzo']
+CPPPATH = [cwd]
 
 group = DefineGroup('lzo', src, depend = ['RT_USING_LZO'], CPPPATH = CPPPATH)
 

+ 2 - 3
components/external/nanopb/SConscript

@@ -1,13 +1,12 @@
-Import('RTT_ROOT')
-Import('rtconfig')
 from building import *
 
+cwd = GetCurrentDir()
 src	= Split('''
 pb_common.c
 pb_decode.c
 pb_encode.c
 ''')
-CPPPATH = [RTT_ROOT + '/components/external/nanopb']
+CPPPATH = [cwd]
 
 group = DefineGroup('Nanopb', src, depend = ['RT_USING_NANOPB'], CPPPATH = CPPPATH)
 

+ 3 - 0
components/libc/SConscript

@@ -17,4 +17,7 @@ else:
     if rtconfig.PLATFORM == 'gcc' and rtconfig.ARCH != 'sim':
         objs = objs + SConscript('minilibc/SConscript')
 
+objs = objs + SConscript('pthreads/SConscript')
+objs = objs + SConscript('libdl/SConscript')
+
 Return('objs')

+ 3 - 3
components/libdl/SConscript → components/libc/libdl/SConscript

@@ -1,9 +1,9 @@
-Import('RTT_ROOT')
-Import('rtconfig')
 from building import *
 
 src	= Glob('*.c')
-CPPPATH = [RTT_ROOT + '/components/libdl']
+cwd = GetCurrentDir()
+CPPPATH = [cwd]
+
 group = DefineGroup('libdl', src, depend = ['RT_USING_MODULE', 'RT_USING_LIBDL'], CPPPATH = CPPPATH)
 
 Return('group')

+ 0 - 0
components/libdl/dlclose.c → components/libc/libdl/dlclose.c


+ 0 - 0
components/libdl/dlerror.c → components/libc/libdl/dlerror.c


+ 0 - 0
components/libdl/dlfcn.h → components/libc/libdl/dlfcn.h


+ 0 - 0
components/libdl/dlopen.c → components/libc/libdl/dlopen.c


+ 0 - 0
components/libdl/dlsym.c → components/libc/libdl/dlsym.c


+ 15 - 0
components/libc/newlib/syscalls.c

@@ -447,3 +447,18 @@ void __libc_init_array(void)
 {
 	/* we not use __libc init_aray to initialize C++ objects */
 }
+
+void abort(void)
+{
+    if (rt_thread_self())
+    {
+        rt_thread_t self = rt_thread_self();
+
+        rt_kprintf("thread:%-8.*s abort!\n", RT_NAME_MAX, self->name);
+        rt_thread_suspend(self);
+
+        rt_schedule();
+    }
+
+	while (1);
+}

+ 3 - 2
components/pthreads/SConscript → components/libc/pthreads/SConscript

@@ -1,8 +1,9 @@
-Import('RTT_ROOT')
 from building import *
 
+cwd = GetCurrentDir()
 src	= Glob('*.c')
-CPPPATH = [RTT_ROOT + '/components/pthreads']
+CPPPATH = [cwd]
+
 group = DefineGroup('pthreads', src, depend = ['RT_USING_PTHREADS', 'RT_USING_LIBC'], CPPPATH = CPPPATH)
 
 Return('group')

+ 0 - 0
components/pthreads/clock_time.c → components/libc/pthreads/clock_time.c


+ 0 - 0
components/pthreads/mqueue.c → components/libc/pthreads/mqueue.c


+ 0 - 0
components/pthreads/mqueue.h → components/libc/pthreads/mqueue.h


+ 0 - 0
components/pthreads/posix_types.h → components/libc/pthreads/posix_types.h


+ 0 - 0
components/pthreads/pthread.c → components/libc/pthreads/pthread.c


+ 14 - 0
components/pthreads/pthread.h → components/libc/pthreads/pthread.h

@@ -142,6 +142,20 @@ typedef struct pthread_barrier pthread_barrier_t;
 /* pthread thread interface */
 int pthread_attr_destroy(pthread_attr_t *attr);
 int pthread_attr_init(pthread_attr_t *attr);
+int pthread_attr_setdetachstate(pthread_attr_t *attr, int state);
+int pthread_attr_getdetachstate(pthread_attr_t const *attr, int *state);
+int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
+int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy);
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size);
+int pthread_attr_getstacksize(pthread_attr_t const *attr, size_t *stack_size);
+int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack_addr);
+int pthread_attr_getstackaddr(pthread_attr_t const *attr, void **stack_addr);
+int pthread_attr_setstack(pthread_attr_t *attr,
+                          void           *stack_base,
+                          size_t          stack_size);
+int pthread_attr_getstack(pthread_attr_t const *attr,
+                          void                **stack_base,
+                          size_t               *stack_size);
 
 int pthread_system_init(void);
 int pthread_create (pthread_t *tid, const pthread_attr_t *attr, 

+ 0 - 0
components/pthreads/pthread_attr.c → components/libc/pthreads/pthread_attr.c


+ 0 - 0
components/pthreads/pthread_barrier.c → components/libc/pthreads/pthread_barrier.c


+ 0 - 0
components/pthreads/pthread_cond.c → components/libc/pthreads/pthread_cond.c


+ 0 - 0
components/pthreads/pthread_internal.h → components/libc/pthreads/pthread_internal.h


+ 0 - 0
components/pthreads/pthread_mutex.c → components/libc/pthreads/pthread_mutex.c


+ 0 - 0
components/pthreads/pthread_rwlock.c → components/libc/pthreads/pthread_rwlock.c


+ 0 - 0
components/pthreads/pthread_spin.c → components/libc/pthreads/pthread_spin.c


+ 0 - 0
components/pthreads/pthread_tls.c → components/libc/pthreads/pthread_tls.c


+ 0 - 0
components/pthreads/sched.c → components/libc/pthreads/sched.c


+ 0 - 0
components/pthreads/sched.h → components/libc/pthreads/sched.h


+ 0 - 0
components/pthreads/semaphore.c → components/libc/pthreads/semaphore.c


+ 0 - 0
components/pthreads/semaphore.h → components/libc/pthreads/semaphore.h


+ 3 - 2
components/net/SConscript

@@ -4,14 +4,15 @@ Import('RTT_ROOT')
 from building import *
 
 objs = []
-list = os.listdir(os.path.join(RTT_ROOT, 'components', 'net'))
+cwd = GetCurrentDir()
+list = os.listdir(cwd)
 
 # the default version of LWIP is 1.4.1
 if not GetDepend('RT_USING_LWIP132') and not GetDepend('RT_USING_LWIP140') and not GetDepend('RT_USING_LWIP_HEAD'):
     AddDepend('RT_USING_LWIP141')
 
 for d in list:
-    path = os.path.join(RTT_ROOT, 'components', 'net', d)
+    path = os.path.join(cwd, d)
     if os.path.isfile(os.path.join(path, 'SConscript')):
         objs = objs + SConscript(os.path.join(d, 'SConscript'))
 

+ 1 - 1
components/net/lwip-1.4.1/src/arch/include/arch/cc.h

@@ -76,7 +76,7 @@ typedef rt_uint32_t	mem_ptr_t;
 #define LWIP_TIMEVAL_PRIVATE	   1
 #endif
 
-#if defined(RT_USING_DFS_LWIP)
+#if defined(RT_USING_DFS_NET)
 #define LWIP_COMPAT_SOCKETS        0
 #endif
 

+ 6 - 0
components/net/lwip-1.4.1/src/core/tcp_out.c

@@ -1248,6 +1248,12 @@ tcp_rexmit_rto(struct tcp_pcb *pcb)
   for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
   /* concatenate unsent queue after unacked queue */
   seg->next = pcb->unsent;
+  #if TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK
+  /* if last unsent changed, we need to update unsent_oversize */
+  if (pcb->unsent == NULL) {
+	pcb->unsent_oversize = seg->oversize_left;
+  }
+  #endif /* TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK*/
   /* unsent queue is the concatenated queue (of unacked, unsent) */
   pcb->unsent = pcb->unacked;
   /* unacked queue is now empty */

+ 1 - 0
components/net/lwip-1.4.1/src/include/netif/etharp.h

@@ -139,6 +139,7 @@ PACK_STRUCT_END
 #define ETHTYPE_VLAN      0x8100U
 #define ETHTYPE_PPPOEDISC 0x8863U  /* PPP Over Ethernet Discovery Stage */
 #define ETHTYPE_PPPOE     0x8864U  /* PPP Over Ethernet Session Stage */
+#define ETHTYPE_EAPOL     0x888eU  /* EAPOL */
 
 /** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables
  * or known to be 32-bit aligned within the protocol header. */

+ 57 - 4
components/net/lwip-1.4.1/src/lwipopts.h

@@ -38,10 +38,6 @@
 #define LWIP_PLATFORM_BYTESWAP      0
 #define BYTE_ORDER                  LITTLE_ENDIAN
 
-/* Enable SO_RCVTIMEO/LWIP_SO_SNDTIMEO processing.   */
-#define LWIP_SO_RCVTIMEO            1
-#define LWIP_SO_SNDTIMEO            1
-
 /* #define RT_LWIP_DEBUG */
 
 #ifdef RT_LWIP_DEBUG
@@ -355,5 +351,62 @@
 #include <stdlib.h>
 #define LWIP_RAND                  rand
 #endif
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/*
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#ifndef LWIP_SOCKET
+#define LWIP_SOCKET                     1
+#endif
+
+/*
+ * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names.
+ * (only used if you use sockets.c)
+ */
+#ifndef LWIP_COMPAT_SOCKETS
+#define LWIP_COMPAT_SOCKETS             1
+#endif
+
+
+/**
+ * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
+ * SO_SNDTIMEO processing.
+ */
+#ifndef LWIP_SO_SNDTIMEO
+#define LWIP_SO_SNDTIMEO                1
+#endif
+
+/**
+ * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
+ * SO_RCVTIMEO processing.
+ */
+#ifndef LWIP_SO_RCVTIMEO
+#define LWIP_SO_RCVTIMEO                1
+#endif
+
+/**
+ * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
+ */
+#ifndef LWIP_SO_RCVBUF
+#define LWIP_SO_RCVBUF                  1
+#endif
+
+/**
+ * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize.
+ */
+#ifndef RECV_BUFSIZE_DEFAULT
+#define RECV_BUFSIZE_DEFAULT            8192
+#endif
+
+/**
+ * SO_REUSE==1: Enable SO_REUSEADDR option.
+ */
+#ifndef SO_REUSE
+#define SO_REUSE                        0
+#endif
 
 #endif /* __LWIPOPTS_H__ */

+ 0 - 3050
components/net/lwip/CHANGELOG

@@ -1,3050 +0,0 @@
-HISTORY
-
-(CVS HEAD)
-
-  * [Enter new changes just after this line - do not remove this line]
-
- ++ New features:
-
-
- ++ Bugfixes:
-
-
-
-
-(STABLE-1.4.0)
-
-  ++ New features:
-
-  2011-03-27: Simon Goldschmidt
-  * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and
-    calculate it in tcp_zero_window_probe (the only place where it was used).
-
-  2010-11-21: Simon Goldschmidt
-  * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif
-    (fixes bug #31525).
-
-  2010-07-12: Simon Goldschmidt (patch by Stephane Lesage)
-  * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
-    IP_MULTICAST_LOOP at socket- and raw-API level.
-
-  2010-06-16: Simon Goldschmidt
-  * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow
-    link-layer-addressed UDP traffic to be received while a netif is down (just
-    like DHCP during configuration)
-
-  2010-05-22: Simon Goldschmidt
-  * many many files: bug #27352: removed packing from ip_addr_t, the packed
-    version is now only used in protocol headers. Added global storage for
-    current src/dest IP address while in input functions.
-
-  2010-05-16: Simon Goldschmidt
-  * def.h: task #10391: Add preprocessor-macros for compile-time htonl
-    calculation (and use them throughout the stack where applicable)
-
-  2010-05-16: Simon Goldschmidt
-  * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool
-    instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h)
-
-  2010-05-16: Simon Goldschmidt
-  * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own
-    MEMP pool instead of the heap
-
-  2010-05-13: Simon Goldschmidt
-  * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added
-    new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast
-    packets to more than one pcb.
-
-  2010-05-02: Simon Goldschmidt
-  * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending
-    UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1
-
-  2010-04-30: Simon Goldschmidt
-  * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that
-    take a precalculated checksum, added pbuf_fill_chksum() to copy data
-    into a pbuf and at the same time calculating the checksum for that data
-
-  2010-04-29: Simon Goldschmidt
-  * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying
-    2-byte-aligned IP addresses and MAC addresses
-
-  2010-04-28: Patch by Bill Auerbach
-  * ip.c: Inline generating IP checksum to save a function call
-
-  2010-04-14: Simon Goldschmidt
-  * tcpip.h/.c, timers.c: Added an overridable define to get informed when the
-    tcpip_thread processes messages or timeouts to implement a watchdog.
-
-  2010-03-28: Simon Goldschmidt
-  * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing
-    fragment if LWIP_NETIF_TX_SINGLE_PBUF==1
-
-  2010-03-27: Simon Goldschmidt
-  * etharp.c: Speedup TX by moving code from find_entry to etharp_output/
-    etharp_query to prevent unnecessary function calls (inspired by
-    patch #7135).
-
-  2010-03-20: Simon Goldschmidt
-  * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code
-    since the linker cannot do this automatically to save space.
-
-  2010-03-20: Simon Goldschmidt
-  * opt.h, etharp.c/.h: Added support for static ARP table entries
-
-  2010-03-14: Simon Goldschmidt
-  * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum
-    when creating TCP segments, not when (re-)transmitting them.
-
-  2010-03-07: Simon Goldschmidt
-  * sockets.c: bug #28775 (select/event_callback: only check select_cb_list
-    on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code.
-    This should speed up receiving data on sockets as the select code in
-    event_callback is only executed when select is waiting.
-
-  2010-03-06: Simon Goldschmidt
-  * tcp_out.c: task #7013 (Create option to have all packets delivered to
-    netif->output in one piece): Always copy to try to create single pbufs
-    in tcp_write.
-
-  2010-03-06: Simon Goldschmidt
-  * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv
-    by not allocating a netbuf): added function netconn_recv_tcp_pbuf()
-    for tcp netconns to receive pbufs, not netbufs; use that function
-    for tcp sockets.
-
-  2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt
-  * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040:
-    Work on tcp_enqueue: Don't waste memory when chaining segments,
-    added option TCP_OVERSIZE to prevent creating many small pbufs when
-    calling tcp_write with many small blocks of data. Instead, pbufs are
-    allocated larger than needed and the space is used for later calls to
-    tcp_write.
-
-  2010-02-21: Simon Goldschmidt
-  * stats.c/.h: Added const char* name to mem- and memp-stats for easier
-    debugging.
-
-  2010-02-21: Simon Goldschmidt
-  * tcp.h (and usages), added tcp_impl.h: Splitted API and internal
-    implementation of tcp to make API usage cleare to application programmers
-
-  2010-02-14: Simon Goldschmidt/Stephane Lesage
-  * ip_addr.h: Improved some defines working on ip addresses, added faster
-    macro to copy addresses that cannot be NULL
-
-  2010-02-13: Simon Goldschmidt
-  * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non-
-    blocking send operation)
-
-  2010-02-12: Simon Goldschmidt
-  * sockets.c/.h: Added a minimal version of posix fctl() to have a
-    standardised way to set O_NONBLOCK for nonblocking sockets.
-
-  2010-02-12: Simon Goldschmidt
-  * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated
-    memory): added autoip_set_struct() and dhcp_set_struct() to let autoip
-    and dhcp work with user-allocated structs instead of callin mem_malloc
-
-  2010-02-12: Simon Goldschmidt/Jeff Barber
-  * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has
-    SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT
-
-  2010-02-12: Simon Goldschmidt
-  * sys layer: task #10139 (Prefer statically allocated memory): converted
-    mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t;
-    converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
-    task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX
-    to let sys.h use binary semaphores instead of mutexes - as before)
-
-  2010-02-09: Simon Goldschmidt (Simon Kallweit)
-  * timers.c/.h: Added function sys_restart_timeouts() from patch #7085
-    (Restart system timeout handling)
-
-  2010-02-09: Simon Goldschmidt
-  * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into
-    netif.c) - loopif does not have to be created by the port any more,
-    just define LWIP_HAVE_LOOPIF to 1.
-
-  2010-02-08: Simon Goldschmidt
-  * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa
-    inet_ntoa_r/ipaddr_ntoa_r
-
-  2010-02-08: Simon Goldschmidt
-  * netif.h: Added netif_s/get_igmp_mac_filter() macros
-
-  2010-02-05: Simon Goldschmidt
-  * netif.h: Added function-like macros to get/set the hostname on a netif
-
-  2010-02-04: Simon Goldschmidt
-  * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to
-    make changing the actual implementation behind the typedef easier.
-
-  2010-02-01: Simon Goldschmidt
-  * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool
-    for allocating memory when getaddrinfo() is called.
-
-  2010-01-31: Simon Goldschmidt
-  * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse
-    them once instead of parsing for every option. This also removes
-    the need for mem_malloc from dhcp_recv and makes it possible to
-    correctly retrieve the BOOTP file.
-
-  2010-01-30: simon Goldschmidt
-  * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect
-    the sockets array.
-
-  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
-  * api.h, api_msg.c, sockets.c: Added except set support in select
-    (patch #6860)
-
-  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
-  * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c:
-    Add non-blocking support for connect (partly from patch #6860),
-    plus many cleanups in socket & netconn API.
-
-  2010-01-27: Simon Goldschmidt
-  * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding
-    to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605
-
-  2010-01-26: Simon Goldschmidt
-  * snmp: Use memp pools for snmp instead of the heap; added 4 new pools.
-
-  2010-01-14: Simon Goldschmidt
-  * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback
-    by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback()
-
-  2010-01-13: Simon Goldschmidt
-  * mem.c: The heap now may be moved to user-defined memory by defining
-    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
-    (patch #6966 and bug #26133)
-
-  2010-01-10: Simon Goldschmidt (Bill Auerbach)
-  * opt.h, memp.c: patch #6822 (Add option to place memory pools in
-    separate arrays)
-
-  2010-01-10: Simon Goldschmidt
-  * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define
-    LWIP_RAND() for lwip-wide randomization (to be defined in cc.h)
-
-  2009-12-31: Simon Goldschmidt
-  * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h
-    added timers.c/.h: Separated timer implementation from semaphore/mbox
-    implementation, moved timer implementation to timers.c/.h, timers are
-    now only called from tcpip_thread or by explicitly checking them.
-    (TASK#7235)
-
-  2009-12-27: Simon Goldschmidt
-  * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option
-    LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE)
-
-
-  ++ Bugfixes:
-
-  2011-04-20: Simon Goldschmidt
-  * sys_arch.txt: sys_arch_timeouts() is not needed any more.
-
-  2011-04-13: Simon Goldschmidt
-  * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by
-    using ports in the IANA private/dynamic range (49152 through 65535).
-
-  2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl:
-  * etharp.h/.c: Fixed broken VLAN support.
-
-  2011-03-27: Simon Goldschmidt
-  * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp
-    pcbs) by checking if the pcb was bound (local_port != 0).
-
-  2011-03-27: Simon Goldschmidt
-  * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice)
-
-  2011-03-27: Simon Goldschmidt
-  * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and
-    raw pcbs with LWIP_TCPIP_CORE_LOCKING==1.
-  
-  2011-03-27: Simon Goldschmidt
-  * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route
-    is present never times out) by starting retransmission timer before checking
-    route.
-
-  2011-03-22: Simon Goldschmidt
-  * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only
-    calling sio_read_abort() if the file descriptor is valid.
-
-  2011-03-14: Simon Goldschmidt
-  * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect
-    more than once can render a socket useless) since it mainly involves changing
-    "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal.
-
-  2011-03-13: Simon Goldschmidt
-  * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing
-    err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN:
-    use EALRADY instead of -1
-
-  2011-03-13: Simon Goldschmidt
-  * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the
-    connection has been aborted by err_tcp (since this is not a normal closing
-    procedure).
-
-  2011-03-13: Simon Goldschmidt
-  * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind
-    with pcb->state != CLOSED
-
-  2011-02-17: Simon Goldschmidt
-  * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in
-    documentation
-
-  2011-02-17: Simon Goldschmidt
-  * many files: Added missing U/UL modifiers to fix 16-bit-arch portability.
-
-  2011-01-24: Simon Goldschmidt
-  * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems
-
-  2010-12-02: Simon Goldschmidt
-  * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal.
-
-  2010-11-23: Simon Goldschmidt
-  * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for
-    LWIP_SO_RCVBUF and ioctl/FIONREAD.
-
-  2010-11-23: Simon Goldschmidt
-  * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at
-    least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet.
-
-  2010-11-23: Simon Goldschmidt
-  * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after
-    refusing 'refused_data' again.
-  
-  2010-11-22: Simon Goldschmidt
-  * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS
-    after a successful nonblocking connection.
-
-  2010-11-22: Simon Goldschmidt
-  * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr
-    must be sent link-local
-
-  2010-11-22: Simon Goldschmidt
-  * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for
-    LWIP_TIMERS==0
-
-  2010-11-20: Simon Goldschmidt
-  * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number
-
-  2010-11-20: Simon Goldschmidt
-  * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to
-    resemble other stacks.
-
-  2010-11-20: Simon Goldschmidt
-  * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else
-    no-copy TCP writes will never succeed.
-
-  2010-11-20: Simon Goldschmidt
-  * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does
-    not match documentation: return ERR_ARG instead of ERR_VAL if not
-    initialized or wrong argument.
-
-  2010-10-20: Simon Goldschmidt
-  * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16
-
-  2010-10-05: Simon Goldschmidt
-  * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when
-    replugging the network cable after an AutoIP address was assigned.
-
-  2010-08-10: Simon Goldschmidt
-  * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs
-
-  2010-08-03: Simon Goldschmidt
-  * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625)
-
-  2010-08-01: Simon Goldschmidt (patch by Greg Renda)
-  * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big
-    endian architectures)
-  
-  2010-07-28: Simon Goldschmidt
-  * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP
-    disabled.
-  
-  2010-07-27: Simon Goldschmidt
-  * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no
-    harm but never did anything
-  
-  2010-07-21: Simon Goldschmidt
-  * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not
-    add IP options)
-
-  2010-07-16: Kieran Mansley
-  * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator 
-
-  2010-07-10: Simon Goldschmidt
-  * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options
-
-  2010-06-30: Simon Goldschmidt
-  * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in
-    netconn_delete)
-
-  2010-06-28: Kieran Mansley
-  * timers.c remove unportable printing of C function pointers
-
-  2010-06-24: Simon Goldschmidt
-  * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag
-    NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading
-
-  2010-06-24: Simon Goldschmidt
-  * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly
-    implemented shutdown at socket level.
-
-  2010-06-21: Simon Goldschmidt
-  * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has
-    problems with zero-copy DMA MACs) by adding custom pbufs and implementing
-    custom pbufs that reference other (original) pbufs. Additionally set
-    IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side.
-
-  2010-06-15: Simon Goldschmidt
-  * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses
-
-  2010-06-14: Simon Goldschmidt
-  * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses
-
-  2010-06-12: Simon Goldschmidt
-  * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop
-    state
-
-  2010-05-17: Simon Goldschmidt
-  * netdb.c: Correctly NULL-terminate h_addr_list
-
-  2010-05-16: Simon Goldschmidt
-  * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent
-    "symbol already defined" i.e. when linking to winsock
-
-  2010-05-05: Simon Goldschmidt
-  * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may
-    overflow)
-
-  2010-04-21: Simon Goldschmidt
-  * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening
-    connection)
-
-  2010-03-28: Luca Ceresoli
-  * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers
-
-  2010-03-27: Luca Ceresoli
-  * mib2.c: patch #7130: remove meaningless const qualifiers
-
-  2010-03-26: Simon Goldschmidt
-  * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too
-
-  2010-03-26: Simon Goldschmidt
-  * various files: Fixed compiling with different options disabled (TCP/UDP),
-    triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled
-
-  2010-03-25: Simon Goldschmidt
-  * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly
-
-  2010-03-25: Simon Goldschmidt
-  * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side
-    overrunning our rcv_wnd in ooseq case.
-
-  2010-03-22: Simon Goldschmidt
-  * tcp.c: tcp_listen() did not copy the pcb's prio.
-
-  2010-03-19: Simon Goldschmidt
-  * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set
-
-  2010-03-14: Simon Goldschmidt
-  * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports
-    where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h
-    and basing PBUF_LINK_HLEN on it.
-
-  2010-03-08: Simon Goldschmidt
-  * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections
-    when assiging routable address): when checking incoming packets and
-    aborting existing connection on address change, filter out link-local
-    addresses.
-
-  2010-03-06: Simon Goldschmidt
-  * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING
-
-  2010-03-06: Simon Goldschmidt
-  * ipv4/ip.c: Don't try to forward link-local addresses
-
-  2010-03-06: Simon Goldschmidt
-  * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal-
-    addresses to gw
-
-  2010-03-05: Simon Goldschmidt
-  * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type
-    and state.
-
-  2010-03-05: Simon Goldschmidt
-  * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split
-    into multiple calls to tcp_write.    
-
-  2010-02-21: Simon Goldschmidt
-  * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep
-    the implementation of DNS_USES_STATIC_BUF==1)
-
-  2010-02-20: Simon Goldschmidt
-  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement
-    close() vs. shutdown(). Now the application does not get any more
-    recv callbacks after calling tcp_close(). Added tcp_shutdown().
-
-  2010-02-19: Simon Goldschmidt
-  * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent
-    confusion with realloc()
-
-  2010-02-15: Simon Goldschmidt/Stephane Lesage
-  * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK
-    (fixes bug #28899)
-
-  2010-02-14: Simon Goldschmidt
-  * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with
-    LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and
-    admin-status of a netif are up
-
-  2010-02-14: Simon Goldschmidt
-  * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet
-    reception and is not really necessary
-
-  2010-02-14: Simon Goldschmidt
-  * etharp.c/.h: Fixed ARP input processing: only add a new entry if a
-    request was directed as us (RFC 826, Packet Reception), otherwise
-    only update existing entries; internalized some functions
-
-  2010-02-14: Simon Goldschmidt
-  * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be
-    disabled on netif used for PPPoE) by adding a new netif flag
-    (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet
-    device but prevents usage of ARP (so that ethernet_input can be used
-    for PPPoE).
-
-  2010-02-12: Simon Goldschmidt
-  * netif.c: netif_set_link_up/down: only do something if the link state
-    actually changes
-
-  2010-02-12: Simon Goldschmidt/Stephane Lesage
-  * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking
-    connect)
-
-  2010-02-12: Simon Goldschmidt
-  * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h)
-
-  2010-02-09: Simon Goldschmidt
-  * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110
-   (recv() makes receive window update for data that wasn't received by
-    application)
-
-  2010-02-09: Simon Goldschmidt/Stephane Lesage
-  * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out
-    or any netconn_recv() error)
-
-  2010-02-09: Simon Goldschmidt
-  * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets)
-
-  2010-02-09: Simon Goldschmidt
-  * netif.c: For loopback packets, adjust the stats- and snmp-counters
-    for the loopback netif.
-
-  2010-02-08: Simon Goldschmidt
-  * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity
-    since they are not used anywhere else.
-
-  2010-02-08: Simon Goldschmidt (Stéphane Lesage)
-  * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats
-    (patch from bug #28798)
-
-  2010-02-08: Simon Goldschmidt (Stéphane Lesage)
-  * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and
-    another bug when LWIP_RAND() returns zero.
-
-  2010-02-04: Simon Goldschmidt
-  * nearly every file: Use macros defined in ip_addr.h (some of them new)
-    to work with IP addresses (preparation for bug #27352 - Change ip_addr
-    from struct to typedef (u32_t) - and better code).
-
-  2010-01-31: Simon Goldschmidt
-  * netif.c: Don't call the link-callback from netif_set_up/down() since
-    this invalidly retriggers DHCP.
-
-  2010-01-29: Simon Goldschmidt
-  * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the
-    portability file inet.h and its contents from the stack: moved htonX-
-    functions to def.h (and the new def.c - they are not ipv4 dependent),
-    let inet.h depend on ip_addr.h and not the other way round.
-    This fixes bug #28732.
-
-  2010-01-28: Kieran Mansley
-  * tcp.c: Ensure ssthresh >= 2*MSS
-
-  2010-01-27: Simon Goldschmidt
-  * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv
-    callback can lead to accessing unallocated memory. As a consequence,
-    ERR_ABRT means the application has called tcp_abort()!
-
-  2010-01-25: Simon Goldschmidt
-  * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY
-    not implemented in SNMP): write-only or not-accessible are still
-    returned by getnext (though not by get)
-
-  2010-01-24: Simon Goldschmidt
-  * snmp: Renamed the private mib node from 'private' to 'mib_private' to
-    not use reserved C/C++ keywords
-
-  2010-01-23: Simon Goldschmidt
-  * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less
-    than 1 ms
-
-  2010-01-21: Simon Goldschmidt
-  * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called
-    if tcp_enqueue fails) both in raw- and netconn-API
-
-  2010-01-19: Simon Goldschmidt
-  * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp
-
-  2010-01-18: Iordan Neshev/Simon Goldschmidt
-  * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some
-    bugfix backports from 2.4.x.
-
-  2010-01-18: Simon Goldschmidt
-  * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong
-
-  2010-01-17: Simon Goldschmidt
-  * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c):
-    task #10102: "netconn: clean up conn->err threading issues" by adding
-    error return value to struct api_msg_msg
-
-  2010-01-17: Simon Goldschmidt
-  * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept()
-    to return err_t (bugs #27709 and #28087)
-
-  2010-01-14: Simon Goldschmidt
-  * ...: Use typedef for function prototypes throughout the stack.
-
-  2010-01-13: Simon Goldschmidt
-  * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive
-    window = 0) by correctly draining recvmbox/acceptmbox
-
-  2010-01-11: Simon Goldschmidt
-  * pap.c: Fixed bug #13315 (PPP PAP authentication can result in
-    erroneous callbacks) by copying the code from recent pppd
-
-  2010-01-10: Simon Goldschmidt
-  * raw.c: Fixed bug #28506 (raw_bind should filter received packets)
-
-  2010-01-10: Simon Goldschmidt
-  * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)())
-
-  2010-01-08: Simon Goldschmidt
-  * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535)
-
-  2010-01-08: Simon Goldschmidt
-  * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string
-    passed to dns_local_addhost() might be volatile
-
-  2010-01-07: Simon Goldschmidt
-  * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too
-
-  2010-01-06: Simon Goldschmidt
-  * netdb.h: Fixed bug #28496: missing include guards in netdb.h
-
-  2009-12-31: Simon Goldschmidt
-  * many ppp files: Reorganised PPP source code from ucip structure to pppd
-    structure to easily compare our code against the pppd code (around v2.3.1)
-
-  2009-12-27: Simon Goldschmidt
-  * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted
-    unit test
-
-
-(STABLE-1.3.2)
-
-  ++ New features:
-
-  2009-10-27 Simon Goldschmidt/Stephan Lesage
-  * netifapi.c/.h: Added netifapi_netif_set_addr()
-
-  2009-10-07 Simon Goldschmidt/Fabian Koch
-  * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to
-    support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO)
-
-  2009-08-26 Simon Goldschmidt/Simon Kallweit
-  * slipif.c/.h: bug #26397: SLIP polling support
-
-  2009-08-25 Simon Goldschmidt
-  * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN),
-    New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK.
-
-  2009-08-25 Simon Goldschmidt
-  * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*)
-
-  2009-08-24 Jakob Stoklund Olesen
-  * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond
-    to netif_set_link_up().
-
-  2009-08-23 Simon Goldschmidt
-  * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state
-    to a human-readable string.
-
-  ++ Bugfixes:
-
-  2009-12-24: Kieran Mansley
-  * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing
-    (BUG#28241)
-
-  2009-12-06: Simon Goldschmidt
-  * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can
-    be statically allocated (like in ucip)
-
-  2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev)
-  * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT
-
-  2009-12-03: Simon Goldschmidt
-  * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit
-    could have non-zero length
-
-  2009-12-02: Simon Goldschmidt
-  * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting
-    tcp_input_pcb until after calling the pcb's callbacks
-
-  2009-11-29: Simon Goldschmidt
-  * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of-
-    sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code
-
-  2009-11-29: Simon Goldschmidt
-  * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by
-    queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty
-
-  2009-11-26: Simon Goldschmidt
-  * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending
-    segment
-
-  2009-11-26: Simon Goldschmidt
-  * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle
-    algorithm at PCB level
-
-  2009-11-22: Simon Goldschmidt
-  * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent
-
-  2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach)
-  * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when
-    reusing time-wait pcb
-
-  2009-11-20: Simon Goldschmidt (patch by Albert Bartel)
-  * sockets.c: Fixed bug #28062: Data received directly after accepting
-    does not wake up select
-
-  2009-11-11: Simon Goldschmidt
-  * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo)
-
-  2009-10-30: Simon Goldschmidt
-  * opt.h: Increased default value for TCP_MSS to 536, updated default
-    value for TCP_WND to 4*TCP_MSS to keep delayed ACK working.
-
-  2009-10-28: Kieran Mansley
-  * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code
-    to follow algorithm from TCP/IP Illustrated
-
-  2009-10-27: Kieran Mansley
-  * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK
-
-  2009-10-25: Simon Goldschmidt
-  * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if
-    pcb->recv is NULL to keep rcv_wnd correct)
-
-  2009-10-25: Simon Goldschmidt
-  * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state
-
-  2009-10-23: Simon Goldschmidt (David Empson)
-  * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes
-
-  2009-10-21: Simon Goldschmidt
-  * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and
-    trailing 1 byte len (SYN/FIN)
-
-  2009-10-21: Simon Goldschmidt
-  * tcp_out.c: Fixed bug #27315: zero window probe and FIN
-
-  2009-10-19: Simon Goldschmidt
-  * dhcp.c/.h: Minor code simplification (don't store received pbuf, change
-    conditional code to assert where applicable), check pbuf length before
-    testing for valid reply
-
-  2009-10-19: Simon Goldschmidt
-  * dhcp.c: Removed most calls to udp_connect since they aren't necessary
-    when using udp_sendto_if() - always stay connected to IP_ADDR_ANY.
-
-  2009-10-16: Simon Goldschmidt
-  * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop
-    valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is
-    enabled
-
-  2009-10-15: Simon Goldschmidt (Oleg Tyshev)
-  * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit
-
-  2009-10-15: Simon Goldschmidt
-  * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv()
-    timeout
-
-  2009-10-15: Simon Goldschmidt
-  * autoip.c: Fixed bug #27704: autoip starts with wrong address
-    LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead
-    of network byte order
-
-  2009-10-11 Simon Goldschmidt (Jörg Kesten)
-  * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments
-    which are not consecutive when retransmitting unacked segments
-
-  2009-10-09 Simon Goldschmidt
-  * opt.h: Fixed default values of some stats to only be enabled if used
-    Fixes bug #27338: sys_stats is defined when NO_SYS = 1
-
-  2009-08-30 Simon Goldschmidt
-  * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK
-    function" by checking for loopback before calling ip_frag
-
-  2009-08-25 Simon Goldschmidt
-  * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0
-
-  2009-08-23 Simon Goldschmidt
-  * ppp.c: bug #27078: Possible memory leak in pppInit()
-
-  2009-08-23 Simon Goldschmidt
-  * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result
-    is error.
-
-  2009-08-23 Simon Goldschmidt
-  * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF
-    Fixed wrong parenthesis, added check in init.c
-
-  2009-08-23 Simon Goldschmidt
-  * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms
-
-  2009-08-23 Simon Goldschmidt
-  * many ppp files: bug #27267: Added include to string.h where needed
-
-  2009-08-23 Simon Goldschmidt
-  * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian)
-
-
-(STABLE-1.3.1)
-
-  ++ New features:
-
-  2009-05-10 Simon Goldschmidt
-  * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option
-    LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only
-    one pbuf to help MACs that don't support scatter-gather DMA.
-
-  2009-05-09 Simon Goldschmidt
-  * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming
-    ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
-
-  2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen
-  * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive
-    extended info about the currently received packet.
-
-  2009-04-27 Simon Goldschmidt
-  * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1
-
-  2009-04-25 Simon Goldschmidt
-  * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next
-    bigger malloc pool if one is empty (only usable with MEM_USE_POOLS).
-
-  2009-04-21 Simon Goldschmidt
-  * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static
-    hosts table. New configuration options DNS_LOCAL_HOSTLIST and
-    DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined
-    as an external function for lookup.
-
-  2009-04-15 Simon Goldschmidt
-  * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique
-
-  2009-03-31 Kieran Mansley
-  * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for
-    TCP timestamp options, off by default.  Rework tcp_enqueue() to
-    take option flags rather than specified option data
-
-  2009-02-18 Simon Goldschmidt
-  * cc.h: Added printf formatter for size_t: SZT_F
-
-  2009-02-16 Simon Goldschmidt (patch by Rishi Khan)
-  * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast
-    pings
-
-  2009-02-12 Simon Goldschmidt
-  * init.h: Added LWIP_VERSION to get the current version of the stack
-
-  2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler)
-  * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead
-    of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc
-    is otherwise used)
-
-  2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach)
-  * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial()
-  is only used by UDPLITE at present, so conditionalise it.
-
-  2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli)
-  * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP
-    "seed" address. This should reduce AUTOIP conflicts if
-    LWIP_AUTOIP_CREATE_SEED_ADDR is overridden.
-
-  2008-10-02 Jonathan Larmour and Rishi Khan
-  * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking
-    socket.
-
-  2008-06-30 Simon Goldschmidt
-  * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from
-    interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows
-    mem_free to run between mem_malloc iterations. Added illegal counter for
-    mem stats.
-
-  2008-06-27 Simon Goldschmidt
-  * stats.h/.c, some other files: patch #6483: stats module improvement:
-    Added defines to display each module's statistic individually, added stats
-    defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter.
-
-  2008-06-17 Simon Goldschmidt
-  * err.h: patch #6459: Made err_t overridable to use a more efficient type
-    (define LWIP_ERR_T in cc.h)
-
-  2008-06-17 Simon Goldschmidt
-  * slipif.c: patch #6480: Added a configuration option for slipif for symmetry
-    to loopif
-
-  2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli)
-  * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly
-    modified version of patch # 6370: Moved loopif code to netif.c so that
-    loopback traffic is supported on all netifs (all local IPs).
-    Added option to limit loopback packets for each netifs.
-
-
-  ++ Bugfixes:
-  2009-08-12 Kieran Mansley
-  * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when
-    out of window or out of order properly
-
-  2009-08-12 Kieran Mansley
-  * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1
-
-  2009-07-28 Simon Goldschmidt
-  * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s
-
-  2009-07-27 Kieran Mansley
-  * api.h api_msg.h netdb.h sockets.h: add missing #include directives
-
-  2009-07-09 Kieran Mansley
-  * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for
-    recv_avail and don't increment counters until message successfully
-    sent to mbox
-
-  2009-06-25 Kieran Mansley
-  * api_msg.c api.h: BUG26722: initialise netconn write variables 
-    in netconn_alloc
-
-  2009-06-25 Kieran Mansley
-  * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set
-
-  2009-06-25 Kieran Mansley
-  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct
-    simultaneous close behaviour, and make snd_nxt have the same meaning 
-    as in the RFCs.
-
-  2009-05-12 Simon Goldschmidt
-  * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on
-    arp_table / uses etharp_query" by adding etharp_gratuitous()
-
-  2009-05-12 Simon Goldschmidt
-  * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options
-    to the IP header (used by igmp_ip_output_if)
-
-  2009-05-06 Simon Goldschmidt
-  * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if
-    defined) for SWAP_BYTES_IN_WORD to speed up checksumming.
-
-  2009-05-05 Simon Goldschmidt
-  * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select()
-    to crash
-
-  2009-05-04 Simon Goldschmidt
-  * init.c: snmp was not initialized in lwip_init()
-
-  2009-05-04 Frédéric Bernon
-  * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled.
-
-  2009-05-03 Simon Goldschmidt
-  * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full
-    (and unsent->next == NULL)
-
-  2009-05-02 Simon Goldschmidt
-  * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after
-    1.3.0 in CVS only) - fixes compilation of ppp_oe.c
-
-  2009-05-02 Simon Goldschmidt
-  * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields
-
-  2009-05-01 Simon Goldschmidt
-  * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets
-
-  2009-05-01 Simon Goldschmidt
-  * ppp.c: bug #24228: Memory corruption with PPP and DHCP
-
-  2009-04-29 Frédéric Bernon
-  * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the
-    SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception
-    of broadcast packets even when this option wasn't set. Port maintainers
-    which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h.
-    If you want this option also filter broadcast on recv operations, you also
-    have to set IP_SOF_BROADCAST_RECV=1 in opt.h.
-
-  2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen
-  * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and
-    DHCP/AUTOIP cooperation
-
-  2009-04-25 Simon Goldschmidt, Oleg Tyshev
-  * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd
-    Fixed by sorting the unsent and unacked queues (segments are inserted at the
-    right place in tcp_output and tcp_rexmit).
-
-  2009-04-25 Simon Goldschmidt
-  * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation
-    when debugging": memp_sizes contained the wrong sizes (including sanity
-    regions); memp pools for MEM_USE_POOLS were too small
-
-  2009-04-24 Simon Goldschmidt, Frédéric Bernon
-  * inet.c: patch #6765: Fix a small problem with the last changes (incorrect
-    behavior, with with ip address string not ended by a '\0', a space or a
-    end of line)
-
-  2009-04-19 Simon Goldschmidt
-  * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails,
-    pcb->err is called, not pcb->connected (with an error code).
-
-  2009-04-19 Simon Goldschmidt
-  * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with
-    no-copy-tcpwrite": deallocate option data, only concat segments with same flags
-
-  2009-04-19 Simon Goldschmidt
-  * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated
-    in the header pbuf, not the data pbuf)
-
-  2009-04-18 Simon Goldschmidt
-  * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore()
-
-  2009-04-15 Simon Goldschmidt
-  * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp
-
-  2009-04-15 Simon Goldschmidt
-  * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in
-
-  2009-04-15 Simon Goldschmidt
-  * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function
-    ip_hinted_output() (for smaller code mainly)
-
-  2009-04-15 Simon Goldschmidt
-  * inet.c: patch #6765: Supporting new line characters in inet_aton()
-
-  2009-04-15 Simon Goldschmidt
-  * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option;
-    Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu
-    is big enough in dhcp_start
-
-  2009-04-15 Simon Goldschmidt
-  * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak
-
-  2009-04-15 Simon Goldschmidt
-  * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY
-
-  2009-04-15 Simon Goldschmidt
-  * sockets.c: bug #26121: set_errno can be overridden
-
-  2009-04-09 Kieran Mansley (patch from Luca Ceresoli <lucaceresoli>)
-  * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when
-    LWIP_TCP==0
-
-  2009-04-09 Kieran Mansley (patch from Roy Lee <roylee17>)
-  * tcp.h: Patch#6802 Add do-while-clauses to those function like
-    macros in tcp.h
-
-  2009-03-31 Kieran Mansley
-  * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window
-    updates are calculated and sent (BUG20515)
-
-  * tcp_in.c: cope with SYN packets received during established states,
-    and retransmission of initial SYN.
-
-  * tcp_out.c: set push bit correctly when tcp segments are merged
-
-  2009-03-27 Kieran Mansley
-  * tcp_out.c set window correctly on probes (correcting change made
-    yesterday)
-
-  2009-03-26 Kieran Mansley
-  * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping
-    connections where no reset required (bug #25622)
-
-  * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes 
-    (bug #20779)
-
-  2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach)
-  * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be
-    too small depending on MEM_ALIGNMENT
-
-  2009-02-16 Simon Goldschmidt
-  * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard;
-    converted size argument of netconn_write to 'size_t'
-
-  2009-02-16 Simon Goldschmidt
-  * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host
-    by moving accept callback function pointer to TCP_PCB_COMMON
-
-  2009-02-12 Simon Goldschmidt
-  * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size"
-    option)
-
-  2009-02-11 Simon Goldschmidt
-  * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start)
-
-  2009-02-11 Simon Goldschmidt
-  * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize:
-    RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv())
-
-  2009-02-10 Simon Goldschmidt
-  * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD:
-    Accepts_pending is decrease on a corresponding listen pcb when a connection
-    in state SYN_RCVD is close.
-
-  2009-01-28 Jonathan Larmour
-  * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run
-    out of pool pbufs.
-
-  2008-12-19 Simon Goldschmidt
-  * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 
-
-  2008-12-10 Tamas Somogyi, Frédéric Bernon
-  * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and
-    port uses deleted netbuf.
-
-  2008-10-18 Simon Goldschmidt
-  * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length
-    in tcp_parseopt
-
-  2008-10-15 Simon Goldschmidt
-  * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers
-    by packing the struct ip_reass_helper.
-
-  2008-10-03 David Woodhouse, Jonathan Larmour
-  * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address.
-
-  2008-10-02 Jonathan Larmour
-  * dns.c: Hard-code structure sizes, to avoid issues on some compilers where
-    padding is included.
-
-  2008-09-30 Jonathan Larmour
-  * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an
-    assertion check that addrlen isn't NULL.
-
-  2008-09-30 Jonathan Larmour
-  * tcp.c: Fix bug #24227, wrong error message in tcp_bind.
-
-  2008-08-26 Simon Goldschmidt
-  * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and
-    inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h
-
-  2008-08-14 Simon Goldschmidt
-  * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when
-    tcp_close returns != ERR_OK)
-
-  2008-07-08 Frédéric Bernon
-  * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters
-    in macros, mainly if MEM_STATS=0 and MEMP_STATS=0).
-
-  2008-06-24 Jonathan Larmour
-  * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused
-    if tcp_seg_copy fails.
-
-  2008-06-17 Simon Goldschmidt
-  * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations)
-    and created defines for swapping bytes and folding u32 to u16.
-
-  2008-05-30 Kieran Mansley
-  * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd
-    rather than rcv_ann_wnd when deciding if packets are in-window.
-    Contributed by <arasmussen@consultant.datasys.swri.edu>
-
-  2008-05-30 Kieran Mansley
-  * mem.h: Fix BUG#23254.  Change macro definition of mem_* to allow
-    passing as function pointers when MEM_LIBC_MALLOC is defined.
-
-  2008-05-09 Jonathan Larmour
-  * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to
-    stop it being treated as a fatal error.
-
-  2008-04-15 Simon Goldschmidt
-  * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP
-    (flag now cleared)
-
-  2008-03-27 Simon Goldschmidt
-  * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free
-    from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1
-    in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs
-    or heap memory from interrupt context
-
-  2008-03-26 Simon Goldschmidt
-  * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote
-    host sent a zero mss as TCP option.
-
-
-(STABLE-1.3.0)
-
-  ++ New features:
-
-  2008-03-10 Jonathan Larmour
-  * inet_chksum.c: Allow choice of one of the sample algorithms to be
-    made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM.
-
-  2008-01-22 Frédéric Bernon
-  * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in 
-    TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names.
-
-  2008-01-14 Frédéric Bernon
-  * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable
-    to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the
-    tcp_recv callback (see rawapi.txt).
-
-  2008-01-14 Frédéric Bernon, Marc Chaland
-  * ip.c: Integrate patch #6369" ip_input : checking before realloc".
-  
-  2008-01-12 Frédéric Bernon
-  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
-    netconn::sem per netconn::op_completed like suggested for the task #7490
-    "Add return value to sys_mbox_post".
-
-  2008-01-12 Frédéric Bernon
-  * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE,
-    DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues
-    sizes), like suggested for the task #7490 "Add return value to sys_mbox_post".
-
-  2008-01-10 Frédéric Bernon
-  * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490
-    "Add return value to sys_mbox_post". tcpip_callback is always defined as
-    "blocking" ("block" parameter = 1).
-
-  2008-01-10 Frédéric Bernon
-  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
-    netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490
-    "Add return value to sys_mbox_post".
-
-  2008-01-05 Frédéric Bernon
-  * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h:
-    Introduce changes for task #7490 "Add return value to sys_mbox_post" with some
-    modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which
-    indicate the number of pointers query by the mailbox. There is three defines
-    in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the 
-    netconn::acceptmbox. Port maintainers, you can decide to just add this new 
-    parameter in your implementation, but to ignore it to keep the previous behavior.
-    The new sys_mbox_trypost function return a value to know if the mailbox is
-    full or if the message is posted. Take a look to sys_arch.txt for more details.
-    This new function is used in tcpip_input (so, can be called in an interrupt
-    context since the function is not blocking), and in recv_udp and recv_raw.
-
-  2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour
-  * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c,
-    tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the
-    "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add
-    documentation in the rawapi.txt file.
-
-  2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
-  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer
-
-  2007-12-31 Frédéric Bernon, Luca Ceresoli
-  * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets
-    in autoip". The change in etharp_raw could be removed, since all calls to
-    etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be
-    wrong in the future.
-
-  2007-12-30 Frédéric Bernon, Tom Evans
-  * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address
-    Filtering" reported by Tom Evans.
-
-  2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour
-  * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c,
-    sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API
-    applications have to call 'tcp_accepted(pcb)' in their accept callback to
-    keep accepting new connections.
-
-  2007-12-13 Frédéric Bernon
-  * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result"
-    by err_t type. Add a new err_t code "ERR_INPROGRESS".
-
-  2007-12-12 Frédéric Bernon
-  * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles
-    are the one which have ram usage.
-
-  2007-12-05 Frédéric Bernon
-  * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static
-    set of variables (=0) or a local one (=1). In this last case, your port should
-    provide a function "struct hostent* sys_thread_hostent( struct hostent* h)"
-    which have to do a copy of "h" and return a pointer ont the "per-thread" copy.
-
-  2007-12-03 Simon Goldschmidt
-  * ip.c: ip_input: check if a packet is for inp first before checking all other
-    netifs on netif_list (speeds up packet receiving in most cases)
-
-  2007-11-30 Simon Goldschmidt
-  * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access
-    UDP: move a (connected) pcb selected for input to the front of the list of
-    pcbs so that it is found faster next time. Same for RAW pcbs that have eaten
-    a packet.
-
-  2007-11-28 Simon Goldschmidt
-  * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS
-
-  2007-11-25 Simon Goldschmidt
-  * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy
-    algorithm.
-
-  2007-11-24 Simon Goldschmidt
-  * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c
-    to the new file netdb.c; included lwip_getaddrinfo.
-
-  2007-11-21 Simon Goldschmidt
-  * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss
-    based on the MTU of the netif used to send. Enabled by default. Disable by
-    setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492.
-
-  2007-11-19 Frédéric Bernon
-  * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name
-    received match the name query), implement DNS_USES_STATIC_BUF (the place where
-    copy dns payload to parse the response), return an error if there is no place
-    for a new query, and fix some minor problems.
-
-  2007-11-16 Simon Goldschmidt
-  * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c
-    removed files: core/inet.c, core/inet6.c
-    Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into
-    inet and chksum part; changed includes in all lwIP files as appropriate
-
-  2007-11-16 Simon Goldschmidt
-  * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential
-    dns resolver function for netconn api (netconn_gethostbyname) and socket api
-    (gethostbyname/gethostbyname_r).
-
-  2007-11-15 Jim Pettinato, Frédéric Bernon
-  * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name
-    requests with RAW api interface. Initialization is done in lwip_init() with
-    build time options. DNS timer is added in tcpip_thread context. DHCP can set
-    DNS server ip addresses when options are received. You need to set LWIP_DNS=1
-    in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get
-    some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo"
-    list with points to improve.
-
-  2007-11-06 Simon Goldschmidt
-  * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly
-    enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status
-    for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined.
-
-  2007-11-06 Simon Goldschmidt
-  * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include
-    core header files in api.h (ip/tcp/udp/raw.h) to hide the internal
-    implementation from netconn api applications.
-
-  2007-11-03 Frédéric Bernon
-  * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP &
-    RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled
-    by default). Netconn API users can use the netconn_recv_bufsize macro to access
-    it. This is a first release which have to be improve for TCP. Note it used the
-    netconn::recv_avail which need to be more "thread-safe" (note there is already
-    the problem for FIONREAD with lwip_ioctl/ioctlsocket).
-
-  2007-11-01 Frédéric Bernon, Marc Chaland
-  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c:
-    Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api
-    layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api
-    layer. This option enable to delayed TCP PUSH flag on multiple "write" calls.
-    Note that previous "copy" parameter for "write" APIs is now called "apiflags".
-
-  2007-10-24 Frédéric Bernon
-  * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than 
-    TCP_EVENT_xxx macros to get a code more readable. It could also help to remove
-    some code (like we have talk in "patch #5919 : Create compile switch to remove
-    select code"), but it could be done later.
-
-  2007-10-08 Simon Goldschmidt
-  * many files: Changed initialization: many init functions are not needed any
-    more since we now rely on the compiler initializing global and static
-    variables to zero!
-
-  2007-10-06 Simon Goldschmidt
-  * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY
-    to enqueue the received pbufs so that multiple packets can be reassembled
-    simultaneously and no static reassembly buffer is needed.
-
-  2007-10-05 Simon Goldschmidt
-  * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so
-    all netifs (or ports) can use it.
-
-  2007-10-05 Frédéric Bernon
-  * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the 
-    common function to reduce a little bit the footprint (for all functions using
-    only the "netif" parameter).
-
-  2007-10-03 Frédéric Bernon
-  * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down,
-    netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce
-    a little bit the footprint (for all functions using only the "netif" parameter).
-
-  2007-09-15 Frédéric Bernon
-  * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF
-    option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for
-    netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for
-    IP_MULTICAST_TTL and IP_MULTICAST_IF.
-
-  2007-09-10 Frédéric Bernon
-  * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles
-    even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime()
-    each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can
-    decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but
-    call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime()
-    or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro.
-    This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside
-    snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only
-    when it's queried (any direct call to "sysuptime" is changed by a call to 
-    snmp_get_sysuptime).
-
-  2007-09-09 Frédéric Bernon, Bill Florac
-  * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP,
-    and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags
-    if you want IGMP on an interface. igmp_stop() is now called inside netif_remove().
-    igmp_report_groups() is now called inside netif_set_link_up() (need to have
-    LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait
-    the next query message to receive the matching multicast streams).
-
-  2007-09-08 Frédéric Bernon
-  * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains
-    IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change).
-    Use this new field to access to common pcb fields (ttl, tos, so_options, etc...).
-    Enable to access to these fields with LWIP_TCP=0.
-
-  2007-09-05 Frédéric Bernon
-  * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h,
-    ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option
-    LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default).
-    Be careful, disabling ICMP make your product non-compliant to RFC1122, but
-    help to reduce footprint, and to reduce "visibility" on the Internet.
-
-  2007-09-05 Frédéric Bernon, Bill Florac
-  * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list
-    for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new
-    parameters have to be provided: a task name, and a task stack size. For this
-    one, since it's platform dependant, you could define the best one for you in
-    your lwipopts.h. For port maintainers, you can just add these new parameters
-    in your sys_arch.c file, and but it's not mandatory, use them in your OS
-    specific functions.
-
-  2007-09-05 Frédéric Bernon
-  * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings
-    inside init.c for task #7142 "Sanity check user-configurable values".
-
-  2007-09-04 Frédéric Bernon, Bill Florac
-  * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by
-    memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the
-    value). It will avoid potential fragmentation problems, use a counter to know
-    how many times a group is used on an netif, and free it when all applications
-    leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity
-    check if LWIP_IGMP!=0).
-
-  2007-09-03 Frédéric Bernon
-  * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement".
-    Initialize igmp_mac_filter to NULL in netif_add (this field should be set in
-    the netif's "init" function). Use the "imr_interface" field (for socket layer)
-    and/or the "interface" field (for netconn layer), for join/leave operations.
-    The igmp_join/leavegroup first parameter change from a netif to an ipaddr.
-    This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany).
-
-  2007-08-30 Frédéric Bernon
-  * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions
-    from api/api_lib". Now netbuf API is independant of netconn, and can be used
-    with other API (application based on raw API, or future "socket2" API). Ports
-    maintainers just have to add src/api/netbuf.c in their makefile/projects.
-
-  2007-08-30 Frédéric Bernon, Jonathan Larmour
-  * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check
-    user-configurable values".
-
-  2007-08-29 Frédéric Bernon
-  * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start.
-    igmp_start is call inside netif_add. Now, igmp initialization is in the same
-    spirit than the others modules. Modify some IGMP debug traces.
-
-  2007-08-29 Frédéric Bernon
-  * Add init.h, init.c, Change opt.h, tcpip.c: Task  #7213 "Add a lwip_init function"
-    Add lwip_init function to regroup all modules initializations, and to provide
-    a place to add code for task #7142 "Sanity check user-configurable values".
-    Ports maintainers should remove direct initializations calls from their code,
-    and add init.c in their makefiles. Note that lwip_init() function is called
-    inside tcpip_init, but can also be used by raw api users since all calls are
-    disabled when matching options are disabled. Also note that their is new options
-    in opt.h, you should configure in your lwipopts.h (they are enabled per default).
-
-  2007-08-26 Marc Boucher
-  * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL
-    since they can under certain circumstances be called with an invalid conn
-    pointer after the connection has been closed (and conn has been freed). 
-
-  2007-08-25 Frédéric Bernon (Artem Migaev's Patch)
-  * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up".
-    Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set.
-
-  2007-08-22 Frédéric Bernon
-  * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK
-    to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release.
-
-  2007-08-22 Frédéric Bernon
-  * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT &
-    ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the 
-    name is tcpip_input (we keep the name of 1.2.0 function).
-
-  2007-08-17 Jared Grubb
-  * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool 
-    settings into new memp_std.h and optional user file lwippools.h. This adds
-    more dynamic mempools, and allows the user to create an arbitrary number of
-    mempools for mem_malloc.
-
-  2007-08-16 Marc Boucher
-  * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function;
-    otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely
-    close the connection.
-
-  2007-08-16 Marc Boucher
-  * sockets.c: lwip_accept(): check netconn_peer() error return.
-
-  2007-08-16 Marc Boucher
-  * mem.c, mem.h: Added mem_calloc().
-
-  2007-08-16 Marc Boucher
-  * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT)
-    for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG
-    and starving other message types.
-    Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API
-
-  2007-08-16 Marc Boucher
-  * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf
-    type and flgs (later renamed to flags).
-    Use enum pbuf_flag as pbuf_type.  Renumber PBUF_FLAG_*.
-    Improved lwip_recvfrom().  TCP push now propagated.
-
-  2007-08-16 Marc Boucher
-  * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global
-    provided by etharp.
-
-  2007-08-16 Marc Boucher
-  * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h,
-    etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c:
-    Added PPPoE support and various PPP improvements.
-
-  2007-07-25 Simon Goldschmidt
-  * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial,
-    making netbuf_copy_partial use this function.
-
-  2007-07-25 Simon Goldschmidt
-  * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with
-    2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and
-    other stacks.
-
-  2007-07-13 Jared Grubb (integrated by Frédéric Bernon)
-  * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add
-    a link callback in the netif struct, and functions to handle it. Be carefull
-    for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c)
-    if you want to be sure to be compatible with future changes...
-
-  2007-06-30 Frédéric Bernon
-  * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions.
-
-  2007-06-21 Simon Goldschmidt
-  * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both
-    LWIP_AUTOIP =0 and =1 to remove redundant code.
-
-  2007-06-21 Simon Goldschmidt
-  * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option
-    MEM_USE_POOLS to use 4 pools with different sized elements instead of a
-    heap. This both prevents memory fragmentation and gives a higher speed
-    at the cost of more memory consumption. Turned off by default.
-
-  2007-06-21 Simon Goldschmidt
-  * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of
-    netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into
-    int to be able to send a bigger buffer than 64K with one time (mainly
-    used from lwip_send).
-
-  2007-06-21 Simon Goldschmidt
-  * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write
-    into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too.
-
-  2007-06-21 Simon Goldschmidt
-  * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in
-    netconn_write from api_lib.c to api_msg.c to also prevent multiple context-
-    changes on low memory or empty send-buffer.
-
-  2007-06-18 Simon Goldschmidt
-  * etharp.c, etharp.h: Changed etharp to use a defined hardware address length
-    of 6 to avoid loading netif->hwaddr_len every time (since this file is only
-    used for ethernet and struct eth_addr already had a defined length of 6).
-
-  2007-06-17 Simon Goldschmidt
-  * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets
-    to disable UDP checksum generation on transmit.
-
-  2007-06-13 Frédéric Bernon, Simon Goldschmidt
-  * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid
-    pointers or parameters, and let the possibility to redefined it in cc.h. Use
-    this macro to check "conn" parameter in api_msg.c functions.
-
-  2007-06-11 Simon Goldschmidt
-  * sockets.c, sockets.h: Added UDP lite support for sockets
-
-  2007-06-10 Simon Goldschmidt
-  * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled
-    by default) to switch off UDP-Lite support if not needed (reduces udp.c code
-    size)
-
-  2007-06-09 Dominik Spies (integrated by Frédéric Bernon)
-  * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h:
-    AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and
-    LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt
-    (see TODO mark in the source code).
-
-  2007-06-09 Simon Goldschmidt
-  * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for
-    etharp_output() to match netif->output so etharp_output() can be used
-    directly as netif->output to save one function call.
-
-  2007-06-08 Simon Goldschmidt
-  * netif.h, ethernetif.c, slipif.c, loopif.c: Added define
-    NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables,
-    added initialization of those to ethernetif, slipif and loopif.
-
-  2007-05-18 Simon Goldschmidt
-  * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF
-    (defaulting to off for now) that can be set to 0 to send fragmented
-    packets by passing PBUF_REFs down the stack.
-
-  2007-05-23 Frédéric Bernon
-  * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP
-    connections, such present in patch #5959.
-
-  2007-05-23 Frédéric Bernon
-  * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx
-    code in only one part...
-
-  2007-05-18 Simon Goldschmidt
-  * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp
-    elements to overflow. This is achieved by adding some bytes before and after
-    each pool element (increasing their size, of course), filling them with a
-    prominent value and checking them on freeing the element.
-    Set it to 2 to also check every element in every pool each time memp_malloc()
-    or memp_free() is called (slower but more helpful).
-
-  2007-05-10 Simon Goldschmidt
-  * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for
-    PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce
-    code size.
-
-  2007-05-11 Frédéric Bernon
-  * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c:
-    Include a function pointer instead of a table index in the message to reduce
-    footprint. Disable some part of lwip_send and lwip_sendto if some options are
-    not set (LWIP_TCP, LWIP_UDP, LWIP_RAW).
-
-  2007-05-10 Simon Goldschmidt
-  * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus
-    \ extern "C" {' in all header files. Now you can write your application using
-    the lwIP stack in C++ and simply #include the core files. Note I have left
-    out the netif/ppp/*h header files for now, since I don't know which files are
-    included by applications and which are for internal use only.
-
-  2007-05-09 Simon Goldschmidt
-  * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library
-    memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for
-    situations where some compilers might inline the copy and save a function
-    call. Also replaced all calls to memcpy() with calls to (S)MEMCPY().
-
-  2007-05-08 Simon Goldschmidt
-  * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc())
-    to be overriden in case the C-library malloc implementation is not protected
-    against concurrent access.
-
-  2007-05-04 Simon Goldschmidt (Atte Kojo)
-  * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending
-    multiple packets to the same host.
-
-  2007-05-04 Frédéric Bernon, Jonathan Larmour
-  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible
-    to corrupt remote addr/port connection state". Reduce problems "not enought memory" with
-    netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between
-    sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function.
-    Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct,
-    these fields are now renamed "addr" & "port".
-
-  2007-04-11 Jonathan Larmour
-  * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new
-    sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return
-    with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro
-    by the port in sys_arch.h if desired.
-
-  2007-04-06 Frédéric Bernon, Simon Goldschmidt
-  * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API
-    allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp
-    clients, using new functions from netifapi.h. Disable as default (no port change to do).
-
-  2007-04-05 Frédéric Bernon
-  * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant.
-
-  2007-04-04 Simon Goldschmidt
-  * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x)
-    use this for and architecture-independent form to tell the compiler you intentionally
-    are not using this variable. Can be overriden in cc.h.
-
-  2007-03-28 Frédéric Bernon
-  * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to
-    define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded
-    string, point on one of your's ethernetif field, or alloc a string you will free yourself).
-    It will be used by DHCP to register a client hostname, but can also be use when you call
-    snmp_set_sysname.
-
-  2007-03-28 Frédéric Bernon
-  * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to 
-    initialize a network interface's flag with. It tell this interface is an ethernet
-    device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility
-    Support for IPv4" section 4.6) when interface is "up" with netif_set_up().
-
-  2007-03-26 Frédéric Bernon, Jonathan Larmour
-  * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build
-    time if you only use PPP or SLIP. The default is enable. Note we don't have to call 
-    etharp_init in your port's initilization sequence if you use tcpip.c, because this call
-    is done in tcpip_init function.
-
-  2007-03-22 Frédéric Bernon
-  * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the
-    new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in
-    your lwipopts.h. More, unused counters are not defined in the stats structs, and not 
-    display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined
-    but never used. Fix msg_in.c with the correct #if test for a stat display.
-
-  2007-03-21 Kieran Mansley
-  * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). 
-    Provides callback on netif up/down state change.
-
-  2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds
-  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c,
-    ip.c, netif.h, tcpip.c, opt.h:
-    New configuration option LWIP_IGMP to enable IGMP processing. Based on only one 
-    filter per all network interfaces. Declare a new function in netif to enable to
-    control the MAC filter (to reduce lwIP traffic processing).
-
-  2007-03-11 Frédéric Bernon
-  * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can
-    be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this
-    unless you know what you're doing (default are RFC1122 compliant). Note
-    that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds.
-
-  2007-03-08 Frédéric Bernon
-  * tcp.h: Keepalive values can be configured at compile time, but don't change
-    this unless you know what you're doing (default are RFC1122 compliant).
-
-  2007-03-08 Frédéric Bernon
-  * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h:
-    Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO
-    on UDP sockets/netconn.
-
-  2007-03-08 Simon Goldschmidt
-  * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time.
-
-  2007-03-06 Frédéric Bernon
-  * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: 
-    Implement SO_RCVTIMEO on UDP sockets/netconn.
-
-  2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt)
-  * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated
-    on the stack and remove the API msg type from memp
-
-  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
-  * sockets.h, sockets.c: Move socket initialization to new
-    lwip_socket_init() function.
-    NOTE: this changes the API with ports. Ports will have to be
-    updated to call lwip_socket_init() now.
-
-  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
-  * api_lib.c: Use memcpy in netbuf_copy_partial.
-
-
-  ++ Bug fixes:
-
-  2008-03-17 Frédéric Bernon, Ed Kerekes
-  * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have
-    some problems to fill the IP header on some targets, use now the
-    ip.h macros to do it).
-
-  2008-03-13 Frédéric Bernon
-  * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using
-    (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a
-    TCP connection caused a crash. Note that using (lwip_)recvfrom
-    like this is a bit slow and that using (lwip)getpeername is the
-    good lwip way to do it (so, using recv is faster on tcp sockets).
-
-  2008-03-12 Frédéric Bernon, Jonathan Larmour
-  * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's
-    recv_raw() does not consume data", and the ping sample (with
-    LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom
-    returned the IP payload, without the IP header).
-
-  2008-03-04 Jonathan Larmour
-  * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors
-  and/or warnings on some systems where mem_size_t and size_t differ.
-  * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc.
-
-  2008-03-04 Kieran Mansley (contributions by others) 
-  * Numerous small compiler error/warning fixes from contributions to
-    mailing list after 1.3.0 release candidate made.
-
-  2008-01-25 Cui hengbin (integrated by Frédéric Bernon)
-  * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures.
-
-  2008-01-15 Kieran Mansley
-  * tcp_out.c: BUG20511.  Modify persist timer to start when we are
-    prevented from sending by a small send window, not just a zero
-    send window.
-
-  2008-01-09 Jonathan Larmour
-  * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid
-    conflict with Linux system headers.
-
-  2008-01-06 Jonathan Larmour
-  * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP
-    address entirely on receiving a DHCPNAK, and restarting discovery.
-
-  2007-12-21 Simon Goldschmidt
-  * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail
-    is not protected" by using new macros for interlocked access to modify/test
-    netconn->recv_avail.
-
-  2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev)
-  * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state)
-
-  2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
-  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling
-    of silly window avoidance and prevent lwIP from shrinking the window)
-
-  2007-12-04 Simon Goldschmidt
-  * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last
-    data packet was lost): add assert that all segment lists are empty in
-    tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED
-    state from LAST_ACK in tcp_process
-
-  2007-12-02 Simon Goldschmidt
-  * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET
-    If including <sys/time.h> for system-struct timeval, LWIP_TIMEVAL_PRIVATE now
-    has to be set to 0 in lwipopts.h
-
-  2007-12-02 Simon Goldschmidt
-  * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always
-    allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen
-    netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox.
-    This is a fix for thread-safety and allocates all items needed for a netconn
-    when the netconn is created.
-
-  2007-11-30 Simon Goldschmidt
-  * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple
-    netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed
-    to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same
-    port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address)
-
-  2007-11-27 Simon Goldschmidt
-  * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by
-    letting ip_route only use netifs that are up.
-
-  2007-11-27 Simon Goldschmidt
-  * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF
-    and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and
-    sockets block most operations once they have seen a fatal error.
-
-  2007-11-27 Simon Goldschmidt
-  * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the
-    netif to send as an argument (to be able to send on netifs that are down).
-
-  2007-11-26 Simon Goldschmidt
-  * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs
-    arrive out-of-order
-
-  2007-11-21 Simon Goldschmidt
-  * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early
-    Fixed the nagle algorithm; nagle now also works for all raw API applications
-    and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY'
-
-  2007-11-12 Frédéric Bernon
-  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most
-    of the netconn_peer and netconn_addr processing is done inside tcpip_thread
-    context in do_getaddr.
-
-  2007-11-10 Simon Goldschmidt
-  * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can
-    happen any time). Now the packet simply isn't enqueued when out of memory.
-
-  2007-11-01 Simon Goldschmidt
-  * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or
-    TCP_MSS if that is smaller) as long as no MSS option is received from the
-    remote host.
-
-  2007-11-01 Simon Goldschmidt
-  * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN)
-    is now based on TCP_MSS instead of pcb->mss (on passive open now effectively
-    sending our configured TCP_MSS instead of the one received).
-
-  2007-11-01 Simon Goldschmidt
-  * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was
-    calculated based on the configured TCP_MSS, not on the MSS option received
-    with SYN+ACK.
-
-  2007-10-09 Simon Goldschmidt
-  * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too
-    short and also was generated wrong if checksum coverage != tot_len;
-    receive: checksum was calculated wrong if checksum coverage != tot_len
-
-  2007-10-08 Simon Goldschmidt
-  * mem.c: lfree was not updated in mem_realloc!
-
-  2007-10-07 Frédéric Bernon
-  * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential
-    crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT:
-    this change cause an API breakage for netconn_addr, since a parameter
-    type change. Any compiler should cause an error without any changes in
-    yours netconn_peer calls (so, it can't be a "silent change"). It also
-    reduce a little bit the footprint for socket layer (lwip_getpeername &
-    lwip_getsockname use now a common lwip_getaddrname function since 
-    netconn_peer & netconn_addr have the same parameters).
-
-  2007-09-20 Simon Goldschmidt
-  * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state)
-    by checking  tcp_tw_pcbs also
-
-  2007-09-19 Simon Goldschmidt
-  * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies)
-
-  2007-09-15 Mike Kleshov
-  * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used)
-
-  2007-09-06 Frédéric Bernon
-  * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove
-    it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which
-    already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h"
-    if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h.
-
-  2007-08-30 Frédéric Bernon
-  * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, 
-    and fix some coding style.
-
-  2007-08-28 Frédéric Bernon
-  * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any
-    kind of packets. These packets are considered like Ethernet packets (payload 
-    pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets 
-    are considered like IP packets (payload pointing to iphdr).
-
-  2007-08-27 Frédéric Bernon
-  * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error
-    problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state
-    and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT).
-
-  2007-08-24 Kieran Mansley
-  * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy
-    compiler (Paradigm C++)
-
-  2007-08-09 Frédéric Bernon, Bill Florac
-  * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement.
-    Introduce IGMP_STATS to centralize statistics management.
-
-  2007-08-09 Frédéric Bernon, Bill Florac
-  * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast
-    packet on a udp pcb binded on an netif's IP address, and not on "any".
-
-  2007-08-09 Frédéric Bernon, Bill Florac
-  * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement.
-    This is mainly on using lookup/lookfor, and some coding styles...
-
-  2007-07-26 Frédéric Bernon (and "thedoctor")
-  * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages.
-
-  2007-07-25 Simon Goldschmidt
-  * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if
-    tcp_output fails in tcp_close, the code in do_close_internal gets simpler
-    (tcp_output is called again later from tcp timers).
-
-  2007-07-25 Simon Goldschmidt
-  * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old
-    copy_from_pbuf, which illegally modified the given pbuf.
-
-  2007-07-25 Simon Goldschmidt
-  * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs:
-    changed snd_queuelen++ to snd_queuelen += pbuf_clen(p).
-
-  2007-07-24 Simon Goldschmidt
-  * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the
-    correct state (must be CLOSED).
-
-  2007-07-13 Thomas Taranowski (commited by Jared Grubb)
-  * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed
-    allocation. It now returns NULL.
-
-  2007-07-13 Frédéric Bernon
-  * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in
-    all error cases.
-
-  2007-07-13 Frédéric Bernon
-  * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed,
-    because current code doesn't follow rawapi.txt documentation.
-
-  2007-07-13 Kieran Mansley
-  * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in
-    out of sequence processing of received packets
-
-  2007-07-03 Simon Goldschmidt
-  * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an
-    assumption is made that this pbuf is in one piece (i.e. not chained). These
-    assumptions clash with the possibility of converting to fully pool-based
-    pbuf implementations, where PBUF_RAM pbufs might be chained.
-
-  2007-07-03 Simon Goldschmidt
-  * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems
-    when closing tcp netconns: removed conn->sem, less context switches when
-    closing, both netconn_close and netconn_delete should safely close tcp
-    connections.
-
-  2007-07-02 Simon Goldschmidt
-  * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c,
-    tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off)
-    to cache ARP table indices with each pcb instead of single-entry cache for
-    the complete stack.
-
-  2007-07-02 Simon Goldschmidt
-  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent
-    warnings when assigning to smaller types.
-
-  2007-06-28 Simon Goldschmidt
-  * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing.
-
-  2007-06-28 Simon Goldschmidt
-  * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if
-    a segment contained chained pbufs)
-
-  2007-06-28 Frédéric Bernon
-  * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute
-    a "pseudo-random" value based on netif's MAC and some autoip fields. It's always
-    possible to define this macro in your own lwipopts.h to always use C library's
-    rand(). Note that autoip_create_rand_addr doesn't use this macro.
-
-  2007-06-28 Frédéric Bernon
-  * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option
-    LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications
-    in api_lib/api_msg (use pointers and not type with table, etc...) 
-
-  2007-06-26 Simon Goldschmidt
-  * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines.
-
-  2007-06-25 Simon Goldschmidt
-  * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload
-    for udp packets with no matching pcb.
-
-  2007-06-25 Simon Goldschmidt
-  * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match
-    could get udp input packets if the remote side matched.
-
-  2007-06-13 Simon Goldschmidt
-  * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get
-    changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0.
-
-  2007-06-13 Simon Goldschmidt
-  * api_msg.c: pcb_new sets conn->err if protocol is not implemented
-    -> netconn_new_..() does not allocate a new connection for unsupported
-    protocols.
-
-  2007-06-13 Frédéric Bernon, Simon Goldschmidt
-  * api_lib.c: change return expression in netconn_addr and netconn_peer, because
-    conn->err was reset to ERR_OK without any reasons (and error was lost)...
-
-  2007-06-13 Frédéric Bernon, Matthias Weisser
-  * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename
-    MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid
-    some macro names collision with some OS macros.
-
-  2007-06-11 Simon Goldschmidt
-  * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0,
-    create checksum over the complete packet. On RX, if it's < 8 (and not 0),
-    discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both
-    UDP & UDP Lite.
-
-  2007-06-11 Srinivas Gollakota & Oleg Tyshev
-  * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags"
-    where TCP flags wasn't initialized in tcp_keepalive.
-
-  2007-06-03 Simon Goldschmidt
-  * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function
-    registered, p->payload was modified without modifying p->len if sending
-    icmp_dest_unreach() (had no negative effect but was definitively wrong).
-
-  2007-06-03 Simon Goldschmidt
-  * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp
-    re-used the input pbuf even if that didn't have enough space to include the
-    link headers. Now the space is tested and a new pbuf is allocated for the
-    echo response packet if the echo request pbuf isn't big enough.
-
-  2007-06-01 Simon Goldschmidt
-  * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread.
-
-  2007-05-23 Frédéric Bernon
-  * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only
-    allocated by do_listen if success) and netconn_accept errors handling. In
-    most of api_lib functions, we replace some errors checkings like "if (conn==NULL)"
-    by ASSERT, except for netconn_delete.
-
-  2007-05-23 Frédéric Bernon
-  * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return
-    an error code if it's impossible to fetch a pbuf on a TCP connection (and not
-    directly close the recvmbox).
-
-  2007-05-22 Simon Goldschmidt
-  * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of
-    bound but unconnected (and non-listening) tcp_pcbs.
-
-  2007-05-22 Frédéric Bernon
-  * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only
-    used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of
-    sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features
-    like "sys_timeout" in their application threads.
-
-  2007-05-22 Frédéric Bernon
-  * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see
-    which parameters are used by which do_xxx function, and to avoid "misusing"
-    parameters (patch #5938).
-
-  2007-05-22 Simon Goldschmidt
-  * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938:
-    changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto
-    is only 8 bits wide. This affects the api, as there, the protocol was
-    u16_t, too.
-
-  2007-05-18 Simon Goldschmidt
-  * memp.c: addition to patch #5913: smaller pointer was returned but
-    memp_memory was the same size -> did not save memory.
-
-  2007-05-16 Simon Goldschmidt
-  * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns
-    != ERR_OK.
-
-  2007-05-16 Simon Goldschmidt
-  * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same
-    as the one of the netif used for sending to prevent sending from old
-    addresses after a netif address gets changed (partly fixes bug #3168).
-
-  2007-05-16 Frédéric Bernon
-  * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work
-    with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in 
-    tcpip_init) because we have to be sure that network interfaces are already
-    added (mac filter is updated only in igmp_init for the moment).
-
-  2007-05-16 Simon Goldschmidt
-  * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls
-    into sys_arch_sem_wait calls to prevent timers from running while waiting
-    for the heap. This fixes bug #19167.
-
-  2007-05-13 Simon Goldschmidt
-  * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines
-    for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from
-    tcp.h to sockets.h.
-
-  2007-05-07 Simon Goldschmidt
-  * mem.c: Another attempt to fix bug #17922.
-
-  2007-05-04 Simon Goldschmidt
-  * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy()
-    implementation so that it can be reused (don't allocate the target
-    pbuf inside pbuf_copy()).
-
-  2007-05-04 Simon Goldschmidt
-  * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem
-    to save a little RAM (next pointer of memp is not used while not in pool).
-
-  2007-05-03 "maq"
-  * sockets.c: Fix ioctl FIONREAD when some data remains from last recv.
-    (patch #3574).
-
-  2007-04-23 Simon Goldschmidt
-  * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results
-    in NULL reference for incoming TCP packets". Loopif has to be configured
-    (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input()
-    (multithreading environments, e.g. netif->input() = tcpip_input()) or
-    putting packets on a list that is fed to the stack by calling loopif_poll()
-    (single-thread / NO_SYS / polling environment where e.g.
-    netif->input() = ip_input).
-
-  2007-04-17 Jonathan Larmour
-  * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold
-    the difference between two u16_t's.
-  * sockets.h: FD_SETSIZE needs to match number of sockets, which is
-    MEMP_NUM_NETCONN in sockets.c right now.
-
-  2007-04-12 Jonathan Larmour
-  * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580).
-
-  2007-04-12 Kieran Mansley
-  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission
-    timer is reset to fix bug#19434, with help from Oleg Tyshev.
-
-  2007-04-11 Simon Goldschmidt
-  * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than
-    previously thought need to be copied (everything but PBUF_ROM!). Cleaned up
-    pbuf.c: removed functions no needed any more (by etharp).
-
-  2007-04-11 Kieran Mansley
-  * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix
-    "Constant is long" warnings with 16bit compilers.  Contributed by
-    avatar@mmlab.cse.yzu.edu.tw
-
-  2007-04-05 Frédéric Bernon, Jonathan Larmour
-  * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on
-    the mailbox is active". Now, the post is only done during a connect, and do_send,
-    do_write and do_join_leave_group don't do anything if a previous error was signaled.
-
-  2007-04-03 Frédéric Bernon
-  * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output
-    packets. See patch #5834.
-
-  2007-03-30 Frédéric Bernon
-  * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add
-    missing  pcb allocations checking (in do_bind, and for each raw_new). Fix style.
-
-  2007-03-30 Frédéric Bernon
-  * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with
-    others environment defines (these were too "generic").
-
-  2007-03-28 Frédéric Bernon
-  * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call
-    result and can cause a crash. lwip_send now check netbuf_ref result.
-
-  2007-03-28 Simon Goldschmidt
-  * sockets.c Remove "#include <errno.h>" from sockets.c to avoid multiple
-    definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is
-    defined. This is the way it should have been already (looking at
-    doc/sys_arch.txt)
-
-  2007-03-28 Kieran Mansley
-  * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS +
-    IP and TCP headers *and* physical link headers
-
-  2007-03-26 Frédéric Bernon (based on patch from Dmitry Potapov)
-  * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause
-    to send some garbage. It is not a definitive solution, but the patch does solve
-    the problem for most cases.
-
-  2007-03-22 Frédéric Bernon
-  * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used).
-
-  2007-03-22 Frédéric Bernon
-  * api_lib.c: somes resources couldn't be freed if there was errors during
-    netconn_new_with_proto_and_callback.
-
-  2007-03-22 Frédéric Bernon
-  * ethernetif.c: update netif->input calls to check return value. In older ports,
-    it's a good idea to upgrade them, even if before, there could be another problem
-    (access to an uninitialized mailbox).
-
-  2007-03-21 Simon Goldschmidt
-  * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed
-    by casting to unsigned).
-
-  2007-03-21 Frédéric Bernon
-  * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from
-    api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a
-    dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call.
-    Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a
-    faster and more reliable communication between api_lib and tcpip.
-
-  2007-03-21 Frédéric Bernon
-  * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0.
-
-  2007-03-21 Frédéric Bernon
-  * api_msg.c, igmp.c, igmp.h: Fix C++ style comments
-
-  2007-03-21 Kieran Mansley
-  * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS +
-    IP and TCP headers
-
-  2007-03-21 Kieran Mansley
-  * Fix all uses of pbuf_header to check the return value.  In some
-    cases just assert if it fails as I'm not sure how to fix them, but
-    this is no worse than before when they would carry on regardless
-    of the failure.
-
-  2007-03-21 Kieran Mansley
-  * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and
-    comment out missing header include in icmp.c
-
-  2007-03-20 Frédéric Bernon
-  * memp.h, stats.c: Fix stats_display function where memp_names table wasn't
-    synchronized with memp.h.
-
-  2007-03-20 Frédéric Bernon
-  * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input,
-    tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with 
-    network interfaces. Also fix a compiler warning.
-
-  2007-03-20 Kieran Mansley
-  * udp.c: Only try and use pbuf_header() to make space for headers if
-    not a ROM or REF pbuf.
-
-  2007-03-19 Frédéric Bernon
-  * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg()
-    and api_msg_post().
-
-  2007-03-19 Frédéric Bernon
-  * Remove unimplemented "memp_realloc" function from memp.h.
-
-  2007-03-11 Simon Goldschmidt
-  * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused
-    memory corruption.
-
-  2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov)
-  * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251
-    (missing `const' qualifier in socket functions), to get more compatible to
-    standard POSIX sockets.
-
-  2007-03-11 Frédéric Bernon (based on patch from Dmitry Potapov)
-  * sockets.c: Add asserts inside bind, connect and sendto to check input
-    parameters. Remove excessive set_errno() calls after get_socket(), because
-    errno is set inside of get_socket(). Move last sock_set_errno() inside
-    lwip_close.
-
-  2007-03-09 Simon Goldschmidt
-  * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory
-    was allocated too small.
-
-  2007-03-06 Simon Goldschmidt
-  * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect
-    the stack from concurrent access.
-
-  2007-03-06 Frédéric Bernon, Dmitry Potapov
-  * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy
-    call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input().
-
-  2007-03-06 Simon Goldschmidt
-  * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files
-    if IP_FRAG == 0 and IP_REASSEMBLY == 0
-
-  2007-03-06 Frédéric Bernon, Simon Goldschmidt
-  * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration
-    option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput.
-    Allow to do ARP processing for incoming packets inside tcpip_thread
-    (protecting ARP layer against concurrent access). You can also disable
-    old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0.
-    Older ports have to use tcpip_ethinput.
-
-  2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov)
-  * err.h, err.c: fixed compiler warning "initialization dircards qualifiers
-    from pointer target type"
-
-  2007-03-05 Frédéric Bernon
-  * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES,
-    ETHARP_TRUST_IP_MAC, review SO_REUSE)
-
-  2007-03-04 Frédéric Bernon
-  * api_msg.c: Remove some compiler warnings : parameter "pcb" was never
-    referenced.
-
-  2007-03-04 Frédéric Bernon
-  * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from
-    Dmitry Potapov).
-    The api_msg struct stay on the stack (not moved to netconn struct).
-
-  2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov)
-  * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if
-    SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available)
-    Also fixed cast warning in pbuf_alloc()
-
-  2007-03-04 Simon Goldschmidt
-  * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt
-    existing pbuf chain when enqueuing multiple pbufs to a pending ARP request
-
-  2007-03-03 Frédéric Bernon
-  * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;"
-    It is static, and never used in udp.c except udp_init().
-
-  2007-03-02 Simon Goldschmidt
-  * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from
-    tcpip_thread() to tcpip_init(). This way, raw API connections can be
-    initialized before tcpip_thread is running (e.g. before OS is started)
-
-  2007-03-02 Frédéric Bernon
-  * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call
-    interval.
-
-  2007-02-28 Kieran Mansley 
-  * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved
-    outside the region of the pbuf by pbuf_header()
-
-  2007-02-28 Kieran Mansley 
-  * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero
-    when supplied timeout is also non-zero 
-
-(STABLE-1.2.0)
-
-  2006-12-05 Leon Woestenberg
-  * CHANGELOG: Mention STABLE-1.2.0 release.
-
-  ++ New features:
-
-  2006-12-01 Christiaan Simons
-  * mem.h, opt.h: Added MEM_LIBC_MALLOC option.
-    Note this is a workaround. Currently I have no other options left.
-
-  2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour)
-  * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define
-    to include/lwip/opt.h.
-  * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL.
-    Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h.
-  * opt.h: Add above new options.
-
-  2006-08-18 Christiaan Simons
-  * tcp_{in,out}.c: added SNMP counters.
-  * ipv4/ip.c: added SNMP counters.
-  * ipv4/ip_frag.c: added SNMP counters.
-
-  2006-08-08 Christiaan Simons
-  * etharp.{c,h}: added etharp_find_addr() to read
-    (stable) ethernet/IP address pair from ARP table
-
-  2006-07-14 Christiaan Simons
-  * mib_structs.c: added
-  * include/lwip/snmp_structs.h: added
-  * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct
-
-  2006-07-06 Christiaan Simons
-  * snmp/asn1_{enc,dec}.c added
-  * snmp/mib2.c added
-  * snmp/msg_{in,out}.c added
-  * include/lwip/snmp_asn1.h added
-  * include/lwip/snmp_msg.h added
-  * doc/snmp_agent.txt added
-
-  2006-03-29 Christiaan Simons
-  * inet.c, inet.h: Added platform byteswap support.
-    Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and
-    optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros.
-
-  ++ Bug fixes:
-
-  2006-11-30 Christiaan Simons
-  * dhcp.c: Fixed false triggers of request_timeout.
-
-  2006-11-28 Christiaan Simons
-  * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags.
-
-  2006-10-11 Christiaan Simons
-  * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h:
-    Partially accepted patch #5449 for ANSI C compatibility / build fixes.
-  * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol
-    identifier from 170 to 136 (bug #17574).
-
-  2006-10-10 Christiaan Simons
-  * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice.
-
-  2006-08-17 Christiaan Simons
-  * udp.c: Fixed bug #17200, added check for broadcast
-    destinations for PCBs bound to a unicast address.
-
-  2006-08-07 Christiaan Simons
-  * api_msg.c: Flushing TCP output in do_close() (bug #15926).
-
-  2006-06-27 Christiaan Simons
-  * api_msg.c: Applied patch for cold case (bug #11135).
-    In accept_function() ensure newconn->callback is always initialized.
-
-  2006-06-15 Christiaan Simons
-  * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748),
-    facilitate printing of mem_size_t and u16_t statistics.
-
-  2006-06-14 Christiaan Simons
-  * api_msg.c: Applied patch #5146 to handle allocation failures
-    in accept() by Kevin Lawson.
-
-  2006-05-26 Christiaan Simons
-  * api_lib.c: Removed conn->sem creation and destruction 
-    from netconn_write() and added sys_sem_new to netconn_new_*.
-
-(STABLE-1_1_1)
-
-  2006-03-03  Christiaan Simons
-  * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap
-    access and added pbuf_alloc() return value checks.
-
-  2006-01-01  Leon Woestenberg <leon.woestenberg@gmx.net>
-  * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is
-    now handled by the checksum routine properly.
-
-  2006-02-27  Leon Woestenberg <leon.woestenberg@gmx.net>
-   * pbuf.c: Fix alignment; pbuf_init() would not work unless
-     pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.)
-
-  2005-12-20  Leon Woestenberg <leon.woestenberg@gmx.net>
-  * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch
-    submitted by Mitrani Hiroshi.
-
-  2005-12-15  Christiaan Simons
-  * inet.c: Disabled the added summing routine to preserve code space.
-
-  2005-12-14  Leon Woestenberg <leon.woestenberg@gmx.net>
-  * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson.
-    Added Curt McDowell's optimized checksumming routine for future
-    inclusion. Need to create test case for unaliged, aligned, odd,
-    even length combination of cases on various endianess machines.
-
-  2005-12-09  Christiaan Simons
-  * inet.c: Rewrote standard checksum routine in proper portable C.
-
-  2005-11-25  Christiaan Simons
-  * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only.
-  * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t,
-    u32_t, s32_t typedefs. This solves most debug word-length assumes.
-
-  2005-07-17 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * inet.c: Fixed unaligned 16-bit access in the standard checksum
-    routine by Peter Jolasson.
-  * slipif.c: Fixed implementation assumption of single-pbuf datagrams.
-
-  2005-02-04 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch.
-  * tcp_{out|in}.c: Applied patch fixing unaligned access.
-
-  2005-01-04 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement.
-
-  2005-01-03 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * udp.c: UDP pcb->recv() was called even when it was NULL.
-
-(STABLE-1_1_0)
-
-  2004-12-28 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * etharp.*: Disabled multiple packets on the ARP queue.
-    This clashes with TCP queueing.
-
-  2004-11-28 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * etharp.*: Fixed race condition from ARP request to ARP timeout.
-    Halved the ARP period, doubled the period counts.
-    ETHARP_MAX_PENDING now should be at least 2. This prevents
-    the counter from reaching 0 right away (which would allow
-    too little time for ARP responses to be received).
-
-  2004-11-25 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * dhcp.c: Decline messages were not multicast but unicast.
-  * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD.
-    Do not try hard to insert arbitrary packet's source address,
-    etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. 
-    etharp_query() now always DOES call ETHARP_TRY_HARD so that users
-    querying an address will see it appear in the cache (DHCP could
-    suffer from this when a server invalidly gave an in-use address.)
-  * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are
-    comparing network addresses (identifiers), not the network masks
-    themselves.
-  * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given
-    IP address actually belongs to the network of the given interface.
-
-  2004-11-24 Kieran Mansley <kjm25@cam.ac.uk>
-  * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state.
-
-(STABLE-1_1_0-RC1)
-
-  2004-10-16 Kieran Mansley <kjm25@cam.ac.uk>
-  * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately,
-    even if one is already pending, if the rcv_wnd is above a threshold
-    (currently TCP_WND/2). This avoids waiting for a timer to expire to send a
-    delayed ACK in order to open the window if the stack is only receiving data.
-
-  2004-09-12 Kieran Mansley <kjm25@cam.ac.uk>
-  * tcp*.*: Retransmit time-out handling improvement by Sam Jansen.
-
-  2004-08-20 Tony Mountifield <tony@softins.co.uk>
-  * etharp.c: Make sure the first pbuf queued on an ARP entry
-    is properly ref counted.
-
-  2004-07-27 Tony Mountifield <tony@softins.co.uk>
-  * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler
-    warnings about comparison.
-  * pbuf.c: Stopped compiler complaining of empty if statement
-    when LWIP_DEBUGF() empty.  Closed an unclosed comment.
-  * tcp.c: Stopped compiler complaining of empty if statement
-    when LWIP_DEBUGF() empty.
-  * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons().
-  * inet.c: Added a couple of casts to quiet the compiler.
-    No need to test isascii(c) before isdigit(c) or isxdigit(c).
-
-  2004-07-22 Tony Mountifield <tony@softins.co.uk>
-  * inet.c: Made data types consistent in inet_ntoa().
-    Added casts for return values of checksum routines, to pacify compiler.
-  * ip_frag.c, tcp_out.c, sockets.c, pbuf.c
-    Small corrections to some debugging statements, to pacify compiler.
-
-  2004-07-21 Tony Mountifield <tony@softins.co.uk>
-  * etharp.c: Removed spurious semicolon and added missing end-of-comment.
-  * ethernetif.c Updated low_level_output() to match prototype for
-    netif->linkoutput and changed low_level_input() similarly for consistency.
-  * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype
-    of raw_recv() in raw.h and so avoid compiler error.
-  * sockets.c: Added trivial (int) cast to keep compiler happier.
-  * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros.
-
-(STABLE-1_0_0)
-
-  ++ Changes:
-
-  2004-07-05 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure
-    your cc.h file defines this either 1 or 0. If non-defined,
-    defaults to 1.
-  * .c: Added <string.h> and <errno.h> includes where used.
-  * etharp.c: Made some array indices unsigned.
-
-  2004-06-27 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * netif.*: Added netif_set_up()/down().
-  * dhcp.c: Changes to restart program flow.
-
-  2004-05-07 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * etharp.c: In find_entry(), instead of a list traversal per candidate, do a
-    single-pass lookup for different candidates. Should exploit locality.
-
-  2004-04-29 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * tcp*.c: Cleaned up source comment documentation for Doxygen processing.
-  * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC.
-  * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by
-    the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option.
-
-  ++ Bug fixes:
-
-  2004-04-27 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution
-    suggested by Timmy Brolin. Fix for 32-bit processors that cannot access
-    non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix
-    is to prefix the 14-bit Ethernet headers with two padding bytes.
-
-  2004-04-23 Leon Woestenberg <leon.woestenberg@gmx.net>
-  * ip_addr.c: Fix in the ip_addr_isbroadcast() check.
-  * etharp.c: Fixed the case where the packet that initiates the ARP request
-    is not queued, and gets lost. Fixed the case where the packets destination
-    address is already known; we now always queue the packet and perform an ARP
-    request.
-
-(STABLE-0_7_0)
-
-  ++ Bug fixes:
-
-  * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition.
-  * Fixed TCP bug in dequeueing of FIN from out of order segment queue.
-  * Fixed two possible NULL references in rare cases.
-
-(STABLE-0_6_6)
-
-  ++ Bug fixes:
-
-  * Fixed DHCP which did not include the IP address in DECLINE messages.
-
-  ++ Changes:
-
-  * etharp.c has been hauled over a bit.
-
-(STABLE-0_6_5)
-
-  ++ Bug fixes:
-
-  * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic.
-  * Packets sent from ARP queue had invalid source hardware address.
-
-  ++ Changes:
-
-  * Pass-by ARP requests do now update the cache.
-
-  ++ New features:
-
-  * No longer dependent on ctype.h.
-  * New socket options.
-  * Raw IP pcb support.
-
-(STABLE-0_6_4)
-
-  ++ Bug fixes:
-
-  * Some debug formatters and casts fixed.
-  * Numereous fixes in PPP.
-
-  ++ Changes:
-
-  * DEBUGF now is LWIP_DEBUGF
-  * pbuf_dechain() has been re-enabled.
-  * Mentioned the changed use of CVS branches in README.
-
-(STABLE-0_6_3)
-
-  ++ Bug fixes:
-
-  * Fixed pool pbuf memory leak in pbuf_alloc().
-    Occured if not enough PBUF_POOL pbufs for a packet pbuf chain.
-    Reported by Savin Zlobec.
-
-  * PBUF_POOL chains had their tot_len field not set for non-first
-    pbufs. Fixed in pbuf_alloc().
-
-  ++ New features:
-
-  * Added PPP stack contributed by Marc Boucher
-
-  ++ Changes:
-
-  * Now drops short packets for ICMP/UDP/TCP protocols. More robust.
-
-  * ARP queueuing now queues the latest packet instead of the first.
-    This is the RFC recommended behaviour, but can be overridden in
-    lwipopts.h.
-
-(0.6.2)
-
-  ++ Bugfixes:
-
-  * TCP has been fixed to deal with the new use of the pbuf->ref
-    counter.
-
-  * DHCP dhcp_inform() crash bug fixed.
-
-  ++ Changes:
-
-  * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed
-    pbuf_refresh(). This has sped up pbuf pool operations considerably.
-    Implemented by David Haas.
-
-(0.6.1)
-
-  ++ New features:
-
-  * The packet buffer implementation has been enhanced to support
-    zero-copy and copy-on-demand for packet buffers which have their
-    payloads in application-managed memory.
-    Implemented by David Haas.
-
-    Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy
-    if an outgoing packet can be directly sent on the link, or perform
-    a copy-on-demand when necessary.
-
-    The application can safely assume the packet is sent, and the RAM
-    is available to the application directly after calling udp_send()
-    or similar function.
-
-  ++ Bugfixes:
-
-  * ARP_QUEUEING should now correctly work for all cases, including
-    PBUF_REF.
-    Implemented by Leon Woestenberg.
-
-  ++ Changes:
-
-  * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer
-    to a '0.0.0.0' IP address.
-
-  * The packet buffer implementation is changed. The pbuf->ref counter
-    meaning has changed, and several pbuf functions have been
-    adapted accordingly.
-
-  * netif drivers have to be changed to set the hardware address length field
-    that must be initialized correctly by the driver (hint: 6 for Ethernet MAC).
-    See the contrib/ports/c16x cs8900 driver as a driver example.
-
-  * netif's have a dhcp field that must be initialized to NULL by the driver.
-    See the contrib/ports/c16x cs8900 driver as a driver example.
-
-(0.5.x) This file has been unmaintained up to 0.6.1. All changes are
-  logged in CVS but have not been explained here.
-
-(0.5.3) Changes since version 0.5.2
-
-  ++ Bugfixes:
-
-  * memp_malloc(MEMP_API_MSG) could fail with multiple application
-    threads because it wasn't protected by semaphores.
-
-  ++ Other changes:
-
-  * struct ip_addr now packed.
-
-  * The name of the time variable in arp.c has been changed to ctime
-    to avoid conflicts with the time() function.
-
-(0.5.2) Changes since version 0.5.1
-
-  ++ New features:
-
-  * A new TCP function, tcp_tmr(), now handles both TCP timers.
-
-  ++ Bugfixes:
-
-  * A bug in tcp_parseopt() could cause the stack to hang because of a
-    malformed TCP option.
-
-  * The address of new connections in the accept() function in the BSD
-    socket library was not handled correctly.
-
-  * pbuf_dechain() did not update the ->tot_len field of the tail.
-
-  * Aborted TCP connections were not handled correctly in all
-    situations.
-
-  ++ Other changes:
-
-  * All protocol header structs are now packed.
-
-  * The ->len field in the tcp_seg structure now counts the actual
-    amount of data, and does not add one for SYN and FIN segments.
-
-(0.5.1) Changes since version 0.5.0
-
-  ++ New features:
-
-  * Possible to run as a user process under Linux.
-
-  * Preliminary support for cross platform packed structs.
-
-  * ARP timer now implemented.
-
-  ++ Bugfixes:
-
-  * TCP output queue length was badly initialized when opening
-    connections.
-
-  * TCP delayed ACKs were not sent correctly.
-
-  * Explicit initialization of BSS segment variables.
-
-  * read() in BSD socket library could drop data.
-
-  * Problems with memory alignment.
-
-  * Situations when all TCP buffers were used could lead to
-    starvation.
-
-  * TCP MSS option wasn't parsed correctly.
-
-  * Problems with UDP checksum calculation.
-
-  * IP multicast address tests had endianess problems.
-
-  * ARP requests had wrong destination hardware address.
-
-  ++ Other changes:
-
-  * struct eth_addr changed from u16_t[3] array to u8_t[6].
-
-  * A ->linkoutput() member was added to struct netif.
-
-  * TCP and UDP ->dest_* struct members where changed to ->remote_*.
-
-  * ntoh* macros are now null definitions for big endian CPUs.
-
-(0.5.0) Changes since version 0.4.2
-
-  ++ New features:
-
-  * Redesigned operating system emulation layer to make porting easier.
-
-  * Better control over TCP output buffers.
-
-  * Documenation added.
-
-  ++ Bugfixes:
-
-  * Locking issues in buffer management.
-
-  * Bugfixes in the sequential API.
-
-  * IP forwarding could cause memory leakage. This has been fixed.
-
-  ++ Other changes:
-
-  * Directory structure somewhat changed; the core/ tree has been
-    collapsed.
-
-(0.4.2) Changes since version 0.4.1
-
-  ++ New features:
-
-  * Experimental ARP implementation added.
-
-  * Skeleton Ethernet driver added.
-
-  * Experimental BSD socket API library added.
-
-  ++ Bugfixes:
-
-  * In very intense situations, memory leakage could occur. This has
-    been fixed.
-
-  ++ Other changes:
-
-  * Variables named "data" and "code" have been renamed in order to
-    avoid name conflicts in certain compilers.
-
-  * Variable++ have in appliciable cases been translated to ++variable
-    since some compilers generate better code in the latter case.
-
-(0.4.1) Changes since version 0.4
-
-  ++ New features:
-
-  * TCP: Connection attempts time out earlier than data
-    transmissions. Nagle algorithm implemented. Push flag set on the
-    last segment in a burst.
-
-  * UDP: experimental support for UDP-Lite extensions.
-
-  ++ Bugfixes:
-
-  * TCP: out of order segments were in some cases handled incorrectly,
-    and this has now been fixed. Delayed acknowledgements was broken
-    in 0.4, has now been fixed. Binding to an address that is in use
-    now results in an error. Reset connections sometimes hung an
-    application; this has been fixed.
-
-  * Checksum calculation sometimes failed for chained pbufs with odd
-    lengths. This has been fixed.
-
-  * API: a lot of bug fixes in the API. The UDP API has been improved
-    and tested. Error reporting and handling has been
-    improved. Logical flaws and race conditions for incoming TCP
-    connections has been found and removed.
-
-  * Memory manager: alignment issues. Reallocating memory sometimes
-    failed, this has been fixed.
-
-  * Generic library: bcopy was flawed and has been fixed.
-
-  ++ Other changes:
-
-  * API: all datatypes has been changed from generic ones such as
-    ints, to specified ones such as u16_t. Functions that return
-    errors now have the correct type (err_t).
-
-  * General: A lot of code cleaned up and debugging code removed. Many
-    portability issues have been fixed.
-
-  * The license was changed; the advertising clause was removed.
-
-  * C64 port added.
-
-  * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri
-    Kosunen, Mikael Caleres, and Frits Wilmink for reporting and
-    fixing bugs!
-
-(0.4) Changes since version 0.3.1
-
-  * Memory management has been radically changed; instead of
-    allocating memory from a shared heap, memory for objects that are
-    rapidly allocated and deallocated is now kept in pools. Allocation
-    and deallocation from those memory pools is very fast. The shared
-    heap is still present but is used less frequently.
-
-  * The memory, memory pool, and packet buffer subsystems now support
-    4-, 2-, or 1-byte alignment.
-
-  * "Out of memory" situations are handled in a more robust way.
-
-  * Stack usage has been reduced.
-
-  * Easier configuration of lwIP parameters such as memory usage,
-    TTLs, statistics gathering, etc. All configuration parameters are
-    now kept in a single header file "lwipopts.h".
-
-  * The directory structure has been changed slightly so that all
-    architecture specific files are kept under the src/arch
-    hierarchy.
-
-  * Error propagation has been improved, both in the protocol modules
-    and in the API.
-
-  * The code for the RTXC architecture has been implemented, tested
-    and put to use.
-
-  * Bugs have been found and corrected in the TCP, UDP, IP, API, and
-    the Internet checksum modules.
-
-  * Bugs related to porting between a 32-bit and a 16-bit architecture
-    have been found and corrected.
-
-  * The license has been changed slightly to conform more with the
-    original BSD license, including the advertisement clause.
-
-(0.3.1) Changes since version 0.3
-
-  * Fix of a fatal bug in the buffer management. Pbufs with allocated
-    RAM never returned the RAM when the pbuf was deallocated.
-
-  * TCP congestion control, window updates and retransmissions did not
-    work correctly. This has now been fixed.
-
-  * Bugfixes in the API.
-
-(0.3) Changes since version 0.2
-
-  * New and improved directory structure. All include files are now
-    kept in a dedicated include/ directory.
-
-  * The API now has proper error handling. A new function,
-    netconn_err(), now returns an error code for the connection in
-    case of errors.
-
-  * Improvements in the memory management subsystem. The system now
-    keeps a pointer to the lowest free memory block. A new function,
-    mem_malloc2() tries to allocate memory once, and if it fails tries
-    to free some memory and retry the allocation.
-
-  * Much testing has been done with limited memory
-    configurations. lwIP now does a better job when overloaded.
-
-  * Some bugfixes and improvements to the buffer (pbuf) subsystem.
-
-  * Many bugfixes in the TCP code:
-
-    - Fixed a bug in tcp_close().
-
-    - The TCP receive window was incorrectly closed when out of
-      sequence segments was received. This has been fixed.
-
-    - Connections are now timed-out of the FIN-WAIT-2 state.
-
-    - The initial congestion window could in some cases be too
-      large. This has been fixed.
-
-    - The retransmission queue could in some cases be screwed up. This
-      has been fixed.
-
-    - TCP RST flag now handled correctly.
-
-    - Out of sequence data was in some cases never delivered to the
-      application. This has been fixed.
-
-    - Retransmitted segments now contain the correct acknowledgment
-      number and advertised window.
-
-    - TCP retransmission timeout backoffs are not correctly computed
-      (ala BSD). After a number of retransmissions, TCP now gives up
-      the connection.
-
-  * TCP connections now are kept on three lists, one for active
-    connections, one for listening connections, and one for
-    connections that are in TIME-WAIT. This greatly speeds up the fast
-    timeout processing for sending delayed ACKs.
-
-  * TCP now provides proper feedback to the application when a
-    connection has been successfully set up.
-
-  * More comments have been added to the code. The code has also been
-    somewhat cleaned up.
-
-(0.2) Initial public release.

+ 0 - 33
components/net/lwip/COPYING

@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2001, 2002 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 lwIP TCP/IP stack.
- * 
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-

+ 0 - 4
components/net/lwip/FILES

@@ -1,4 +0,0 @@
-src/      - The source code for the lwIP TCP/IP stack.
-doc/      - The documentation for lwIP.
-
-See also the FILES file in each subdirectory.

+ 0 - 89
components/net/lwip/README

@@ -1,89 +0,0 @@
-INTRODUCTION
-
-lwIP is a small independent implementation of the TCP/IP protocol
-suite that has been developed by Adam Dunkels at the Computer and
-Networks Architectures (CNA) lab at the Swedish Institute of Computer
-Science (SICS).
-
-The focus of the lwIP TCP/IP implementation is to reduce the RAM usage
-while still having a full scale TCP. This making lwIP suitable for use
-in embedded systems with tens of kilobytes of free RAM and room for
-around 40 kilobytes of code ROM.
-
-FEATURES
-
-  * IP (Internet Protocol) including packet forwarding over multiple network
-    interfaces
-  * ICMP (Internet Control Message Protocol) for network maintenance and debugging
-  * IGMP (Internet Group Management Protocol) for multicast traffic management
-  * UDP (User Datagram Protocol) including experimental UDP-lite extensions
-  * TCP (Transmission Control Protocol) with congestion control, RTT estimation
-    and fast recovery/fast retransmit
-  * Specialized raw/native API for enhanced performance
-  * Optional Berkeley-like socket API
-  * DNS (Domain names resolver)
-  * SNMP (Simple Network Management Protocol)
-  * DHCP (Dynamic Host Configuration Protocol)
-  * AUTOIP (for IPv4, conform with RFC 3927)
-  * PPP (Point-to-Point Protocol)
-  * ARP (Address Resolution Protocol) for Ethernet
-
-LICENSE
-
-lwIP is freely available under a BSD license.
-
-DEVELOPMENT
-
-lwIP has grown into an excellent TCP/IP stack for embedded devices,
-and developers using the stack often submit bug fixes, improvements,
-and additions to the stack to further increase its usefulness.
-
-Development of lwIP is hosted on Savannah, a central point for
-software development, maintenance and distribution. Everyone can
-help improve lwIP by use of Savannah's interface, CVS and the
-mailing list. A core team of developers will commit changes to the
-CVS source tree.
-
-The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and
-contributions (such as platform ports) are in the 'contrib' module.
-
-See doc/savannah.txt for details on CVS server access for users and
-developers.
-
-Last night's CVS tar ball can be downloaded from:
-  http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING]
-
-The current CVS trees are web-browsable:
-  http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/
-  http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/
-
-Submit patches and bugs via the lwIP project page:
-  http://savannah.nongnu.org/projects/lwip/
-
-
-DOCUMENTATION
-
-The original out-dated homepage of lwIP and Adam Dunkels' papers on
-lwIP are at the official lwIP home page:
-  http://www.sics.se/~adam/lwip/
-
-Self documentation of the source code is regularly extracted from the
-current CVS sources and is available from this web page:
-  http://www.nongnu.org/lwip/
-
-There is now a constantly growin wiki about lwIP at
-  http://lwip.wikia.com/wiki/LwIP_Wiki
-
-Also, there are mailing lists you can subscribe at
-  http://savannah.nongnu.org/mail/?group=lwip
-plus searchable archives:
-  http://lists.nongnu.org/archive/html/lwip-users/
-  http://lists.nongnu.org/archive/html/lwip-devel/
-
-Reading Adam's papers, the files in docs/, browsing the source code
-documentation and browsing the mailing list archives is a good way to
-become familiar with the design of lwIP.
-
-Adam Dunkels <adam@sics.se>
-Leon Woestenberg <leon.woestenberg@gmx.net>
-

+ 0 - 87
components/net/lwip/SConscript

@@ -1,87 +0,0 @@
-Import('RTT_ROOT')
-from building import *
-
-src = Split("""
-src/api/api_lib.c
-src/api/api_msg.c
-src/api/err.c
-src/api/netbuf.c
-src/api/netdb.c
-src/api/netifapi.c
-src/api/sockets.c
-src/api/tcpip.c
-src/arch/sys_arch.c
-src/core/def.c
-src/core/dhcp.c
-src/core/dns.c
-src/core/init.c
-src/core/memp.c
-src/core/netif.c
-src/core/pbuf.c
-src/core/raw.c
-src/core/stats.c
-src/core/sys.c
-src/core/tcp.c
-src/core/tcp_in.c
-src/core/tcp_out.c
-src/core/timers.c
-src/core/udp.c
-src/core/ipv4/autoip.c
-src/core/ipv4/icmp.c
-src/core/ipv4/igmp.c
-src/core/ipv4/inet.c
-src/core/ipv4/inet_chksum.c
-src/core/ipv4/ip.c
-src/core/ipv4/ip_addr.c
-src/core/ipv4/ip_frag.c
-src/netif/etharp.c
-src/netif/ethernetif.c
-src/netif/slipif.c
-""")
-
-snmp_src = Split("""
-src/core/snmp/asn1_dec.c
-src/core/snmp/asn1_enc.c
-src/core/snmp/mib2.c
-src/core/snmp/mib_structs.c
-src/core/snmp/msg_in.c
-src/core/snmp/msg_out.c
-""")
-
-ppp_src = Split("""
-src/netif/ppp/auth.c
-src/netif/ppp/chap.c
-src/netif/ppp/chpms.c
-src/netif/ppp/fsm.c
-src/netif/ppp/ipcp.c
-src/netif/ppp/lcp.c
-src/netif/ppp/magic.c
-src/netif/ppp/md5.c
-src/netif/ppp/pap.c
-src/netif/ppp/ppp.c
-src/netif/ppp/ppp_oe.c
-src/netif/ppp/randm.c
-src/netif/ppp/vj.c
-""")
-
-# The set of source files associated with this SConscript file.
-path = [GetCurrentDir() + '/src',
-    GetCurrentDir() + '/src/include',
-    GetCurrentDir() + '/src/include/ipv4',
-    GetCurrentDir() + '/src/arch/include',
-    GetCurrentDir() + '/src/include/netif']
-
-if GetDepend(['RT_LWIP_SNMP']):
-    src += snmp_src
-
-if GetDepend(['RT_LWIP_PPP']):
-    src += ppp_src
-    path += [GetCurrentDir() + '/src/netif/ppp']
-
-# For testing apps
-if GetDepend(['RT_USING_NETUTILS']):
-    src += Glob('./apps/*.c')
-
-group = DefineGroup('LwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP140'], CPPPATH = path)
-
-Return('group')

+ 0 - 144
components/net/lwip/UPGRADING

@@ -1,144 +0,0 @@
-This file lists major changes between release versions that require
-ports or applications to be changed. Use it to update a port or an
-application written for an older version of lwIP to correctly work
-with newer versions.
-
-
-(CVS HEAD)
-
-  * [Enter new changes just after this line - do not remove this line]
-
-  ++ Application changes:
-
-  * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
-    compatibility to old applications, but will be removed in the future).
-
-  * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()
-
-  +++ Raw API:
-    * Changed the semantics of tcp_close() (since it was rather a
-      shutdown before): Now the application does *NOT* get any calls to the recv
-      callback (aside from NULL/closed) after calling tcp_close()
-
-    * When calling tcp_abort() from a raw API TCP callback function,
-      make sure you return ERR_ABRT to prevent accessing unallocated memory.
-      (ERR_ABRT now means the applicaiton has called tcp_abort!)
-
-  +++ Netconn API:
-    * Changed netconn_receive() and netconn_accept() to return
-      err_t, not a pointer to new data/netconn.
-
-  +++ Socket API:
-    * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
-      now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.
-
-    * Added a minimal version of posix fctl() to have a
-      standardised way to set O_NONBLOCK for nonblocking sockets.
-
-  +++ all APIs:
-    * correctly implemented SO(F)_REUSEADDR
-
-  ++ Port changes
-
-  +++ new files:
-
-    * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:
-
-    * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
-      the actual application programmer's API
-  
-    * Separated timer implementation from sys.h/.c, moved to timers.h/.c;
-      Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
-      still want to use your own timer implementation for NO_SYS==0 (as before).
-
-  +++ sys layer:
-
-    * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
-      sys_sem_t;
-
-    * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
-
-    * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
-      binary semaphores instead of mutexes - as before)
-
-  +++ new options:
-
-     * Don't waste memory when chaining segments, added option TCP_OVERSIZE to
-       prevent creating many small pbufs when calling tcp_write with many small
-       blocks of data. Instead, pbufs are allocated larger than needed and the
-       space is used for later calls to tcp_write.
-
-     * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
-       in tcp_write/udp_send.
-
-    * Added an additional option LWIP_ETHERNET to support ethernet without ARP
-      (necessary for pure PPPoE)
-
-    * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
-      be used to place these pools into user-defined memory by using external
-      declaration.
-
-    * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT
-
-  +++ new pools:
-
-     * Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
-       so MEMP_NUM_NETDB has to be set accordingly.
-
-     * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
-       MEMP_NUM_LOCALHOSTLIST has to be set accordingly.
-
-     * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
-       to be set accordingly.
-
-     * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
-       has to be set accordingly
-
-  * Integrated loopif into netif.c - loopif does not have to be created by the
-    port any more, just define LWIP_HAVE_LOOPIF to 1.
-
-  * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
-    in cc.h, e.g. used by igmp)
-
-  * Added printf-formatter X8_F to printf u8_t as hex
-
-  * The heap now may be moved to user-defined memory by defining
-    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
-
-  * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
-    with user-allocated structs instead of calling mem_malloc
-
-  * Added const char* name to mem- and memp-stats for easier debugging.
-
-  * Calculate the TCP/UDP checksum while copying to only fetch data once:
-    Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
-
-  * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
-    more than one pcb.
-
-  * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
-    off any more, if this is set to 0, only one packet (the most recent one) is
-    queued (like demanded by RFC 1122).
-
-  
-  ++ Major bugfixes/improvements
-
-  * Implemented tcp_shutdown() to only shut down one end of a connection
-  * Implemented shutdown() at socket- and netconn-level
-  * Added errorset support to select() + improved select speed overhead
-  * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
-  * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
-  * Use macros defined in ip_addr.h to work with IP addresses
-  * Implemented many nonblocking socket/netconn functions
-  * Fixed ARP input processing: only add a new entry if a request was directed as us
-  * mem_realloc() to mem_trim() to prevent confusion with realloc()
-  * Some improvements for AutoIP (don't route/forward link-local addresses, don't break
-    existing connections when assigning a routable address)
-  * Correctly handle remote side overrunning our rcv_wnd in ooseq case
-  * Removed packing from ip_addr_t, the packed version is now only used in protocol headers
-  * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
-  * Added support for static ARP table entries
-
-(STABLE-1.3.2)
-
-  * initial version of this file

+ 0 - 7
components/net/lwip/apps/SConscript

@@ -1,7 +0,0 @@
-Import('RTT_ROOT')
-from building import *
-
-src   = Glob('*.c')
-group = DefineGroup('netutils', src, depend = ['RT_USING_NETUTILS'])
-
-Return('group')

+ 0 - 216
components/net/lwip/apps/chargen.c

@@ -1,216 +0,0 @@
-#include <rtthread.h>
-
-#include "lwip/sockets.h"
-#define MAX_SERV                 32         /* Maximum number of chargen services. Don't need too many */
-#define CHARGEN_THREAD_NAME      "chargen"
-#if RT_THREAD_PRIORITY_MAX == 32
-#define CHARGEN_PRIORITY         20        /* Really low priority */
-#else
-#define CHARGEN_PRIORITY         200       /* Really low priority */
-#endif
-#define CHARGEN_THREAD_STACKSIZE 1024
-struct charcb
-{
-    struct charcb *next;
-    int socket;
-    struct sockaddr_in cliaddr;
-    socklen_t clilen;
-    char nextchar;
-};
-
-static struct charcb *charcb_list = 0;
-static int do_read(struct charcb *p_charcb);
-static void close_chargen(struct charcb *p_charcb);
-
-/**************************************************************
- * void chargen_thread(void *arg)
- *
- * chargen task. This server will wait for connections on well
- * known TCP port number: 19. For every connection, the server will
- * write as much data as possible to the tcp port.
- **************************************************************/
-static void chargen_thread(void *arg)
-{
-    int listenfd;
-    struct sockaddr_in chargen_saddr;
-    fd_set readset;
-    fd_set writeset;
-    int i, maxfdp1;
-    struct charcb *p_charcb;
-
-    /* First acquire our socket for listening for connections */
-    listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
-    LWIP_ASSERT("chargen_thread(): Socket create failed.", listenfd >= 0);
-    memset(&chargen_saddr, 0, sizeof(chargen_saddr));
-    chargen_saddr.sin_family = AF_INET;
-    chargen_saddr.sin_addr.s_addr = htonl(INADDR_ANY);
-    chargen_saddr.sin_port = htons(19);     // Chargen server port
-
-    if (lwip_bind(listenfd, (struct sockaddr *) &chargen_saddr, sizeof(chargen_saddr)) == -1)
-        LWIP_ASSERT("chargen_thread(): Socket bind failed.", 0);
-
-    /* Put socket into listening mode */
-    if (lwip_listen(listenfd, MAX_SERV) == -1)
-        LWIP_ASSERT("chargen_thread(): Listen failed.", 0);
-
-    /* Wait forever for network input: This could be connections or data */
-    for (;;)
-    {
-        maxfdp1 = listenfd+1;
-
-        /* Determine what sockets need to be in readset */
-        FD_ZERO(&readset);
-        FD_ZERO(&writeset);
-        FD_SET(listenfd, &readset);
-        for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next)
-        {
-            if (maxfdp1 < p_charcb->socket + 1)
-                maxfdp1 = p_charcb->socket + 1;
-            FD_SET(p_charcb->socket, &readset);
-            FD_SET(p_charcb->socket, &writeset);
-        }
-
-        /* Wait for data or a new connection */
-        i = lwip_select(maxfdp1, &readset, &writeset, 0, 0);
-
-        if (i == 0) continue;
-
-        /* At least one descriptor is ready */
-        if (FD_ISSET(listenfd, &readset))
-        {
-            /* We have a new connection request!!! */
-            /* Lets create a new control block */
-            p_charcb = (struct charcb *)rt_calloc(1, sizeof(struct charcb));
-            if (p_charcb)
-            {
-                p_charcb->socket = lwip_accept(listenfd,
-                                        (struct sockaddr *) &p_charcb->cliaddr,
-                                        &p_charcb->clilen);
-                if (p_charcb->socket < 0)
-                    rt_free(p_charcb);
-                else
-                {
-                    /* Keep this tecb in our list */
-                    p_charcb->next = charcb_list;
-                    charcb_list = p_charcb;
-                    p_charcb->nextchar = 0x21;
-                }
-            }
-			else
-			{
-                /* No memory to accept connection. Just accept and then close */
-                int sock;
-                struct sockaddr cliaddr;
-                socklen_t clilen;
-
-                sock = lwip_accept(listenfd, &cliaddr, &clilen);
-                if (sock >= 0)
-                    lwip_close(sock);
-            }
-        }
-        /* Go through list of connected clients and process data */
-        for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next)
-        {
-            if (FD_ISSET(p_charcb->socket, &readset))
-            {
-                /* This socket is ready for reading. This could be because someone typed
-                 * some characters or it could be because the socket is now closed. Try reading
-                 * some data to see. */
-                if (do_read(p_charcb) < 0)
-                    break;
-            }
-            if (FD_ISSET(p_charcb->socket, &writeset))
-            {
-                char line[80];
-                char setchar = p_charcb->nextchar;
-
-                for( i = 0; i < 59; i++)
-                {
-                    line[i] = setchar;
-                    if (++setchar == 0x7f)
-                        setchar = 0x21;
-                }
-                line[i] = 0;
-                strcat(line, "\n\r");
-                if (lwip_write(p_charcb->socket, line, strlen(line)) < 0)
-                {
-                    close_chargen(p_charcb);
-                    break;
-                }
-                if (++p_charcb->nextchar == 0x7f)
-                    p_charcb->nextchar = 0x21;
-            }
-        }
-    }
-}
-
-/**************************************************************
- * void close_chargen(struct charcb *p_charcb)
- *
- * Close the socket and remove this charcb from the list.
- **************************************************************/
-static void close_chargen(struct charcb *p_charcb)
-{
-    struct charcb *p_search_charcb;
-
-    /* Either an error or tcp connection closed on other
-     * end. Close here */
-    lwip_close(p_charcb->socket);
-
-    /* Free charcb */
-    if (charcb_list == p_charcb)
-        charcb_list = p_charcb->next;
-    else
-        for (p_search_charcb = charcb_list; p_search_charcb; p_search_charcb = p_search_charcb->next)
-        {
-            if (p_search_charcb->next == p_charcb)
-            {
-                p_search_charcb->next = p_charcb->next;
-                break;
-            }
-        }
-
-    rt_free(p_charcb);
-}
-
-/**************************************************************
- * void do_read(struct charcb *p_charcb)
- *
- * Socket definitely is ready for reading. Read a buffer from the socket and
- * discard the data.  If no data is read, then the socket is closed and the
- * charcb is removed from the list and freed.
- **************************************************************/
-static int do_read(struct charcb *p_charcb)
-{
-    char buffer[80];
-    int readcount;
-
-    /* Read some data */
-    readcount = lwip_read(p_charcb->socket, &buffer, 80);
-    if (readcount <= 0)
-    {
-        close_chargen(p_charcb);
-        return -1;
-    }
-    return 0;
-}
-
-void chargen_init(void)
-{
-	rt_thread_t chargen;
-
-	chargen = rt_thread_create(CHARGEN_THREAD_NAME,
-		chargen_thread, RT_NULL,
-		CHARGEN_THREAD_STACKSIZE,
-		CHARGEN_PRIORITY, 5);
-	if (chargen != RT_NULL) rt_thread_startup(chargen);
-}
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-void chargen()
-{
-	chargen_init();
-}
-FINSH_FUNCTION_EXPORT(chargen, start chargen server);
-#endif

+ 0 - 985
components/net/lwip/apps/ftpd.c

@@ -1,985 +0,0 @@
-#include <string.h>
-#include <stdlib.h>
-
-#include <rtthread.h>
-#include <dfs_posix.h>
-#include <lwip/sockets.h>
-#include <time.h>
-
-#define FTP_PORT			21
-#define FTP_SRV_ROOT		"/"
-#define FTP_MAX_CONNECTION	2
-#define FTP_USER			"rtt"
-#define FTP_PASSWORD		"demo"
-#define FTP_WELCOME_MSG		"220 welcome on RT-Thread FTP server.\r\n"
-#define FTP_BUFFER_SIZE		1024
-
-#define INET_ADDRSTRLEN 16
-
-
-struct ftp_session
-{
-	rt_bool_t is_anonymous;
-
-	int sockfd;
-	struct sockaddr_in remote;
-	struct sockaddr_in server;
-
-	char serveraddr[INET_ADDRSTRLEN];
-
-	/* pasv data */
-	int  pasv_listen_sockfd;
-	char pasv_active;
-	int  pasv_sockfd;
-
-	unsigned short pasv_port;
-	size_t offset;
-
-	/* current directory */
-	char currentdir[256];
-
-	struct ftp_session* next;
-};
-static struct ftp_session* session_list = NULL;
-
-int ftp_process_request(struct ftp_session* session, char * buf);
-int ftp_get_filesize(char *filename);
-
-struct ftp_session* ftp_new_session()
-{
-	struct ftp_session* session;
-
-	session = (struct ftp_session*)rt_malloc(sizeof(struct ftp_session));
-	rt_memset((void *)session, 0, sizeof(struct ftp_session));
-
-	session->next = session_list;
-	session_list = session;
-
-	return session;
-}
-
-void ftp_close_session(struct ftp_session* session)
-{
-	struct ftp_session* list;
-
-	if (session_list == session)
-	{
-		session_list = session_list->next;
-		session->next = NULL;
-	}
-	else
-	{
-		list = session_list;
-		while (list->next != session) list = list->next;
-
-		list->next = session->next;
-		session->next = NULL;
-	}
-
-	rt_free(session);
-}
-
-static int open_data_connection(struct ftp_session* session)
-{
-	socklen_t len = sizeof(struct sockaddr);
-	struct sockaddr_in sin;
-#if 0
-	/* Previous PORT command from client */
-	if (ctrl->data_address[0]) {
-		ctrl->data_sd = socket(AF_INET, SOCK_STREAM, 0);
-		if (-1 == ctrl->data_sd) {
-			printf("Failed creating data socket");
-			return -1;
-		}
-
-		memset(&sin, 0, sizeof(sin));
-		sin.sin_family = AF_INET;
-		sin.sin_port = htons(ctrl->data_port);
-		inet_aton(ctrl->data_address, &(sin.sin_addr));
-
-		if (connect(ctrl->data_sd, (struct sockaddr *)&sin, len) == -1) {
-			printf("Failed connecting data socket to client");
-			close(ctrl->data_sd);
-			ctrl->data_sd = -1;
-
-			return -1;
-		}
-
-		DBG("Connected successfully to client's previously requested address:PORT %s:%d", ctrl->data_address, ctrl->data_port);
-		return 0;
-	}
-#endif
-	/* Previous PASV command, accept connect from client */
-	if (session->pasv_listen_sockfd > 0) {
-		char client_ip[100];
-
-		session->pasv_sockfd = accept(session->pasv_listen_sockfd, (struct sockaddr *)&sin, &len);
-		if (-1 == session->pasv_sockfd) {
-			printf("Failed accepting connection from client");
-			return -1;
-		}
-
-		len = sizeof(struct sockaddr);
-		if (-1 == getpeername(session->pasv_sockfd, (struct sockaddr *)&sin, &len)) {
-			printf("Cannot determine client address");
-			closesocket(session->pasv_sockfd);
-			session->pasv_sockfd = -1;
-			return -1;
-		}
-
-		printf("Client PASV data connection from %s\n", inet_ntoa(sin.sin_addr));
-	}
-
-	return 0;
-}
-
-static void close_data_connection(struct ftp_session* session)
-{
-	/* PASV server listening socket */
-	if (session->pasv_listen_sockfd > 0) {
-		closesocket(session->pasv_listen_sockfd);
-		session->pasv_listen_sockfd = -1;
-	}
-
-	/* PASV client socket */
-	if (session->pasv_sockfd > 0) {
-		closesocket(session->pasv_sockfd);
-		session->pasv_sockfd = -1;
-	}
-#if 0
-	/* PORT */
-	if (ctrl->data_address[0]) {
-		ctrl->data_address[0] = 0;
-		ctrl->data_port = 0;
-	}
-#endif
-}
-
-
-int ftp_get_filesize(char * filename)
-{
-	int pos;
-	int end;
-	int fd;
-
-	fd = open(filename, O_RDONLY, 0);
-	if (fd < 0) return -1;
-
-	pos = lseek(fd, 0, SEEK_CUR);
-	end = lseek(fd, 0, SEEK_END);
-	lseek (fd, pos, SEEK_SET);
-	close(fd);
-
-	return end;
-}
-
-rt_bool_t is_absolute_path(char* path)
-{
-#ifdef _WIN32
-	if (path[0] == '\\' ||
-		(path[1] == ':' && path[2] == '\\'))
-		return RT_TRUE;
-#else
-	if (path[0] == '/') return RT_TRUE;
-#endif
-
-	return RT_FALSE;
-}
-
-int build_full_path(struct ftp_session* session, char* path, char* new_path, size_t size)
-{
-	if (is_absolute_path(path) == RT_TRUE)
-		strcpy(new_path, path);
-	else
-	{
-		rt_sprintf(new_path, "%s/%s", session->currentdir, path);
-	}
-
-	return 0;
-}
-
-void ftpd_thread_entry(void* parameter)
-{
-	int numbytes;
-	int sockfd, maxfdp1;
-	struct sockaddr_in local;
-	fd_set readfds, tmpfds;
-	struct ftp_session* session;
-	rt_uint32_t addr_len = sizeof(struct sockaddr);
-	char * buffer = (char *) rt_malloc(FTP_BUFFER_SIZE);
-
-	local.sin_port=htons(FTP_PORT);
-	local.sin_family=PF_INET;
-	local.sin_addr.s_addr=INADDR_ANY;
-
-	FD_ZERO(&readfds);
-	FD_ZERO(&tmpfds);
-
-	sockfd=socket(AF_INET, SOCK_STREAM, 0);
-	if(sockfd < 0)
-	{
-		rt_kprintf("create socket failed\n");
-		return ;
-	}
-
-	bind(sockfd, (struct sockaddr *)&local, addr_len);
-	listen(sockfd, FTP_MAX_CONNECTION);
-
-	FD_SET(sockfd, &readfds);
-	for(;;)
-	{
-	    /* get maximum fd */
-	    maxfdp1 = sockfd + 1;
-        session = session_list;
-	    while (session != RT_NULL)
-	    {
-	        if (maxfdp1 < session->sockfd + 1)
-                maxfdp1 = session->sockfd + 1;
-
-            FD_SET(session->sockfd, &readfds);
-            session = session->next;
-	    }
-
-		tmpfds=readfds;
-		if (select(maxfdp1, &tmpfds, 0, 0, 0) == 0) continue;
-
-		if(FD_ISSET(sockfd, &tmpfds))
-		{
-			int com_socket;
-			struct sockaddr_in remote;
-
-			com_socket = accept(sockfd, (struct sockaddr*)&remote, &addr_len);
-			if(com_socket == -1)
-			{
-				rt_kprintf("Error on accept()\nContinuing...\n");
-				continue;
-			}
-			else
-			{
-				rt_kprintf("Got connection from %s\n", inet_ntoa(remote.sin_addr));
-				send(com_socket, FTP_WELCOME_MSG, strlen(FTP_WELCOME_MSG), 0);
-				FD_SET(com_socket, &readfds);
-
-				/* new session */
-				session = ftp_new_session();
-				if (session != NULL)
-				{
-					if (-1 == getsockname(com_socket, (struct sockaddr *)&session->server, &addr_len)) {
-						printf("Cannot determine our address, need it if client should connect to us\n");
-					}
-					ipaddr_ntoa_r(&(session->server.sin_addr), session->serveraddr, sizeof(session->serveraddr));
-					strcpy(session->currentdir, FTP_SRV_ROOT);
-					session->sockfd = com_socket;
-					session->remote = remote;
-				}
-			}
-		}
-
-		{
-			struct ftp_session* next;
-
-			session = session_list;
-			while (session != NULL)
-			{
-				next = session->next;
-				if (FD_ISSET(session->sockfd, &tmpfds))
-				{
-					numbytes=recv(session->sockfd, buffer, FTP_BUFFER_SIZE, 0);
-					if(numbytes==0 || numbytes==-1)
-					{
-						rt_kprintf("Client %s disconnected\n", inet_ntoa(session->remote.sin_addr));
-						FD_CLR(session->sockfd, &readfds);
-						closesocket(session->sockfd);
-						session->sockfd = -1;
-						ftp_close_session(session);
-					}
-					else
-					{
-						buffer[numbytes]=0;
-						if(ftp_process_request(session, buffer)==-1)
-						{
-							rt_kprintf("Client %s disconnected\r\n", inet_ntoa(session->remote.sin_addr));
-							closesocket(session->sockfd);
-							session->sockfd = -1;
-							ftp_close_session(session);
-						}
-					}
-				}
-
-				session = next;
-			}
-		}
-	}
-
-	// rt_free(buffer);
-}
-
-int do_list(char* directory, int sockfd)
-{
-	DIR* dirp;
-	struct dirent* entry;
-	char line_buffer[256], line_length;
-#ifdef _WIN32
-	struct _stat s;
-#else
-	struct stat s;
-#endif
-
-	dirp = opendir(directory);
-	if (dirp == NULL)
-	{
-		line_length = rt_sprintf(line_buffer, "500 Internal Error\r\n");
-		send(sockfd, line_buffer, line_length, 0);
-		return -1;
-	}
-
-	while (1)
-	{
-		entry = readdir(dirp);
-		if (entry == NULL) break;
-
-		rt_sprintf(line_buffer, "%s/%s", directory, entry->d_name);
-#ifdef _WIN32
-		if (_stat(line_buffer, &s) ==0)
-#else
-		if (stat(line_buffer, &s) == 0)
-#endif
-		{
-			if (s.st_mode & S_IFDIR)
-				line_length = rt_sprintf(line_buffer, "drw-r--r-- 1 admin admin %d Jan 1 2000 %s\r\n", 0, entry->d_name);
-			else
-				line_length = rt_sprintf(line_buffer, "-rw-r--r-- 1 admin admin %d Jan 1 2000 %s\r\n", s.st_size, entry->d_name);
-
-			send(sockfd, line_buffer, line_length, 0);
-		}
-		else
-		{
-			rt_kprintf("Get directory entry error\n");
-			break;
-		}
-	}
-
-	closedir(dirp);
-	return 0;
-}
-
-int do_simple_list(char* directory, int sockfd)
-{
-	DIR* dirp;
-	struct dirent* entry;
-	char line_buffer[256], line_length;
-
-	dirp = opendir(directory);
-	if (dirp == NULL)
-	{
-		line_length = rt_sprintf(line_buffer, "500 Internal Error\r\n");
-		send(sockfd, line_buffer, line_length, 0);
-		return -1;
-	}
-
-	while (1)
-	{
-		entry = readdir(dirp);
-		if (entry == NULL) break;
-
-		line_length = rt_sprintf(line_buffer, "%s\r\n", entry->d_name);
-		send(sockfd, line_buffer, line_length, 0);
-	}
-
-	closedir(dirp);
-	return 0;
-}
-
-int str_begin_with(char* src, char* match)
-{
-	while (*match)
-	{
-		/* check source */
-		if (*src == 0) return -1;
-
-		if (*match != *src) return -1;
-		match ++; src ++;
-	}
-
-	return 0;
-}
-
-int ftp_process_request(struct ftp_session* session, char *buf)
-{
-	int  fd;
-	struct timeval tv;
-	fd_set readfds;
-	char filename[256];
-	int  numbytes;
-	char *sbuf;
-	char *parameter_ptr, *ptr;
-	rt_uint32_t addr_len = sizeof(struct sockaddr_in);
-	struct sockaddr_in local, pasvremote;
-
-	sbuf =(char *)rt_malloc(FTP_BUFFER_SIZE);
-
-	tv.tv_sec=3, tv.tv_usec=0;
-	local.sin_family=PF_INET;
-	local.sin_addr.s_addr=INADDR_ANY;
-
-	/* remove \r\n */
-	ptr = buf;
-	while (*ptr)
-	{
-		if (*ptr == '\r' || *ptr == '\n') *ptr = 0;
-		ptr ++;
-	}
-
-	/* get request parameter */
-	parameter_ptr = strchr(buf, ' '); if (parameter_ptr != NULL) parameter_ptr ++;
-
-	// debug:
-	rt_kprintf("%s requested: \"%s\"\n", inet_ntoa(session->remote.sin_addr), buf);
-
-	//
-	//-----------------------
-	if(str_begin_with(buf, "USER")==0)
-	{
-		rt_kprintf("%s sent login \"%s\"\n", inet_ntoa(session->remote.sin_addr), parameter_ptr);
-		// login correct
-		if(strcmp(parameter_ptr, "anonymous") == 0)
-		{
-			session->is_anonymous = RT_TRUE;
-			rt_sprintf(sbuf, "331 Anonymous login OK send e-mail address for password.\r\n", parameter_ptr);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-		else if (strcmp(parameter_ptr, FTP_USER) == 0)
-		{
-			session->is_anonymous = RT_FALSE;
-			rt_sprintf(sbuf, "331 Password required for %s\r\n", parameter_ptr);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-		else
-		{
-			// incorrect login
-			rt_sprintf(sbuf, "530 Login incorrect. Bye.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			rt_free(sbuf);
-			return -1;
-		}
-		return 0;
-	}
-	else if(str_begin_with(buf, "PASS")==0)
-	{
-		rt_kprintf("%s sent password \"%s\"\n", inet_ntoa(session->remote.sin_addr), parameter_ptr);
-		if (strcmp(parameter_ptr, FTP_PASSWORD)==0 ||
-			session->is_anonymous == RT_TRUE)
-		{
-			// password correct
-			rt_sprintf(sbuf, "230 User logged in.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			rt_free(sbuf);
-			return 0;
-		}
-
-		// incorrect password
-		rt_sprintf(sbuf, "530 Login or Password incorrect. Bye!\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		rt_free(sbuf);
-		return -1;
-	}
-	else if(str_begin_with(buf, "LIST")==0  )
-	{
-		memset(sbuf,0,FTP_BUFFER_SIZE);
-		open_data_connection(session);
-		rt_sprintf(sbuf, "150 Opening Binary mode connection for file list.\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		do_list(session->currentdir, session->pasv_sockfd);
-		close_data_connection(session);
-		session->pasv_active = 0;
-		rt_sprintf(sbuf, "226 Transfert Complete.\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "NLST")==0 )
-	{
-		memset(sbuf, 0, FTP_BUFFER_SIZE);
-		rt_sprintf(sbuf, "150 Opening Binary mode connection for file list.\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		open_data_connection(session);
-		do_simple_list(session->currentdir, session->pasv_sockfd);
-		close_data_connection(session);
-		session->pasv_active = 0;
-		rt_sprintf(sbuf, "226 Transfert Complete.\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "PWD")==0 || str_begin_with(buf, "XPWD")==0)
-	{
-		rt_sprintf(sbuf, "257 \"%s\" is current directory.\r\n", session->currentdir);
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "TYPE")==0)
-	{
-		// Ignore it
-		if(strcmp(parameter_ptr, "I")==0)
-		{
-			rt_sprintf(sbuf, "200 Type set to binary.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-		else
-		{
-			rt_sprintf(sbuf, "200 Type set to ascii.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-	}
-	else if(str_begin_with(buf, "PASV")==0)
-	{
-		int dig1, dig2;
-		//int sockfd;
-		int optval=1;
-		int port;
-		struct sockaddr_in data;
-		socklen_t len = sizeof(struct sockaddr);
-		char *msg, *p;
-
-		if (session->pasv_sockfd > 0) {
-			closesocket(session->pasv_sockfd);
-			session->pasv_sockfd = -1;
-		}
-
-		if (session->pasv_listen_sockfd > 0)
-			closesocket(session->pasv_listen_sockfd);
-
-		session->pasv_port = 10000;
-		session->pasv_active = 1;
-		local.sin_port=htons(session->pasv_port);
-		local.sin_addr.s_addr=INADDR_ANY;
-
-		dig1 = (int)(session->pasv_port/256);
-		dig2 = session->pasv_port % 256;
-
-		FD_ZERO(&readfds);
-		if((session->pasv_listen_sockfd=socket(PF_INET, SOCK_STREAM, 0))==-1)
-		{
-			rt_sprintf(sbuf, "425 Can't open data connection0.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			goto err1;
-		}
-		if(setsockopt(session->pasv_listen_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))==-1)
-		{
-			rt_sprintf(sbuf, "425 Can't open data connection1.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			goto err1;
-		}
-		if(bind(session->pasv_listen_sockfd, (struct sockaddr *)&local, addr_len)==-1)
-		{
-			rt_sprintf(sbuf, "425 Can't open data connection2.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			goto err1;
-		}
-		if(listen(session->pasv_listen_sockfd, 1)==-1)
-		{
-			rt_sprintf(sbuf, "425 Can't open data connection3.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			goto err1;
-		}
-		if (-1 == getsockname(session->pasv_listen_sockfd, (struct sockaddr *)&data, &len)) {
-			rt_kprintf("Cannot determine our address, need it if client should connect to us\n");
-			goto err1;
-		}
-
-		port = ntohs(data.sin_port);
-		rt_kprintf("Port %d\n", port);
-
-		/* Convert server IP address and port to comma separated list */
-		msg = strdup(session->serveraddr);
-		if (!msg) {
-			rt_sprintf(sbuf, "426 Internal server error.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			goto err1;
-		}
-		p = msg;
-		while ((p = strchr(p, '.')))
-			*p++ = ',';
-	
-		rt_kprintf("Listening %d seconds @ port %d\n", tv.tv_sec, session->pasv_port);
-		rt_sprintf(sbuf, "227 Entering passive mode (%s,%d,%d)\r\n", msg, port / 256, port % 256);
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		rt_free(sbuf);
-		rt_free(msg);
-		return 0;
-	#if 0
-		FD_SET(sockfd, &readfds);
-		select(0, &readfds, 0, 0, &tv);
-		if(FD_ISSET(sockfd, &readfds))
-		{
-			if((session->pasv_sockfd = accept(sockfd, (struct sockaddr*)&pasvremote, &addr_len))==-1)
-			{
-				rt_sprintf(sbuf, "425 Can't open data connection4.\r\n");
-				send(session->sockfd, sbuf, strlen(sbuf), 0);
-				goto err1;
-			}
-			else
-			{
-				rt_kprintf("Got Data(PASV) connection from %s\n", inet_ntoa(pasvremote.sin_addr));
-				session->pasv_active = 1;
-				closesocket(sockfd);
-			}
-		}
-		else
-		{
-err1:
-			closesocket(session->pasv_sockfd);
-			session->pasv_active = 0;
-			rt_free(sbuf);
-			return 0;
-		}
-	#endif
-err1:
-		close_data_connection(session);
-		session->pasv_active = 0;
-		rt_free(sbuf);
-		rt_free(msg);
-		return 0;
-
-	}
-	else if (str_begin_with(buf, "RETR")==0)
-	{
-		int file_size;
-
-		open_data_connection(session);
-
-		strcpy(filename, buf + 5);
-
-		build_full_path(session, parameter_ptr, filename, 256);
-		file_size = ftp_get_filesize(filename);
-		if (file_size == -1)
-		{
-			rt_sprintf(sbuf, "550 \"%s\" : not a regular file\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			session->offset=0;
-			close_data_connection(session);
-			rt_free(sbuf);
-			return 0;
-		}
-
-		fd = open(filename, O_RDONLY, 0);
-		if (fd < 0)
-		{
-			close_data_connection(session);
-			rt_free(sbuf);
-			return 0;
-		}
-
-		if(session->offset>0 && session->offset < file_size)
-		{
-			lseek(fd, session->offset, SEEK_SET);
-			rt_sprintf(sbuf, "150 Opening binary mode data connection for partial \"%s\" (%d/%d bytes).\r\n",
-				filename, file_size - session->offset, file_size);
-		}
-		else
-		{
-			rt_sprintf(sbuf, "150 Opening binary mode data connection for \"%s\" (%d bytes).\r\n", filename, file_size);
-		}
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		while((numbytes = read(fd, sbuf, FTP_BUFFER_SIZE))>0)
-		{
-			send(session->pasv_sockfd, sbuf, numbytes, 0);
-		}
-		rt_sprintf(sbuf, "226 Finished.\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		close(fd);
-		close_data_connection(session);
-	}
-	else if (str_begin_with(buf, "STOR")==0)
-	{
-		open_data_connection(session);
-		if(session->is_anonymous == RT_TRUE)
-		{
-			rt_sprintf(sbuf, "550 Permission denied.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			close_data_connection(session);
-			rt_free(sbuf);
-			return 0;
-		}
-
-		build_full_path(session, parameter_ptr, filename, 256);
-
-		fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0);
-		if(fd < 0)
-		{
-			rt_sprintf(sbuf, "550 Cannot open \"%s\" for writing.\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			close_data_connection(session);
-			rt_free(sbuf);
-			return 0;
-		}
-		rt_sprintf(sbuf, "150 Opening binary mode data connection for \"%s\".\r\n", filename);
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		FD_ZERO(&readfds);
-		FD_SET(session->pasv_sockfd, &readfds);
-		rt_kprintf("Waiting %d seconds for data...\n", tv.tv_sec);
-		while(select(session->pasv_sockfd+1, &readfds, 0, 0, &tv)>0 )
-		{
-			if((numbytes=recv(session->pasv_sockfd, sbuf, FTP_BUFFER_SIZE, 0))>0)
-			{
-				write(fd, sbuf, numbytes);
-			}
-			else if(numbytes==0)
-			{
-				close(fd);
-				close_data_connection(session);
-				rt_sprintf(sbuf, "226 Finished.\r\n");
-				send(session->sockfd, sbuf, strlen(sbuf), 0);
-				break;
-			}
-			else if(numbytes==-1)
-			{
-				close(fd);
-				close_data_connection(session);
-				rt_free(sbuf);
-				return -1;
-			}
-		}
-		close_data_connection(session);
-	}
-	else if(str_begin_with(buf, "SIZE")==0)
-	{
-		int file_size;
-
-		build_full_path(session, parameter_ptr, filename, 256);
-
-		file_size = ftp_get_filesize(filename);
-		if( file_size == -1)
-		{
-			rt_sprintf(sbuf, "550 \"%s\" : not a regular file\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-		else
-		{
-			rt_sprintf(sbuf, "213 %d\r\n", file_size);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-	}
-	else if(str_begin_with(buf, "MDTM")==0)
-	{
-		rt_sprintf(sbuf, "550 \"/\" : not a regular file\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "SYST")==0)
-	{
-		rt_sprintf(sbuf, "215 %s\r\n", "RT-Thread RTOS");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "CWD")==0)
-	{
-		build_full_path(session, parameter_ptr, filename, 256);
-
-		rt_sprintf(sbuf, "250 Changed to directory \"%s\"\r\n", filename);
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		strcpy(session->currentdir, filename);
-		rt_kprintf("Changed to directory %s", filename);
-	}
-	else if(str_begin_with(buf, "CDUP")==0)
-	{
-		rt_sprintf(filename, "%s/%s", session->currentdir, "..");
-
-		rt_sprintf(sbuf, "250 Changed to directory \"%s\"\r\n", filename);
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		strcpy(session->currentdir, filename);
-		rt_kprintf("Changed to directory %s", filename);
-	}
-	else if(str_begin_with(buf, "PORT")==0)
-	{
-		int i;
-		int portcom[6];
-		char tmpip[100];
-
-		i=0;
-		portcom[i++]=atoi(strtok(parameter_ptr, ".,;()"));
-		for(;i<6;i++)
-			portcom[i]=atoi(strtok(0, ".,;()"));
-		rt_sprintf(tmpip, "%d.%d.%d.%d", portcom[0], portcom[1], portcom[2], portcom[3]);
-
-		FD_ZERO(&readfds);
-		if((session->pasv_sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1)
-		{
-			rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			closesocket(session->pasv_sockfd);
-			session->pasv_active = 0;
-			rt_free(sbuf);
-			return 0;
-		}
-		pasvremote.sin_addr.s_addr=inet_addr(tmpip);
-		pasvremote.sin_port=htons(portcom[4] * 256 + portcom[5]);
-		pasvremote.sin_family=PF_INET;
-		if(connect(session->pasv_sockfd, (struct sockaddr *)&pasvremote, addr_len)==-1)
-		{
-			// is it only local address?try using gloal ip addr
-			pasvremote.sin_addr=session->remote.sin_addr;
-			if(connect(session->pasv_sockfd, (struct sockaddr *)&pasvremote, addr_len)==-1)
-			{
-				rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
-				send(session->sockfd, sbuf, strlen(sbuf), 0);
-				closesocket(session->pasv_sockfd);
-				rt_free(sbuf);
-				return 0;
-			}
-		}
-		session->pasv_active=1;
-		session->pasv_port = portcom[4] * 256 + portcom[5];
-		rt_kprintf("Connected to Data(PORT) %s @ %d\n", tmpip, portcom[4] * 256 + portcom[5]);
-		rt_sprintf(sbuf, "200 Port Command Successful.\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "REST")==0)
-	{
-		if(atoi(parameter_ptr)>=0)
-		{
-			session->offset=atoi(parameter_ptr);
-			rt_sprintf(sbuf, "350 Send RETR or STOR to start transfert.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-	}
-	else if(str_begin_with(buf, "MKD")==0)
-	{
-		if (session->is_anonymous == RT_TRUE)
-		{
-			rt_sprintf(sbuf, "530 Permission denied.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			rt_free(sbuf);
-			return 0;
-		}
-
-		build_full_path(session, parameter_ptr, filename, 256);
-
-		if(mkdir(filename, 0) == -1)
-		{
-			rt_sprintf(sbuf, "550 File \"%s\" exists.\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-		else
-		{
-			rt_sprintf(sbuf, "257 directory \"%s\" successfully created.\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-	}
-	else if(str_begin_with(buf, "DELE")==0)
-	{
-		if (session->is_anonymous == RT_TRUE)
-		{
-			rt_sprintf(sbuf, "530 Permission denied.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			rt_free(sbuf);
-			return 0;
-		}
-
-		build_full_path(session, parameter_ptr, filename, 256);
-
-		if(unlink(filename)==0)
-			rt_sprintf(sbuf, "250 Successfully deleted file \"%s\".\r\n", filename);
-		else
-		{
-			rt_sprintf(sbuf, "550 Not such file or directory: %s.\r\n", filename);
-		}
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "RMD")==0)
-	{
-		if (session->is_anonymous == RT_TRUE)
-		{
-			rt_sprintf(sbuf, "530 Permission denied.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			rt_free(sbuf);
-			return 0;
-		}
-		build_full_path(session, parameter_ptr, filename, 256);
-
-		if(unlink(filename) == -1)
-		{
-			rt_sprintf(sbuf, "550 Directory \"%s\" doesn't exist.\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-		else
-		{
-			rt_sprintf(sbuf, "257 directory \"%s\" successfully deleted.\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-	}
-	else if(str_begin_with(buf, "RNFR")==0)
-	{
-		if (session->is_anonymous == RT_TRUE)
-		{
-			rt_sprintf(sbuf, "530 Permission denied.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			rt_free(sbuf);
-			return 0;
-		}
-		build_full_path(session, parameter_ptr, filename, 256);
-
-		rt_sprintf(sbuf, "350 Successfully rececive old file \"%s\".\r\n", filename);
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "RNTO")==0)
-	{
-		char new_filename[256];
-		if (session->is_anonymous == RT_TRUE)
-		{
-			rt_sprintf(sbuf, "530 Permission denied.\r\n");
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-			rt_free(sbuf);
-			return 0;
-		}
-		build_full_path(session, parameter_ptr, new_filename, 256);
-
-		if(rename(filename, new_filename) == -1)
-		{
-			rt_sprintf(sbuf, "553 rename file \"%s\" error.\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-		else
-		{
-			rt_sprintf(sbuf, "250 Successfully rename to new file \"%s\".\r\n", filename);
-			send(session->sockfd, sbuf, strlen(sbuf), 0);
-		}
-	}
-	else if((str_begin_with(buf, "NOOP")==0) || str_begin_with(buf, "noop")==0)
-	{
-		rt_sprintf(sbuf, "200 noop!\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	else if(str_begin_with(buf, "QUIT")==0)
-	{
-		rt_sprintf(sbuf, "221 Bye!\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-		rt_free(sbuf);
-		return -1;
-	}
-	else
-	{
-		rt_sprintf(sbuf, "502 Not Implemented.\r\n");
-		send(session->sockfd, sbuf, strlen(sbuf), 0);
-	}
-	rt_free(sbuf);
-	return 0;
-}
-
-void ftpd_start()
-{
-	rt_thread_t tid;
-
-	tid = rt_thread_create("ftpd",
-		ftpd_thread_entry, RT_NULL,
-		4096, 30, 5);
-	if (tid != RT_NULL) rt_thread_startup(tid);
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-FINSH_FUNCTION_EXPORT(ftpd_start, start ftp server);
-
-#ifdef FINSH_USING_MSH
-int cmd_ftpd_start(int argc, char** argv)
-{
-	ftpd_start();
-	return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_ftpd_start, __cmd_ftpd_start, start ftp server.);
-#endif
-
-#endif

+ 0 - 370
components/net/lwip/apps/netio.c

@@ -1,370 +0,0 @@
-/**
- * @file
- * MetIO Server
- *
- */
-
-/*
- * 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 lwIP TCP/IP stack.
- *
- */
-#include "lwip/opt.h"
-
-#if LWIP_TCP
-#include "lwip/tcp.h"
-
-/*
- * This implements a netio server.
- *  The client sends a command word (4 bytes) then a data length word (4 bytes).
- *  If the command is "receive", the server is to consume "data length" bytes into
- *   a circular buffer until the first byte is non-zero, then it is to consume
- *   another command/data pair.
- *  If the command is "send", the server is to send "data length" bytes from a circular
- *   buffer with the first byte being zero, until "some time" (6 seconds in the
- *   current netio126.zip download) has passed and then send one final buffer with
- *   the first byte being non-zero. Then it is to consume another command/data pair.
- */
-
-/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
-
-/* implementation options */
-#define NETIO_BUF_SIZE              (4 * 1024)
-#define NETIO_USE_STATIC_BUF        0
-
-/* NetIO server state definition */
-#define NETIO_STATE_WAIT_FOR_CMD    0
-#define NETIO_STATE_RECV_DATA       1
-#define NETIO_STATE_SEND_DATA       2
-#define NETIO_STATE_SEND_DATA_LAST  3
-#define NETIO_STATE_DONE            4
-
-struct netio_state {
-  u32_t  state;
-  u32_t  cmd;
-  u32_t  data_len;
-  u32_t  cntr;
-  u8_t * buf_ptr;
-  u32_t  buf_pos;
-  u32_t  first_byte;
-  u32_t  time_stamp;
-};
-
-/* NetIO command protocol definition */
-#define NETIO_CMD_QUIT              0
-#define NETIO_CMD_C2S               1
-#define NETIO_CMD_S2C               2
-#define NETIO_CMD_RES               3
-
-static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
-
-static void
-netio_close(void *arg, struct tcp_pcb *pcb)
-{
-  err_t err;
-
-  struct netio_state *ns = arg;
-  ns->state = NETIO_STATE_DONE;
-  tcp_recv(pcb, NULL);
-  err = tcp_close(pcb);
-
-  if (err != ERR_OK) {
-    /* closing failed, try again later */
-    tcp_recv(pcb, netio_recv);
-  } else {
-    /* closing succeeded */
-#if NETIO_USE_STATIC_BUF != 1
-    if(ns->buf_ptr != NULL){
-      mem_free(ns->buf_ptr);
-    }
-#endif
-    tcp_arg(pcb, NULL);
-    tcp_poll(pcb, NULL, 0);
-    tcp_sent(pcb, NULL);
-    if (arg != NULL) {
-      mem_free(arg);
-    }
-  }
-}
-
-static err_t
-netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
-{
-  struct netio_state *ns = arg;
-  u8_t * data_ptr;
-  u32_t data_cntr;
-  struct pbuf *q = p;
-  u16_t len;
-
-  if (p != NULL) {
-    tcp_recved(pcb, p->tot_len);
-  }
-
-  if (err == ERR_OK && q != NULL) {
-
-    while (q != NULL) {
-      data_cntr = q->len;
-      data_ptr = q->payload;
-      while (data_cntr--) {
-        if (ns->state == NETIO_STATE_DONE){
-          netio_close(ns, pcb);
-          break;
-        } else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) {
-          if (ns->cntr < 4) {
-            /* build up the CMD field */
-            ns->cmd <<= 8;
-            ns->cmd |= *data_ptr++;
-            ns->cntr++;
-          } else if (ns->cntr < 8) {
-            /* build up the DATA field */
-            ns->data_len <<= 8;
-            ns->data_len |= *data_ptr++;
-            ns->cntr++;
-
-            if (ns->cntr == 8) {
-              /* now we have full command and data words */
-              ns->cntr = 0;
-              ns->buf_pos = 0;
-              ns->buf_ptr[0] = 0;
-              if (ns->cmd == NETIO_CMD_C2S) {
-                ns->state = NETIO_STATE_RECV_DATA;
-              } else if (ns->cmd == NETIO_CMD_S2C) {
-                ns->state = NETIO_STATE_SEND_DATA;
-                /* start timer */
-                ns->time_stamp = rt_tick_get();
-                /* send first round of data */
-
-                len = tcp_sndbuf(pcb);
-                len = LWIP_MIN(len, ns->data_len - ns->cntr);
-                len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
-
-                do {
-                  err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
-                  if (err == ERR_MEM) {
-                    len /= 2;
-                  }
-                } while ((err == ERR_MEM) && (len > 1));
-
-                ns->buf_pos += len;
-                ns->cntr    += len;
-
-              } else {
-                /* unrecognized command, punt */
-                ns->cntr = 0;
-                ns->buf_pos = 0;
-                ns->buf_ptr[0] = 0;
-                netio_close(ns, pcb);
-                break;
-              }
-            }
-          } else {
-            /* in trouble... shouldn't be in this state! */
-          }
-
-        } else if (ns->state == NETIO_STATE_RECV_DATA) {
-
-          if(ns->cntr == 0){
-            /* save the first byte of this new round of data
-             * this will not match ns->buf_ptr[0] in the case that
-             *   NETIO_BUF_SIZE is less than ns->data_len.
-             */
-            ns->first_byte = *data_ptr;
-          }
-
-          ns->buf_ptr[ns->buf_pos++] = *data_ptr++;
-          ns->cntr++;
-
-          if (ns->buf_pos == NETIO_BUF_SIZE) {
-            /* circularize the buffer */
-            ns->buf_pos = 0;
-          }
-
-          if(ns->cntr == ns->data_len){
-            ns->cntr = 0;
-            if (ns->first_byte != 0) {
-              /* if this last round did not start with 0,
-               *  go look for another command */
-              ns->state = NETIO_STATE_WAIT_FOR_CMD;
-              ns->data_len = 0;
-              ns->cmd = 0;
-              /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
-            } else {
-              /* stay here and wait on more data */
-            }
-          }
-
-        } else if (ns->state == NETIO_STATE_SEND_DATA
-            || ns->state == NETIO_STATE_SEND_DATA_LAST) {
-          /* I don't think this should happen... */
-        } else {
-          /* done / quit */
-          netio_close(ns, pcb);
-          break;
-        } /* end of ns->state condition */
-      } /* end of while data still in this pbuf */
-
-      q = q->next;
-    }
-
-    pbuf_free(p);
-
-  } else {
-
-    /* error or closed by other side */
-    if (p != NULL) {
-      pbuf_free(p);
-    }
-
-    /* close the connection */
-    netio_close(ns, pcb);
-
-  }
-  return ERR_OK;
-
-}
-
-static err_t
-netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
-{
-  struct netio_state *ns = arg;
-  err_t err = ERR_OK;
-
-  if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) {
-    /* done with this round of sending */
-    ns->buf_pos = 0;
-    ns->cntr = 0;
-
-    /* check if timer expired */
-    if (rt_tick_get() - ns->time_stamp > 600) {
-      ns->buf_ptr[0] = 1;
-      ns->state = NETIO_STATE_SEND_DATA_LAST;
-    } else {
-      ns->buf_ptr[0] = 0;
-    }
-  }
-
-  if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){
-    len = tcp_sndbuf(pcb);
-    len = LWIP_MIN(len, ns->data_len - ns->cntr);
-    len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
-
-    if(ns->cntr < ns->data_len){
-      do {
-        err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
-        if (err == ERR_MEM) {
-          len /= 2;
-        }
-      } while ((err == ERR_MEM) && (len > 1));
-
-      ns->buf_pos += len;
-      if(ns->buf_pos >= NETIO_BUF_SIZE){
-        ns->buf_pos = 0;
-      }
-
-      ns->cntr += len;
-    }
-  }
-
-  if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){
-    /* we have buffered up all our data to send this last round, go look for a command */
-   ns->state = NETIO_STATE_WAIT_FOR_CMD;
-   ns->cntr  = 0;
-   /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
-  }
-
-  return ERR_OK;
-}
-
-static err_t
-netio_poll(void *arg, struct tcp_pcb *pcb)
-{
-  struct netio_state * ns = arg;
-  if(ns->state == NETIO_STATE_SEND_DATA){
-
-  } else if(ns->state == NETIO_STATE_DONE){
-    netio_close(ns, pcb);
-  }
-
-  return ERR_OK;
-
-}
-
-#if NETIO_USE_STATIC_BUF == 1
-static u8_t netio_buf[NETIO_BUF_SIZE];
-#endif
-
-static err_t
-netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
-{
-  struct netio_state * ns;
-
-  LWIP_UNUSED_ARG(err);
-
-  ns = mem_malloc(sizeof(struct netio_state));
-
-  if(ns == NULL){
-    return ERR_MEM;
-  }
-
-  ns->state = NETIO_STATE_WAIT_FOR_CMD;
-  ns->data_len = 0;
-  ns->cmd = 0;
-  ns->cntr = 0;
-  ns->buf_pos = 0;
-#if NETIO_USE_STATIC_BUF == 1
-  ns->buf_ptr = netio_buf;
-#else
-  ns->buf_ptr = mem_malloc(NETIO_BUF_SIZE);
-
-  if(ns->buf_ptr == NULL){
-    mem_free(ns);
-    return ERR_MEM;
-  }
-#endif
-
-  ns->buf_ptr[0] = 0;
-
-  tcp_arg(pcb, ns);
-  tcp_sent(pcb, netio_sent);
-  tcp_recv(pcb, netio_recv);
-  tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */
-  return ERR_OK;
-}
-
-void netio_init(void)
-{
-  struct tcp_pcb *pcb;
-
-  pcb = tcp_new();
-  tcp_bind(pcb, IP_ADDR_ANY, 18767);
-  pcb = tcp_listen(pcb);
-  tcp_accept(pcb, netio_accept);
-}
-
-#endif /* LWIP_TCP */
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-FINSH_FUNCTION_EXPORT(netio_init, netio server);
-#endif

+ 0 - 180
components/net/lwip/apps/ping.c

@@ -1,180 +0,0 @@
-/*
- * netutils: ping implementation
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/mem.h"
-#include "lwip/icmp.h"
-#include "lwip/netif.h"
-#include "lwip/sys.h"
-#include "lwip/sockets.h"
-#include "lwip/inet.h"
-#include "lwip/inet_chksum.h"
-#include "lwip/ip.h"
-
-/**
- * PING_DEBUG: Enable debugging for PING.
- */
-#ifndef PING_DEBUG
-#define PING_DEBUG     LWIP_DBG_ON
-#endif
-
-/** ping receive timeout - in milliseconds */
-#define PING_RCV_TIMEO 1000
-/** ping delay - in milliseconds */
-#define PING_DELAY     100
-
-/** ping identifier - must fit on a u16_t */
-#ifndef PING_ID
-#define PING_ID        0xAFAF
-#endif
-
-/** ping additional data size to include in the packet */
-#ifndef PING_DATA_SIZE
-#define PING_DATA_SIZE 32
-#endif
-
-/* ping variables */
-static u16_t ping_seq_num;
-struct _ip_addr
-{
-    rt_uint8_t addr0, addr1, addr2, addr3;
-};
-
-/** Prepare a echo ICMP request */
-static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
-{
-    size_t i;
-    size_t data_len = len - sizeof(struct icmp_echo_hdr);
-
-    ICMPH_TYPE_SET(iecho, ICMP_ECHO);
-    ICMPH_CODE_SET(iecho, 0);
-    iecho->chksum = 0;
-    iecho->id     = PING_ID;
-    iecho->seqno  = htons(++ping_seq_num);
-
-    /* fill the additional data buffer with some data */
-    for(i = 0; i < data_len; i++)
-    {
-        ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
-    }
-
-    iecho->chksum = inet_chksum(iecho, len);
-}
-
-/* Ping using the socket ip */
-static err_t ping_send(int s, struct ip_addr *addr, int size)
-{
-    int err;
-    struct icmp_echo_hdr *iecho;
-    struct sockaddr_in to;
-    size_t ping_size = sizeof(struct icmp_echo_hdr) + size;
-    LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
-
-    iecho = rt_malloc(ping_size);
-    if (iecho == RT_NULL)
-    {
-        return ERR_MEM;
-    }
-
-    ping_prepare_echo(iecho, (u16_t)ping_size);
-
-    to.sin_len = sizeof(to);
-    to.sin_family = AF_INET;
-    to.sin_addr.s_addr = addr->addr;
-
-    err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
-    rt_free(iecho);
-
-    return (err ? ERR_OK : ERR_VAL);
-}
-
-static void ping_recv(int s)
-{
-    char buf[64];
-    int fromlen, len;
-    struct sockaddr_in from;
-    struct ip_hdr *iphdr;
-    struct icmp_echo_hdr *iecho;
-    struct _ip_addr *addr;
-
-    while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0)
-    {
-        if (len >= (sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr)))
-        {
-            addr = (struct _ip_addr *)&(from.sin_addr);
-            rt_kprintf("ping: recv %d.%d.%d.%d\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
-
-            iphdr = (struct ip_hdr *)buf;
-            iecho = (struct icmp_echo_hdr *)(buf+(IPH_HL(iphdr) * 4));
-            if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)))
-            {
-                return;
-            }
-            else
-            {
-                rt_kprintf("ping: drop\n");
-            }
-        }
-    }
-
-    if (len <= 0)
-    {
-        rt_kprintf("ping: timeout\n");
-    }
-}
-
-rt_err_t ping(char* target, rt_uint32_t time, rt_size_t size)
-{
-    int s;
-    int timeout = PING_RCV_TIMEO;
-    struct ip_addr ping_target;
-    rt_uint32_t send_time;
-    struct _ip_addr
-    {
-        rt_uint8_t addr0, addr1, addr2, addr3;
-    } *addr;
-
-    send_time = 0;
-
-    if(size == 0)
-        size = PING_DATA_SIZE;
-
-    if (inet_aton(target, (struct in_addr*)&ping_target) == 0) return -RT_ERROR;
-    addr = (struct _ip_addr*)&ping_target;
-
-    if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
-    {
-        rt_kprintf("create socket failled\n");
-        return -RT_ERROR;
-    }
-
-    lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
-
-    while (1)
-    {
-        if (ping_send(s, &ping_target, size) == ERR_OK)
-        {
-            rt_kprintf("ping: send %d.%d.%d.%d\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
-            ping_recv(s);
-        }
-        else
-        {
-            rt_kprintf("ping: send %d.%d.%d.%d - error\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
-        }
-
-        send_time ++;
-        if (send_time >= time) break; /* send ping times reached, stop */
-
-        rt_thread_delay(PING_DELAY); /* take a delay */
-    }
-
-    lwip_close(s);
-
-    return RT_EOK;
-}
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-FINSH_FUNCTION_EXPORT(ping, ping network host);
-#endif

+ 0 - 213
components/net/lwip/apps/sntp.c

@@ -1,213 +0,0 @@
-/**
- * @file
- * SNTP client module
- *
- */
-
-/*
- * 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 lwIP TCP/IP stack.
- *
- */
-
-#include "lwip/sys.h"
-#include "lwip/sockets.h"
-
-#include <string.h>
-#include <time.h>
-
-/** This is an example of a "SNTP" client (with socket API).
- *
- * For a list of some public NTP servers, see this link :
- * http://support.ntp.org/bin/view/Servers/NTPPoolServers
- *
- */
-
-/**
- * SNTP_DEBUG: Enable debugging for SNTP.
- */
-#ifndef SNTP_DEBUG
-#define SNTP_DEBUG                  LWIP_DBG_ON
-#endif
-
-/** SNTP server port */
-#ifndef SNTP_PORT
-#define SNTP_PORT                   123
-#endif
-
-/** SNTP server address as IPv4 address in "u32_t" format */
-#ifndef SNTP_SERVER_ADDRESS
-#define SNTP_SERVER_ADDRESS         inet_addr("213.161.194.93") /* pool.ntp.org */
-#endif
-
-/** SNTP receive timeout - in milliseconds */
-#ifndef SNTP_RECV_TIMEOUT
-#define SNTP_RECV_TIMEOUT           3000
-#endif
-
-/** SNTP update delay - in milliseconds */
-#ifndef SNTP_UPDATE_DELAY
-#define SNTP_UPDATE_DELAY           60000
-#endif
-
-/** SNTP macro to change system time and/or the update the RTC clock */
-#ifndef SNTP_SYSTEM_TIME
-#define SNTP_SYSTEM_TIME(t)
-#endif
-
-/* SNTP protocol defines */
-#define SNTP_MAX_DATA_LEN           48
-#define SNTP_RCV_TIME_OFS           32
-#define SNTP_LI_NO_WARNING          0x00
-#define SNTP_VERSION               (4/* NTP Version 4*/<<3)
-#define SNTP_MODE_CLIENT            0x03
-#define SNTP_MODE_SERVER            0x04
-#define SNTP_MODE_BROADCAST         0x05
-#define SNTP_MODE_MASK              0x07
-
-/* number of seconds between 1900 and 1970 */
-#define DIFF_SEC_1900_1970         (2208988800)
-
-/**
- * SNTP processing
- */
-static void sntp_process( time_t t)
-{
-	/* change system time and/or the update the RTC clock */
-	SNTP_SYSTEM_TIME(t);
-
-	/* display local time from GMT time */
-	LWIP_DEBUGF( SNTP_DEBUG, ("sntp_process: %s", ctime(&t)));
-}
-
-/**
- * SNTP request
- */
-static void sntp_request()
-{
-	int                sock;
-	struct sockaddr_in local;
-	struct sockaddr_in to;
-	int                tolen;
-	int                size;
-	int                timeout;
-	u8_t               sntp_request [SNTP_MAX_DATA_LEN];
-	u8_t               sntp_response[SNTP_MAX_DATA_LEN];
-	u32_t              sntp_server_address;
-	u32_t              timestamp;
-	time_t             t;
-
-	/* initialize SNTP server address */
-	sntp_server_address = SNTP_SERVER_ADDRESS;
-
-	/* if we got a valid SNTP server address... */
-	if (sntp_server_address!=0)
-	{
-		/* create new socket */
-		sock = socket( AF_INET, SOCK_DGRAM, 0);
-		if (sock>=0)
-		{
-			/* prepare local address */
-			memset(&local, 0, sizeof(local));
-			local.sin_family      = AF_INET;
-			local.sin_port        = htons(INADDR_ANY);
-			local.sin_addr.s_addr = htonl(INADDR_ANY);
-
-			/* bind to local address */
-			if (bind( sock, (struct sockaddr *)&local, sizeof(local))==0)
-			{
-				/* set recv timeout */
-				timeout = SNTP_RECV_TIMEOUT;
-				setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
-
-				/* prepare SNTP request */
-				memset( sntp_request, 0, sizeof(sntp_request));
-				sntp_request[0] = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
-
-				/* prepare SNTP server address */
-				memset(&to, 0, sizeof(to));
-				to.sin_family      = AF_INET;
-				to.sin_port        = htons(SNTP_PORT);
-				to.sin_addr.s_addr = sntp_server_address;
-
-				/* send SNTP request to server */
-				if (sendto( sock, sntp_request, sizeof(sntp_request), 0, (struct sockaddr *)&to, sizeof(to))>=0)
-				{
-					/* receive SNTP server response */
-					tolen = sizeof(to);
-					size  = recvfrom( sock, sntp_response, sizeof(sntp_response), 0, (struct sockaddr *)&to, (socklen_t *)&tolen);
-
-					/* if the response size is good */
-					if (size == SNTP_MAX_DATA_LEN)
-					{
-						/* if this is a SNTP response... */
-						if (((sntp_response[0] & SNTP_MODE_MASK) == SNTP_MODE_SERVER) || ((sntp_response[0] & SNTP_MODE_MASK) == SNTP_MODE_BROADCAST))
-						{
-							/* extract GMT time from response */
-							SMEMCPY( &timestamp, (sntp_response+SNTP_RCV_TIME_OFS), sizeof(timestamp));
-							t = (ntohl(timestamp) - DIFF_SEC_1900_1970);
-
-							/* do time processing */
-							sntp_process(t);
-
-						}
-						else
-						{
-							LWIP_DEBUGF( SNTP_DEBUG, ("sntp_request: not response frame code\n"));
-						}
-					}
-					else
-					{
-						LWIP_DEBUGF( SNTP_DEBUG, ("sntp_request: not recvfrom==%i\n", errno));
-					}
-				}
-				else
-				{
-					LWIP_DEBUGF( SNTP_DEBUG, ("sntp_request: not sendto==%i\n", errno));
-				}
-			}
-			/* close the socket */
-			closesocket(sock);
-		}
-	}
-}
-
-/**
- * SNTP thread
- */
-static void
-sntp_thread(void *arg)
-{
-	LWIP_UNUSED_ARG(arg);
-	while(1)
-	{
-		sntp_request();
-		sys_msleep(SNTP_UPDATE_DELAY);
-	}
-}
-
-void sntp_init(void)
-{
-	sys_thread_new("sntp_thread", sntp_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
-}

+ 0 - 68
components/net/lwip/apps/tcpecho.c

@@ -1,68 +0,0 @@
-#include <lwip/api.h>
-
-#define TCP_ECHO_PORT   7
-
-void tcpecho_entry(void *parameter)
-{
-	struct netconn *conn, *newconn;
-	err_t err;
-
-	/* Create a new connection identifier. */
-	conn = netconn_new(NETCONN_TCP);
-
-	/* Bind connection to well known port number 7. */
-	netconn_bind(conn, NULL, TCP_ECHO_PORT);
-
-	/* Tell connection to go into listening mode. */
-	netconn_listen(conn);
-
-	while(1)
-	{
-		/* Grab new connection. */
-		err = netconn_accept(conn, &newconn);
-		/* Process the new connection. */
-		if(err == ERR_OK)
-		{
-			struct netbuf *buf;
-			void *data;
-			u16_t len;
-
-			while(netconn_recv(newconn, &buf) == ERR_OK)
-			{
-				do
-				{
-					netbuf_data(buf, &data, &len);
-					err = netconn_write(newconn, data, len, NETCONN_COPY);
-					if(err != ERR_OK){}
-				}
-				while(netbuf_next(buf) >= 0);
-				netbuf_delete(buf);
-			}
-			/* Close connection and discard connection identifier. */
-			netconn_delete(newconn);
-		}
-	}
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-static rt_thread_t echo_tid = RT_NULL;
-void tcpecho(rt_uint32_t startup)
-{
-    if (startup && echo_tid == RT_NULL)
-    {
-        echo_tid = rt_thread_create("echo",
-			tcpecho_entry, RT_NULL,
-            512, 30, 5);
-        if (echo_tid != RT_NULL)
-            rt_thread_startup(echo_tid);
-    }
-    else
-    {
-        if (echo_tid != RT_NULL)
-            rt_thread_delete(echo_tid); /* delete thread */
-        echo_tid = RT_NULL;
-    }
-}
-FINSH_FUNCTION_EXPORT(tcpecho, startup or stop TCP echo server);
-#endif

+ 0 - 206
components/net/lwip/apps/tftp.c

@@ -1,206 +0,0 @@
-#include <rtthread.h>
-#include <dfs_posix.h>
-#include <lwip/sockets.h>
-
-#include <finsh.h>
-
-#define TFTP_PORT	69
-/* opcode */
-#define TFTP_RRQ			1 	/* read request */
-#define TFTP_WRQ			2	/* write request */
-#define TFTP_DATA			3	/* data */
-#define TFTP_ACK			4	/* ACK */
-#define TFTP_ERROR			5	/* error */
-
-rt_uint8_t tftp_buffer[512 + 4];
-/* tftp client */
-void tftp_get(const char* host, const char* dir, const char* filename)
-{
-	int fd, sock_fd, sock_opt;
-	struct sockaddr_in tftp_addr, from_addr;
-	rt_uint32_t length;
-	socklen_t fromlen;
-
-	/* make local file name */
-	rt_snprintf((char*)tftp_buffer, sizeof(tftp_buffer),
-		"%s/%s", dir, filename);
-
-	/* open local file for write */
-	fd = open((char*)tftp_buffer, O_RDWR | O_CREAT, 0);
-	if (fd < 0)
-	{
-		rt_kprintf("can't open local filename\n");
-		return;
-	}
-
-	/* connect to tftp server */
-    inet_aton(host, (struct in_addr*)&(tftp_addr.sin_addr));
-    tftp_addr.sin_family = AF_INET;
-    tftp_addr.sin_port = htons(TFTP_PORT);
-    
-    sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
-    if (sock_fd < 0)
-	{
-	    close(fd);
-	    rt_kprintf("can't create a socket\n");
-	    return ;
-	}
-	
-	/* set socket option */
-	sock_opt = 5000; /* 5 seconds */
-	lwip_setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &sock_opt, sizeof(sock_opt));
-
-	/* make tftp request */
-	tftp_buffer[0] = 0;			/* opcode */
-	tftp_buffer[1] = TFTP_RRQ; 	/* RRQ */
-	length = rt_sprintf((char *)&tftp_buffer[2], "%s", filename) + 2;
-	tftp_buffer[length] = 0; length ++;
-	length += rt_sprintf((char*)&tftp_buffer[length], "%s", "octet");
-	tftp_buffer[length] = 0; length ++;
-
-	fromlen = sizeof(struct sockaddr_in);
-	
-	/* send request */	
-	lwip_sendto(sock_fd, tftp_buffer, length, 0, 
-		(struct sockaddr *)&tftp_addr, fromlen);
-	
-	do
-	{
-		length = lwip_recvfrom(sock_fd, tftp_buffer, sizeof(tftp_buffer), 0, 
-			(struct sockaddr *)&from_addr, &fromlen);
-		
-		if (length > 0)
-		{
-			write(fd, (char*)&tftp_buffer[4], length - 4);
-			rt_kprintf("#");
-
-			/* make ACK */			
-			tftp_buffer[0] = 0; tftp_buffer[1] = TFTP_ACK; /* opcode */
-			/* send ACK */
-			lwip_sendto(sock_fd, tftp_buffer, 4, 0, 
-				(struct sockaddr *)&from_addr, fromlen);
-		}
-	} while (length == 516);
-
-	if (length == 0) rt_kprintf("timeout\n");
-	else rt_kprintf("done\n");
-
-	close(fd);
-	lwip_close(sock_fd);
-}
-FINSH_FUNCTION_EXPORT(tftp_get, get file from tftp server);
-
-void tftp_put(const char* host, const char* dir, const char* filename)
-{
-	int fd, sock_fd, sock_opt;
-	struct sockaddr_in tftp_addr, from_addr;
-	rt_uint32_t length, block_number = 0;
-	socklen_t fromlen;
-
-	/* make local file name */
-	rt_snprintf((char*)tftp_buffer, sizeof(tftp_buffer),
-		"%s/%s", dir, filename);
-
-	/* open local file for write */
-	fd = open((char*)tftp_buffer, O_RDONLY, 0);
-	if (fd < 0)
-	{
-		rt_kprintf("can't open local filename\n");
-		return;
-	}
-
-	/* connect to tftp server */
-    inet_aton(host, (struct in_addr*)&(tftp_addr.sin_addr));
-    tftp_addr.sin_family = AF_INET;
-    tftp_addr.sin_port = htons(TFTP_PORT);
-
-    sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
-    if (sock_fd < 0)
-	{
-	    close(fd);
-	    rt_kprintf("can't create a socket\n");
-	    return ;
-	}
-
-	/* set socket option */
-	sock_opt = 5000; /* 5 seconds */
-	lwip_setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &sock_opt, sizeof(sock_opt));
-
-	/* make tftp request */
-	tftp_buffer[0] = 0;			/* opcode */
-	tftp_buffer[1] = TFTP_WRQ; 	/* WRQ */
-	length = rt_sprintf((char *)&tftp_buffer[2], "%s", filename) + 2;
-	tftp_buffer[length] = 0; length ++;
-	length += rt_sprintf((char*)&tftp_buffer[length], "%s", "octet");
-	tftp_buffer[length] = 0; length ++;
-
-	fromlen = sizeof(struct sockaddr_in);
-	
-	/* send request */	
-	lwip_sendto(sock_fd, tftp_buffer, length, 0, 
-		(struct sockaddr *)&tftp_addr, fromlen);
-
-	/* wait ACK 0 */	
-	length = lwip_recvfrom(sock_fd, tftp_buffer, sizeof(tftp_buffer), 0, 
-		(struct sockaddr *)&from_addr, &fromlen);
-	if (!(tftp_buffer[0] == 0 &&
-		tftp_buffer[1] == TFTP_ACK &&
-		tftp_buffer[2] == 0 &&
-		tftp_buffer[3] == 0))
-	{
-		rt_kprintf("tftp server error\n");
-		close(fd);
-		return;
-	}
-
-	block_number = 1;
-	
-	while (1)
-	{
-		length = read(fd, (char*)&tftp_buffer[4], 512);
-		if (length > 0)
-		{
-			/* make opcode and block number */
-			tftp_buffer[0] = 0; tftp_buffer[1] = TFTP_DATA;
-			tftp_buffer[2] = (block_number >> 8) & 0xff;
-			tftp_buffer[3] = block_number & 0xff;
-
-			lwip_sendto(sock_fd, tftp_buffer, length + 4, 0, 
-				(struct sockaddr *)&from_addr, fromlen);
-		}
-		else
-		{
-			rt_kprintf("done\n");
-			break; /* no data yet */
-		}
-
-		/* receive ack */
-		length = lwip_recvfrom(sock_fd, tftp_buffer, sizeof(tftp_buffer), 0, 
-			(struct sockaddr *)&from_addr, &fromlen);
-		if (length > 0)
-		{
-			if ((tftp_buffer[0] == 0 &&
-				tftp_buffer[1] == TFTP_ACK &&
-				tftp_buffer[2] == (block_number >> 8) & 0xff) &&
-				tftp_buffer[3] == (block_number & 0xff))
-			{
-				block_number ++;
-				rt_kprintf("#");
-			}
-			else 
-			{
-				rt_kprintf("server respondes with an error\n");
-				break;
-			}
-		}
-		else if (length == 0)
-		{
-			rt_kprintf("server timeout\n");
-			break;
-		}
-	}
-
-	close(fd);
-	lwip_close(sock_fd);
-}
-FINSH_FUNCTION_EXPORT(tftp_put, put file to tftp server);

+ 0 - 56
components/net/lwip/apps/udpecho.c

@@ -1,56 +0,0 @@
-#include <lwip/api.h>
-
-#define UDP_ECHO_PORT   7
-
-void udpecho_entry(void *parameter)
-{
-	struct netconn *conn;
-	struct netbuf *buf;
-	struct ip_addr *addr;
-	unsigned short port;
-
-	conn = netconn_new(NETCONN_UDP);
-	netconn_bind(conn, IP_ADDR_ANY, 7);
-
-	while(1)
-	{
-        /* received data to buffer */
-		netconn_recv(conn, &buf);
-
-		addr = netbuf_fromaddr(buf);
-		port = netbuf_fromport(buf);
-
-        /* send the data to buffer */
-		netconn_connect(conn, addr, port);
-
-		/* reset address, and send to client */
-		buf->addr = *IP_ADDR_ANY;
-		netconn_send(conn, buf);
-
-        /* release buffer */
-		netbuf_delete(buf);
-	}
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-static rt_thread_t echo_tid = RT_NULL;
-void udpecho(rt_uint32_t startup)
-{
-	if (startup && echo_tid == RT_NULL)
-	{
-		echo_tid = rt_thread_create("uecho",
-									udpecho_entry, RT_NULL,
-									512, 30, 5);
-		if (echo_tid != RT_NULL)
-			rt_thread_startup(echo_tid);
-	}
-	else
-	{
-		if (echo_tid != RT_NULL)
-			rt_thread_delete(echo_tid); /* delete thread */
-		echo_tid = RT_NULL;
-	}
-}
-FINSH_FUNCTION_EXPORT(udpecho, startup or stop UDP echo server);
-#endif

+ 0 - 6
components/net/lwip/doc/FILES

@@ -1,6 +0,0 @@
-savannah.txt   - How to obtain the current development source code.
-contrib.txt    - How to contribute to lwIP as a developer.
-rawapi.txt     - The documentation for the core API of lwIP.
-                 Also provides an overview about the other APIs and multithreading.
-snmp_agent.txt - The documentation for the lwIP SNMP agent.
-sys_arch.txt   - The documentation for a system abstraction layer of lwIP.

+ 0 - 63
components/net/lwip/doc/contrib.txt

@@ -1,63 +0,0 @@
-1 Introduction
-
-This document describes some guidelines for people participating
-in lwIP development.
-
-2 How to contribute to lwIP
-
-Here is a short list of suggestions to anybody working with lwIP and 
-trying to contribute bug reports, fixes, enhancements, platform ports etc.
-First of all as you may already know lwIP is a volunteer project so feedback
-to fixes or questions might often come late. Hopefully the bug and patch tracking 
-features of Savannah help us not lose users' input.
-
-2.1 Source code style:
-
-1. do not use tabs.
-2. indentation is two spaces per level (i.e. per tab).
-3. end debug messages with a trailing newline (\n).
-4. one space between keyword and opening bracket.
-5. no space between function and opening bracket.
-6. one space and no newline before opening curly braces of a block.
-7. closing curly brace on a single line.
-8. spaces surrounding assignment and comparisons.
-9. don't initialize static and/or global variables to zero, the compiler takes care of that.
-10. use current source code style as further reference.
-
-2.2 Source code documentation style:
-
-1. JavaDoc compliant and Doxygen compatible.
-2. Function documentation above functions in .c files, not .h files.
-   (This forces you to synchronize documentation and implementation.)
-3. Use current documentation style as further reference.
- 
-2.3 Bug reports and patches:
-
-1. Make sure you are reporting bugs or send patches against the latest
-   sources. (From the latest release and/or the current CVS sources.)
-2. If you think you found a bug make sure it's not already filed in the
-   bugtracker at Savannah.
-3. If you have a fix put the patch on Savannah. If it is a patch that affects
-   both core and arch specific stuff please separate them so that the core can
-   be applied separately while leaving the other patch 'open'. The prefered way
-   is to NOT touch archs you can't test and let maintainers take care of them.
-   This is a good way to see if they are used at all - the same goes for unix
-   netifs except tapif.
-4. Do not file a bug and post a fix to it to the patch area. Either a bug report
-   or a patch will be enough.
-   If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area.
-5. Trivial patches (compiler warning, indentation and spelling fixes or anything obvious which takes a line or two)
-   can go to the lwip-users list. This is still the fastest way of interaction and the list is not so crowded
-   as to allow for loss of fixes. Putting bugs on Savannah and subsequently closing them is too much an overhead
-   for reporting a compiler warning fix.
-6. Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other
-   trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you
-   change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than
-   if it's not to the point and long :) so the chances for it to be applied are greater. 
-
-2.4 Platform porters:
-
-1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and
-   you think it could benefit others[1] you might want discuss this on the mailing list. You
-   can also ask for CVS access to submit and maintain your port in the contrib CVS module.
-   

+ 0 - 505
components/net/lwip/doc/rawapi.txt

@@ -1,505 +0,0 @@
-Raw TCP/IP interface for lwIP
-
-Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons
-
-lwIP provides three Application Program's Interfaces (APIs) for programs
-to use for communication with the TCP/IP code:
-* low-level "core" / "callback" or "raw" API.
-* higher-level "sequential" API.
-* BSD-style socket API.
-
-The sequential API provides a way for ordinary, sequential, programs
-to use the lwIP stack. It is quite similar to the BSD socket API. The
-model of execution is based on the blocking open-read-write-close
-paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP
-code and the application program must reside in different execution
-contexts (threads).
-
-The socket API is a compatibility API for existing applications,
-currently it is built on top of the sequential API. It is meant to
-provide all functions needed to run socket API applications running
-on other platforms (e.g. unix / windows etc.). However, due to limitations
-in the specification of this API, there might be incompatibilities
-that require small modifications of existing programs.
-
-** Threading
-
-lwIP started targeting single-threaded environments. When adding multi-
-threading support, instead of making the core thread-safe, another
-approach was chosen: there is one main thread running the lwIP core
-(also known as the "tcpip_thread"). The raw API may only be used from
-this thread! Application threads using the sequential- or socket API
-communicate with this main thread through message passing.
-
-      As such, the list of functions that may be called from
-      other threads or an ISR is very limited! Only functions
-      from these API header files are thread-safe:
-      - api.h
-      - netbuf.h
-      - netdb.h
-      - netifapi.h
-      - sockets.h
-      - sys.h
-
-      Additionaly, memory (de-)allocation functions may be
-      called from multiple threads (not ISR!) with NO_SYS=0
-      since they are protected by SYS_LIGHTWEIGHT_PROT and/or
-      semaphores.
-
-      Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1
-      and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1,
-      pbuf_free() may also be called from another thread or
-      an ISR (since only then, mem_free - for PBUF_RAM - may
-      be called from an ISR: otherwise, the HEAP is only
-      protected by semaphores).
-      
-
-** The remainder of this document discusses the "raw" API. **
-
-The raw TCP/IP interface allows the application program to integrate
-better with the TCP/IP code. Program execution is event based by
-having callback functions being called from within the TCP/IP
-code. The TCP/IP code and the application program both run in the same
-thread. The sequential API has a much higher overhead and is not very
-well suited for small systems since it forces a multithreaded paradigm
-on the application.
-
-The raw TCP/IP interface is not only faster in terms of code execution
-time but is also less memory intensive. The drawback is that program
-development is somewhat harder and application programs written for
-the raw TCP/IP interface are more difficult to understand. Still, this
-is the preferred way of writing applications that should be small in
-code size and memory usage.
-
-Both APIs can be used simultaneously by different application
-programs. In fact, the sequential API is implemented as an application
-program using the raw TCP/IP interface.
-
---- Callbacks
-
-Program execution is driven by callbacks. Each callback is an ordinary
-C function that is called from within the TCP/IP code. Every callback
-function is passed the current TCP or UDP connection state as an
-argument. Also, in order to be able to keep program specific state,
-the callback functions are called with a program specified argument
-that is independent of the TCP/IP state.
-
-The function for setting the application connection state is:
-
-- void tcp_arg(struct tcp_pcb *pcb, void *arg)
-
-  Specifies the program specific state that should be passed to all
-  other callback functions. The "pcb" argument is the current TCP
-  connection control block, and the "arg" argument is the argument
-  that will be passed to the callbacks.
-
-  
---- TCP connection setup
-
-The functions used for setting up connections is similar to that of
-the sequential API and of the BSD socket API. A new TCP connection
-identifier (i.e., a protocol control block - PCB) is created with the
-tcp_new() function. This PCB can then be either set to listen for new
-incoming connections or be explicitly connected to another host.
-
-- struct tcp_pcb *tcp_new(void)
-
-  Creates a new connection identifier (PCB). If memory is not
-  available for creating the new pcb, NULL is returned.
-
-- err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr,
-                 u16_t port)
-
-  Binds the pcb to a local IP address and port number. The IP address
-  can be specified as IP_ADDR_ANY in order to bind the connection to
-  all local IP addresses.
-
-  If another connection is bound to the same port, the function will
-  return ERR_USE, otherwise ERR_OK is returned.
-
-- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb)
-
-  Commands a pcb to start listening for incoming connections. When an
-  incoming connection is accepted, the function specified with the
-  tcp_accept() function will be called. The pcb will have to be bound
-  to a local port with the tcp_bind() function.
-
-  The tcp_listen() function returns a new connection identifier, and
-  the one passed as an argument to the function will be
-  deallocated. The reason for this behavior is that less memory is
-  needed for a connection that is listening, so tcp_listen() will
-  reclaim the memory needed for the original connection and allocate a
-  new smaller memory block for the listening connection.
-
-  tcp_listen() may return NULL if no memory was available for the
-  listening connection. If so, the memory associated with the pcb
-  passed as an argument to tcp_listen() will not be deallocated.
-
-- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
-
-  Same as tcp_listen, but limits the number of outstanding connections
-  in the listen queue to the value specified by the backlog argument.
-  To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h.
-
-- void tcp_accepted(struct tcp_pcb *pcb)
-
-  Inform lwIP that an incoming connection has been accepted. This would
-  usually be called from the accept callback. This allows lwIP to perform
-  housekeeping tasks, such as allowing further incoming connections to be
-  queued in the listen backlog.
-
-- void tcp_accept(struct tcp_pcb *pcb,
-                  err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
-                                   err_t err))
-
-  Specified the callback function that should be called when a new
-  connection arrives on a listening connection.
-      
-- err_t tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr,
-                    u16_t port, err_t (* connected)(void *arg,
-                                                    struct tcp_pcb *tpcb,
-                                                    err_t err));
-
-  Sets up the pcb to connect to the remote host and sends the
-  initial SYN segment which opens the connection. 
-
-  The tcp_connect() function returns immediately; it does not wait for
-  the connection to be properly setup. Instead, it will call the
-  function specified as the fourth argument (the "connected" argument)
-  when the connection is established. If the connection could not be
-  properly established, either because the other host refused the
-  connection or because the other host didn't answer, the "err"
-  callback function of this pcb (registered with tcp_err, see below)
-  will be called.
-
-  The tcp_connect() function can return ERR_MEM if no memory is
-  available for enqueueing the SYN segment. If the SYN indeed was
-  enqueued successfully, the tcp_connect() function returns ERR_OK.
-
-  
---- Sending TCP data
-
-TCP data is sent by enqueueing the data with a call to
-tcp_write(). When the data is successfully transmitted to the remote
-host, the application will be notified with a call to a specified
-callback function.
-
-- err_t tcp_write(struct tcp_pcb *pcb, void *dataptr, u16_t len,
-                  u8_t copy)
-
-  Enqueues the data pointed to by the argument dataptr. The length of
-  the data is passed as the len parameter. The copy argument is either
-  0 or 1 and indicates whether the new memory should be allocated for
-  the data to be copied into. If the argument is 0, no new memory
-  should be allocated and the data should only be referenced by
-  pointer.
-
-  The tcp_write() function will fail and return ERR_MEM if the length
-  of the data exceeds the current send buffer size or if the length of
-  the queue of outgoing segment is larger than the upper limit defined
-  in lwipopts.h. The number of bytes available in the output queue can
-  be retrieved with the tcp_sndbuf() function.
-
-  The proper way to use this function is to call the function with at
-  most tcp_sndbuf() bytes of data. If the function returns ERR_MEM,
-  the application should wait until some of the currently enqueued
-  data has been successfully received by the other host and try again.
-
-- void tcp_sent(struct tcp_pcb *pcb,
-                err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
-                u16_t len))
-
-  Specifies the callback function that should be called when data has
-  successfully been received (i.e., acknowledged) by the remote
-  host. The len argument passed to the callback function gives the
-  amount bytes that was acknowledged by the last acknowledgment.
-
-  
---- Receiving TCP data
-
-TCP data reception is callback based - an application specified
-callback function is called when new data arrives. When the
-application has taken the data, it has to call the tcp_recved()
-function to indicate that TCP can advertise increase the receive
-window.
-
-- void tcp_recv(struct tcp_pcb *pcb,
-                err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
-                               struct pbuf *p, err_t err))
-
-  Sets the callback function that will be called when new data
-  arrives. The callback function will be passed a NULL pbuf to
-  indicate that the remote host has closed the connection. If
-  there are no errors and the callback function is to return
-  ERR_OK, then it must free the pbuf. Otherwise, it must not
-  free the pbuf so that lwIP core code can store it.
-
-- void tcp_recved(struct tcp_pcb *pcb, u16_t len)
-
-  Must be called when the application has received the data. The len
-  argument indicates the length of the received data.
-    
-
---- Application polling
-
-When a connection is idle (i.e., no data is either transmitted or
-received), lwIP will repeatedly poll the application by calling a
-specified callback function. This can be used either as a watchdog
-timer for killing connections that have stayed idle for too long, or
-as a method of waiting for memory to become available. For instance,
-if a call to tcp_write() has failed because memory wasn't available,
-the application may use the polling functionality to call tcp_write()
-again when the connection has been idle for a while.
-
-- void tcp_poll(struct tcp_pcb *pcb, 
-                err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
-				u8_t interval)
-
-  Specifies the polling interval and the callback function that should
-  be called to poll the application. The interval is specified in
-  number of TCP coarse grained timer shots, which typically occurs
-  twice a second. An interval of 10 means that the application would
-  be polled every 5 seconds.
-
-
---- Closing and aborting connections
-
-- err_t tcp_close(struct tcp_pcb *pcb)
-
-  Closes the connection. The function may return ERR_MEM if no memory
-  was available for closing the connection. If so, the application
-  should wait and try again either by using the acknowledgment
-  callback or the polling functionality. If the close succeeds, the
-  function returns ERR_OK.
-
-  The pcb is deallocated by the TCP code after a call to tcp_close(). 
-
-- void tcp_abort(struct tcp_pcb *pcb)
-
-  Aborts the connection by sending a RST (reset) segment to the remote
-  host. The pcb is deallocated. This function never fails.
-
-  ATTENTION: When calling this from one of the TCP callbacks, make
-  sure you always return ERR_ABRT (and never return ERR_ABRT otherwise
-  or you will risk accessing deallocated memory or memory leaks!
-
-
-If a connection is aborted because of an error, the application is
-alerted of this event by the err callback. Errors that might abort a
-connection are when there is a shortage of memory. The callback
-function to be called is set using the tcp_err() function.
-
-- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg,
-       err_t err))
-
-  The error callback function does not get the pcb passed to it as a
-  parameter since the pcb may already have been deallocated.
-
-
---- Lower layer TCP interface
-
-TCP provides a simple interface to the lower layers of the
-system. During system initialization, the function tcp_init() has
-to be called before any other TCP function is called. When the system
-is running, the two timer functions tcp_fasttmr() and tcp_slowtmr()
-must be called with regular intervals. The tcp_fasttmr() should be
-called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and
-tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds. 
-
-
---- UDP interface
-
-The UDP interface is similar to that of TCP, but due to the lower
-level of complexity of UDP, the interface is significantly simpler.
-
-- struct udp_pcb *udp_new(void)
-
-  Creates a new UDP pcb which can be used for UDP communication. The
-  pcb is not active until it has either been bound to a local address
-  or connected to a remote address.
-
-- void udp_remove(struct udp_pcb *pcb)
-
-  Removes and deallocates the pcb.  
-  
-- err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr,
-                 u16_t port)
-
-  Binds the pcb to a local address. The IP-address argument "ipaddr"
-  can be IP_ADDR_ANY to indicate that it should listen to any local IP
-  address. The function currently always return ERR_OK.
-
-- err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr,
-                    u16_t port)
-
-  Sets the remote end of the pcb. This function does not generate any
-  network traffic, but only set the remote address of the pcb.
-
-- err_t udp_disconnect(struct udp_pcb *pcb)
-
-  Remove the remote end of the pcb. This function does not generate
-  any network traffic, but only removes the remote address of the pcb.
-
-- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
-
-  Sends the pbuf p. The pbuf is not deallocated.
-
-- void udp_recv(struct udp_pcb *pcb,
-                void (* recv)(void *arg, struct udp_pcb *upcb,
-                                         struct pbuf *p,
-                                         struct ip_addr *addr,
-                                         u16_t port),
-                              void *recv_arg)
-
-  Specifies a callback function that should be called when a UDP
-  datagram is received.
-  
-
---- System initalization
-
-A truly complete and generic sequence for initializing the lwip stack
-cannot be given because it depends on the build configuration (lwipopts.h)
-and additional initializations for your runtime environment (e.g. timers).
-
-We can give you some idea on how to proceed when using the raw API.
-We assume a configuration using a single Ethernet netif and the
-UDP and TCP transport layers, IPv4 and the DHCP client.
-
-Call these functions in the order of appearance:
-
-- stats_init()
-
-  Clears the structure where runtime statistics are gathered.
-
-- sys_init()
-  
-  Not of much use since we set the NO_SYS 1 option in lwipopts.h,
-  to be called for easy configuration changes.
-
-- mem_init()
-
-  Initializes the dynamic memory heap defined by MEM_SIZE.
-
-- memp_init()
-
-  Initializes the memory pools defined by MEMP_NUM_x.
-
-- pbuf_init()
-
-  Initializes the pbuf memory pool defined by PBUF_POOL_SIZE.
-  
-- etharp_init()
-
-  Initializes the ARP table and queue.
-  Note: you must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval
-  after this initialization.
-
-- ip_init()
-
-  Doesn't do much, it should be called to handle future changes.
-
-- udp_init()
-
-  Clears the UDP PCB list.
-
-- tcp_init()
-
-  Clears the TCP PCB list and clears some internal TCP timers.
-  Note: you must call tcp_fasttmr() and tcp_slowtmr() at the
-  predefined regular intervals after this initialization. 
-  
-- netif_add(struct netif *netif, struct ip_addr *ipaddr,
-            struct ip_addr *netmask, struct ip_addr *gw,
-            void *state, err_t (* init)(struct netif *netif),
-            err_t (* input)(struct pbuf *p, struct netif *netif))
-
-  Adds your network interface to the netif_list. Allocate a struct
-  netif and pass a pointer to this structure as the first argument.
-  Give pointers to cleared ip_addr structures when using DHCP,
-  or fill them with sane numbers otherwise. The state pointer may be NULL.
-
-  The init function pointer must point to a initialization function for
-  your ethernet netif interface. The following code illustrates it's use.
-  
-  err_t netif_if_init(struct netif *netif)
-  {
-    u8_t i;
-    
-    for(i = 0; i < ETHARP_HWADDR_LEN; i++) netif->hwaddr[i] = some_eth_addr[i];
-    init_my_eth_device();
-    return ERR_OK;
-  }
-  
-  For ethernet drivers, the input function pointer must point to the lwip
-  function ethernet_input() declared in "netif/etharp.h". Other drivers
-  must use ip_input() declared in "lwip/ip.h".
-  
-- netif_set_default(struct netif *netif)
-
-  Registers the default network interface.
-
-- netif_set_up(struct netif *netif)
-
-  When the netif is fully configured this function must be called.
-
-- dhcp_start(struct netif *netif)
-
-  Creates a new DHCP client for this interface on the first call.
-  Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at
-  the predefined regular intervals after starting the client.
-  
-  You can peek in the netif->dhcp struct for the actual DHCP status.
-
-
---- Optimalization hints
-
-The first thing you want to optimize is the lwip_standard_checksum()
-routine from src/core/inet.c. You can override this standard
-function with the #define LWIP_CHKSUM <your_checksum_routine>.
-
-There are C examples given in inet.c or you might want to
-craft an assembly function for this. RFC1071 is a good
-introduction to this subject.
-
-Other significant improvements can be made by supplying
-assembly or inline replacements for htons() and htonl()
-if you're using a little-endian architecture.
-#define LWIP_PLATFORM_BYTESWAP 1
-#define LWIP_PLATFORM_HTONS(x) <your_htons>
-#define LWIP_PLATFORM_HTONL(x) <your_htonl>
-
-Check your network interface driver if it reads at
-a higher speed than the maximum wire-speed. If the
-hardware isn't serviced frequently and fast enough
-buffer overflows are likely to occur.
-
-E.g. when using the cs8900 driver, call cs8900if_service(ethif)
-as frequently as possible. When using an RTOS let the cs8900 interrupt
-wake a high priority task that services your driver using a binary
-semaphore or event flag. Some drivers might allow additional tuning
-to match your application and network.
-
-For a production release it is recommended to set LWIP_STATS to 0.
-Note that speed performance isn't influenced much by simply setting
-high values to the memory options.
-
-For more optimization hints take a look at the lwIP wiki.
-
---- Zero-copy MACs
-
-To achieve zero-copy on transmit, the data passed to the raw API must
-remain unchanged until sent. Because the send- (or write-)functions return
-when the packets have been enqueued for sending, data must be kept stable
-after that, too.
-
-This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions
-must *not* be reused by the application unless their ref-count is 1.
-
-For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too,
-but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while
-PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change).
-
-Also, data passed to tcp_write without the copy-flag must not be changed!
-
-Therefore, be careful which type of PBUF you use and if you copy TCP data
-or not!

+ 0 - 135
components/net/lwip/doc/savannah.txt

@@ -1,135 +0,0 @@
-Daily Use Guide for using Savannah for lwIP
-
-Table of Contents:
-
-1 - Obtaining lwIP from the CVS repository
-2 - Committers/developers CVS access using SSH (to be written)
-3 - Merging from DEVEL branch to main trunk (stable branch)
-4 - How to release lwIP
-
-
-
-1 Obtaining lwIP from the CVS repository
-----------------------------------------
-
-To perform an anonymous CVS checkout of the main trunk (this is where
-bug fixes and incremental enhancements occur), do this:
-
-cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout lwip
- 
-Or, obtain a stable branch (updated with bug fixes only) as follows:
-cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \
-  -r STABLE-0_7 -d lwip-0.7 lwip
-
-Or, obtain a specific (fixed) release as follows:
-cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \
-  -r STABLE-0_7_0 -d lwip-0.7.0 lwip
-
-3 Committers/developers CVS access using SSH
---------------------------------------------
-
-The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption.
-As such, CVS commits to the server occur through a SSH tunnel for project members.
-To create a SSH2 key pair in UNIX-like environments, do this:
-
-ssh-keygen -t dsa
-
-Under Windows, a recommended SSH client is "PuTTY", freely available with good
-documentation and a graphic user interface. Use its key generator.
-
-Now paste the id_dsa.pub contents into your Savannah account public key list. Wait
-a while so that Savannah can update its configuration (This can take minutes).
-
-Try to login using SSH:
-
-ssh -v your_login@cvs.sv.gnu.org
-
-If it tells you:
-
-Authenticating with public key "your_key_name"...
-Server refused to allocate pty
-
-then you could login; Savannah refuses to give you a shell - which is OK, as we
-are allowed to use SSH for CVS only. Now, you should be able to do this:
-
-export CVS_RSH=ssh
-cvs -z3 -d:ext:your_login@cvs.sv.gnu.org:/sources/lwip co lwip
- 
-after which you can edit your local files with bug fixes or new features and
-commit them. Make sure you know what you are doing when using CVS to make
-changes on the repository. If in doubt, ask on the lwip-members mailing list.
-
-(If SSH asks about authenticity of the host, you can check the key
- fingerprint against http://savannah.nongnu.org/cvs/?group=lwip)
-
-
-3 Merging from DEVEL branch to main trunk (stable)
---------------------------------------------------
-
-Merging is a delicate process in CVS and requires the
-following disciplined steps in order to prevent conflicts
-in the future. Conflicts can be hard to solve!
-
-Merging from branch A to branch B requires that the A branch
-has a tag indicating the previous merger. This tag is called
-'merged_from_A_to_B'. After merging, the tag is moved in the
-A branch to remember this merger for future merge actions.
-
-IMPORTANT: AFTER COMMITTING A SUCCESFUL MERGE IN THE
-REPOSITORY, THE TAG MUST BE SET ON THE SOURCE BRANCH OF THE
-MERGE ACTION (REPLACING EXISTING TAGS WITH THE SAME NAME).
-
-Merge all changes in DEVEL since our last merge to main:
-
-In the working copy of the main trunk:
-cvs update -P -jmerged_from_DEVEL_to_main -jDEVEL 
-
-(This will apply the changes between 'merged_from_DEVEL_to_main'
-and 'DEVEL' to your work set of files)
-
-We can now commit the merge result.
-cvs commit -R -m "Merged from DEVEL to main." 
-
-If this worked out OK, we now move the tag in the DEVEL branch
-to this merge point, so we can use this point for future merges:
-
-cvs rtag -F -r DEVEL merged_from_DEVEL_to_main lwip 
-
-4 How to release lwIP
----------------------
-
-First, checkout a clean copy of the branch to be released. Tag this set with
-tag name "STABLE-0_6_3". (I use release number 0.6.3 throughout this example).
-
-Login CVS using pserver authentication, then export a clean copy of the
-tagged tree. Export is similar to a checkout, except that the CVS metadata
-is not created locally. 
-
-export CVS_RSH=ssh
-cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \
-  -r STABLE-0_6_3 -d lwip-0.6.3 lwip
-
-Archive this directory using tar, gzip'd, bzip2'd and zip'd.
-
-tar czvf lwip-0.6.3.tar.gz lwip-0.6.3
-tar cjvf lwip-0.6.3.tar.bz2 lwip-0.6.3
-zip -r lwip-0.6.3.zip lwip-0.6.3
-
-Now, sign the archives with a detached GPG binary signature as follows:
-
-gpg -b lwip-0.6.3.tar.gz
-gpg -b lwip-0.6.3.tar.bz2
-gpg -b lwip-0.6.3.zip
-
-Upload these files using anonymous FTP:
-ncftp ftp://savannah.gnu.org/incoming/savannah/lwip
-
-ncftp>mput *0.6.3.*
-
-Additionally, you may post a news item on Savannah, like this:
-
-A new 0.6.3 release is now available here:
-http://savannah.nongnu.org/files/?group=lwip&highlight=0.6.3
-
-You will have to submit this via the user News interface, then approve
-this via the Administrator News interface.

+ 0 - 181
components/net/lwip/doc/snmp_agent.txt

@@ -1,181 +0,0 @@
-SNMPv1 agent for lwIP
-
-Author: Christiaan Simons
-
-This is a brief introduction how to use and configure the SNMP agent.
-Note the agent uses the raw-API UDP interface so you may also want to
-read rawapi.txt to gain a better understanding of the SNMP message handling.
-
-0 Agent Capabilities
-====================
-
-SNMPv1 per RFC1157
-  This is an old(er) standard but is still widely supported.
-  For SNMPv2c and v3 have a greater complexity and need many
-  more lines of code. IMHO this breaks the idea of "lightweight IP".
-
-  Note the S in SNMP stands for "Simple". Note that "Simple" is
-  relative. SNMP is simple compared to the complex ISO network
-  management protocols CMIP (Common Management Information Protocol)
-  and CMOT (CMip Over Tcp).
-
-MIB II per RFC1213
-  The standard lwIP stack management information base.
-  This is a required MIB, so this is always enabled.
-  When builing lwIP without TCP, the mib-2.tcp group is omitted.
-  The groups EGP, CMOT and transmission are disabled by default.
-  
-  Most mib-2 objects are not writable except:
-  sysName, sysLocation, sysContact, snmpEnableAuthenTraps.
-  Writing to or changing the ARP and IP address and route
-  tables is not possible.
- 
-  Note lwIP has a very limited notion of IP routing. It currently
-  doen't have a route table and doesn't have a notion of the U,G,H flags.
-  Instead lwIP uses the interface list with only one default interface
-  acting as a single gateway interface (G) for the default route.
-
-  The agent returns a "virtual table" with the default route 0.0.0.0
-  for the default interface and network routes (no H) for each
-  network interface in the netif_list.
-  All routes are considered to be up (U).
-
-Loading additional MIBs
-  MIBs can only be added in compile-time, not in run-time.
-  There is no MIB compiler thus additional MIBs must be hand coded.
-
-Large SNMP message support
-  The packet decoding and encoding routines are designed
-  to use pbuf-chains. Larger payloads than the minimum
-  SNMP requirement of 484 octets are supported if the 
-  PBUF_POOL_SIZE and IP_REASS_BUFSIZE are set to match your
-  local requirement.
-
-1 Building the Agent
-====================
-
-First of all you'll need to add the following define
-to your local lwipopts.h:
-
-#define LWIP_SNMP               1
-
-and add the source files in lwip/src/core/snmp
-and some snmp headers in lwip/src/include/lwip to your makefile.
-
-Note you'll might need to adapt you network driver to update
-the mib2 variables for your interface.
-
-2 Running the Agent
-===================
-
-The following function calls must be made in your program to
-actually get the SNMP agent running.
-
-Before starting the agent you should supply pointers
-to non-volatile memory for sysContact, sysLocation,
-and snmpEnableAuthenTraps. You can do this by calling
-
-snmp_set_syscontact()
-snmp_set_syslocation()
-snmp_set_snmpenableauthentraps()
-
-Additionally you may want to set
-
-snmp_set_sysdescr()
-snmp_set_sysobjid() (if you have a private MIB)
-snmp_set_sysname()
-
-Also before starting the agent you need to setup
-one or more trap destinations using these calls:
-
-snmp_trap_dst_enable();
-snmp_trap_dst_ip_set();
-
-In the lwIP initialisation sequence call snmp_init() just after
-the call to udp_init().
-
-Exactly every 10 msec the SNMP uptime timestamp must be updated with
-snmp_inc_sysuptime(). You should call this from a timer interrupt
-or a timer signal handler depending on your runtime environment.
-
-An alternative way to update the SNMP uptime timestamp is to do a call like
-snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but call to
-a lower frequency). Another one is to not call snmp_inc_sysuptime() or
-snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro.
-This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside
-snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only
-when it's queried (any function which need "sysuptime" have to call
-snmp_get_sysuptime).
-
-
-3 Private MIBs
-==============
-
-If want to extend the agent with your own private MIB you'll need to
-add the following define to your local lwipopts.h:
-
-#define SNMP_PRIVATE_MIB        1
-
-You must provide the private_mib.h and associated files yourself.
-Note we don't have a "MIB compiler" that generates C source from a MIB,
-so you're required to do some serious coding if you enable this!
-
-Note the lwIP enterprise ID (26381) is assigned to the lwIP project,
-ALL OBJECT IDENTIFIERS LIVING UNDER THIS ID ARE ASSIGNED BY THE lwIP
-MAINTAINERS!
-
-If you need to create your own private MIB you'll need
-to apply for your own enterprise ID with IANA: http://www.iana.org/numbers.html 
-
-You can set it by passing a struct snmp_obj_id to the agent
-using snmp_set_sysobjid(&my_object_id), just before snmp_init().
-
-Note the object identifiers for thes MIB-2 and your private MIB
-tree must be kept in sorted ascending (lexicographical) order.
-This to ensure correct getnext operation.
-
-An example for a private MIB is part of the "minimal Unix" project:
-contrib/ports/unix/proj/minimal/lwip_prvmib.c
-
-The next chapter gives a more detailed description of the
-MIB-2 tree and the optional private MIB.
-
-4 The Gory Details
-==================
-
-4.0 Object identifiers and the MIB tree.
-
-We have three distinct parts for all object identifiers:
-
-The prefix
-  .iso.org.dod.internet
-
-the middle part 
-  .mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress
-
-and the index part
-  .1.192.168.0.1
-
-Objects located above the .internet hierarchy aren't supported.
-Currently only the .mgmt sub-tree is available and
-when the SNMP_PRIVATE_MIB is enabled the .private tree
-becomes available too.
-
-Object identifiers from incoming requests are checked
-for a matching prefix, middle part and index part
-or are expanded(*) for GetNext requests with short
-or inexisting names in the request.
-(* we call this "expansion" but this also
-resembles the "auto-completion" operation)
-
-The middle part is usually located in ROM (const)
-to preserve precious RAM on small microcontrollers.
-However RAM location is possible for a dynamically
-changing private tree.
-
-The index part is handled by functions which in
-turn use dynamically allocated index trees from RAM.
-These trees are updated by e.g. the etharp code
-when new entries are made or removed form the ARP cache.
-
-/** @todo more gory details */

+ 0 - 216
components/net/lwip/doc/sys_arch.txt

@@ -1,216 +0,0 @@
-sys_arch interface for lwIP 0.6++
-
-Author: Adam Dunkels
-
-The operating system emulation layer provides a common interface
-between the lwIP code and the underlying operating system kernel. The
-general idea is that porting lwIP to new architectures requires only
-small changes to a few header files and a new sys_arch
-implementation. It is also possible to do a sys_arch implementation
-that does not rely on any underlying operating system.
-
-The sys_arch provides semaphores and mailboxes to lwIP. For the full
-lwIP functionality, multiple threads support can be implemented in the
-sys_arch, but this is not required for the basic lwIP
-functionality. Previous versions of lwIP required the sys_arch to
-implement timer scheduling as well but as of lwIP 0.5 this is
-implemented in a higher layer.
-
-In addition to the source file providing the functionality of sys_arch,
-the OS emulation layer must provide several header files defining
-macros used throughout lwip.  The files required and the macros they
-must define are listed below the sys_arch description.
-
-Semaphores can be either counting or binary - lwIP works with both
-kinds. Mailboxes are used for message passing and can be implemented
-either as a queue which allows multiple messages to be posted to a
-mailbox, or as a rendez-vous point where only one message can be
-posted at a time. lwIP works with both kinds, but the former type will
-be more efficient. A message in a mailbox is just a pointer, nothing
-more. 
-
-Semaphores are represented by the type "sys_sem_t" which is typedef'd
-in the sys_arch.h file. Mailboxes are equivalently represented by the
-type "sys_mbox_t". lwIP does not place any restrictions on how
-sys_sem_t or sys_mbox_t are represented internally.
-
-The following functions must be implemented by the sys_arch:
-
-- void sys_init(void)
-
-  Is called to initialize the sys_arch layer.
-
-- sys_sem_t sys_sem_new(u8_t count)
-
-  Creates and returns a new semaphore. The "count" argument specifies
-  the initial state of the semaphore.
-
-- void sys_sem_free(sys_sem_t sem)
-
-  Deallocates a semaphore.
-
-- void sys_sem_signal(sys_sem_t sem)
-
-  Signals a semaphore.
-
-- u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
-
-  Blocks the thread while waiting for the semaphore to be
-  signaled. If the "timeout" argument is non-zero, the thread should
-  only be blocked for the specified time (measured in
-  milliseconds). If the "timeout" argument is zero, the thread should be
-  blocked until the semaphore is signalled.
-
-  If the timeout argument is non-zero, the return value is the number of
-  milliseconds spent waiting for the semaphore to be signaled. If the
-  semaphore wasn't signaled within the specified time, the return value is
-  SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
-  (i.e., it was already signaled), the function may return zero.
-
-  Notice that lwIP implements a function with a similar name,
-  sys_sem_wait(), that uses the sys_arch_sem_wait() function.
-
-- sys_mbox_t sys_mbox_new(int size)
-
-  Creates an empty mailbox for maximum "size" elements. Elements stored
-  in mailboxes are pointers. You have to define macros "_MBOX_SIZE"
-  in your lwipopts.h, or ignore this parameter in your implementation
-  and use a default size.
-
-- void sys_mbox_free(sys_mbox_t mbox)
-
-  Deallocates a mailbox. If there are messages still present in the
-  mailbox when the mailbox is deallocated, it is an indication of a
-  programming error in lwIP and the developer should be notified.
-
-- void sys_mbox_post(sys_mbox_t mbox, void *msg)
-
-  Posts the "msg" to the mailbox. This function have to block until
-  the "msg" is really posted.
-
-- err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg)
-
-  Try to post the "msg" to the mailbox. Returns ERR_MEM if this one
-  is full, else, ERR_OK if the "msg" is posted.
-
-- u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
-
-  Blocks the thread until a message arrives in the mailbox, but does
-  not block the thread longer than "timeout" milliseconds (similar to
-  the sys_arch_sem_wait() function). If "timeout" is 0, the thread should
-  be blocked until a message arrives. The "msg" argument is a result
-  parameter that is set by the function (i.e., by doing "*msg =
-  ptr"). The "msg" parameter maybe NULL to indicate that the message
-  should be dropped.
-
-  The return values are the same as for the sys_arch_sem_wait() function:
-  Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
-  timeout.
-
-  Note that a function with a similar name, sys_mbox_fetch(), is
-  implemented by lwIP. 
-
-- u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg)
-
-  This is similar to sys_arch_mbox_fetch, however if a message is not
-  present in the mailbox, it immediately returns with the code
-  SYS_MBOX_EMPTY. On success 0 is returned.
-
-  To allow for efficient implementations, this can be defined as a
-  function-like macro in sys_arch.h instead of a normal function. For
-  example, a naive implementation could be:
-    #define sys_arch_mbox_tryfetch(mbox,msg) \
-      sys_arch_mbox_fetch(mbox,msg,1)
-  although this would introduce unnecessary delays.
-  
-If threads are supported by the underlying operating system and if
-such functionality is needed in lwIP, the following function will have
-to be implemented as well:
-
-- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
-
-  Starts a new thread named "name" with priority "prio" that will begin its
-  execution in the function "thread()". The "arg" argument will be passed as an
-  argument to the thread() function. The stack size to used for this thread is
-  the "stacksize" parameter. The id of the new thread is returned. Both the id
-  and the priority are system dependent.
-
-- sys_prot_t sys_arch_protect(void)
-
-  This optional function does a "fast" critical region protection and returns
-  the previous protection level. This function is only called during very short
-  critical regions. An embedded system which supports ISR-based drivers might
-  want to implement this function by disabling interrupts. Task-based systems
-  might want to implement this by using a mutex or disabling tasking. This
-  function should support recursive calls from the same task or interrupt. In
-  other words, sys_arch_protect() could be called while already protected. In
-  that case the return value indicates that it is already protected.
-
-  sys_arch_protect() is only required if your port is supporting an operating
-  system.
-
-- void sys_arch_unprotect(sys_prot_t pval)
-
-  This optional function does a "fast" set of critical region protection to the
-  value specified by pval. See the documentation for sys_arch_protect() for
-  more information. This function is only required if your port is supporting
-  an operating system.
-
-Note:
-
-Be carefull with using mem_malloc() in sys_arch. When malloc() refers to
-mem_malloc() you can run into a circular function call problem. In mem.c
-mem_init() tries to allcate a semaphore using mem_malloc, which of course
-can't be performed when sys_arch uses mem_malloc.
-
--------------------------------------------------------------------------------
-Additional files required for the "OS support" emulation layer:
--------------------------------------------------------------------------------
-
-cc.h       - Architecture environment, some compiler specific, some
-             environment specific (probably should move env stuff 
-             to sys_arch.h.)
-
-  Typedefs for the types used by lwip -
-    u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t
-
-  Compiler hints for packing lwip's structures -
-    PACK_STRUCT_FIELD(x)
-    PACK_STRUCT_STRUCT
-    PACK_STRUCT_BEGIN
-    PACK_STRUCT_END
-
-  Platform specific diagnostic output -
-    LWIP_PLATFORM_DIAG(x)    - non-fatal, print a message.
-    LWIP_PLATFORM_ASSERT(x)  - fatal, print message and abandon execution.
-    Portability defines for printf formatters:
-    U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F
-
-  "lightweight" synchronization mechanisms -
-    SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable.
-    SYS_ARCH_PROTECT(x)      - enter protection mode.
-    SYS_ARCH_UNPROTECT(x)    - leave protection mode.
-
-  If the compiler does not provide memset() this file must include a
-  definition of it, or include a file which defines it.
-
-  This file must either include a system-local <errno.h> which defines
-  the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO
-  to make lwip/arch.h define the codes which are used throughout.
-
-
-perf.h     - Architecture specific performance measurement.
-  Measurement calls made throughout lwip, these can be defined to nothing.
-    PERF_START               - start measuring something.
-    PERF_STOP(x)             - stop measuring something, and record the result.
-
-sys_arch.h - Tied to sys_arch.c
-
-  Arch dependent types for the following objects:
-    sys_sem_t, sys_mbox_t, sys_thread_t,
-  And, optionally:
-    sys_prot_t
-
-  Defines to set vars of sys_mbox_t and sys_sem_t to NULL.
-    SYS_MBOX_NULL NULL
-    SYS_SEM_NULL NULL

+ 0 - 26
components/net/lwip/src/.hgignore

@@ -1,26 +0,0 @@
-syntax: glob 
- 
-*.pyc 
-*.orig 
-*.rej 
-*~ 
-TAGS 
-Module.symvers 
-*.ncb
-*.suo
-*.bak
-*.orig
-*.rej
-
-syntax: regexp
-\.\#.+
-[\\/]CVS$
-^CVS$
-^build$
-^install$
-^logs.build_tree$
-[\\/]bin$
-^bin$
-[\\/]obj$
-^obj$
-\.cvsignore

+ 0 - 13
components/net/lwip/src/FILES

@@ -1,13 +0,0 @@
-api/      - The code for the high-level wrapper API. Not needed if
-            you use the lowel-level call-back/raw API.
-
-core/     - The core of the TPC/IP stack; protocol implementations,
-            memory and buffer management, and the low-level raw API.
-
-include/  - lwIP include files.
-
-netif/    - Generic network interface device drivers are kept here,
-            as well as the ARP module.
-
-For more information on the various subdirectories, check the FILES
-file in each directory.

+ 0 - 740
components/net/lwip/src/api/api_lib.c

@@ -1,740 +0,0 @@
-/**
- * @file
- * Sequential API External module
- *
- */
- 
-/*
- * Copyright (c) 2001-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. 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 lwIP TCP/IP stack.
- * 
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-/* This is the part of the API that is linked with
-   the application */
-
-#include "lwip/opt.h"
-
-#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/api.h"
-#include "lwip/tcpip.h"
-#include "lwip/memp.h"
-
-#include "lwip/ip.h"
-#include "lwip/raw.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-
-#include <string.h>
-
-/**
- * Create a new netconn (of a specific type) that has a callback function.
- * The corresponding pcb is also created.
- *
- * @param t the type of 'connection' to create (@see enum netconn_type)
- * @param proto the IP protocol for RAW IP pcbs
- * @param callback a function to call on status changes (RX available, TX'ed)
- * @return a newly allocated struct netconn or
- *         NULL on memory error
- */
-struct netconn*
-netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
-{
-  struct netconn *conn;
-  struct api_msg msg;
-
-  conn = netconn_alloc(t, callback);
-  if (conn != NULL) {
-    msg.function = do_newconn;
-    msg.msg.msg.n.proto = proto;
-    msg.msg.conn = conn;
-    if (TCPIP_APIMSG(&msg) != ERR_OK) {
-      LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
-      LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
-      LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
-#if LWIP_TCP
-      LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
-#endif /* LWIP_TCP */
-      sys_sem_free(&conn->op_completed);
-      sys_mbox_free(&conn->recvmbox);
-      memp_free(MEMP_NETCONN, conn);
-      return NULL;
-    }
-  }
-  return conn;
-}
-
-/**
- * Close a netconn 'connection' and free its resources.
- * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate
- * after this returns.
- *
- * @param conn the netconn to delete
- * @return ERR_OK if the connection was deleted
- */
-err_t
-netconn_delete(struct netconn *conn)
-{
-  struct api_msg msg;
-
-  /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
-  if (conn == NULL) {
-    return ERR_OK;
-  }
-
-  msg.function = do_delconn;
-  msg.msg.conn = conn;
-  tcpip_apimsg(&msg);
-
-  netconn_free(conn);
-
-  /* don't care for return value of do_delconn since it only calls void functions */
-
-  return ERR_OK;
-}
-
-/**
- * Get the local or remote IP address and port of a netconn.
- * For RAW netconns, this returns the protocol instead of a port!
- *
- * @param conn the netconn to query
- * @param addr a pointer to which to save the IP address
- * @param port a pointer to which to save the port (or protocol for RAW)
- * @param local 1 to get the local IP address, 0 to get the remote one
- * @return ERR_CONN for invalid connections
- *         ERR_OK if the information was retrieved
- */
-err_t
-netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
-  LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
-  LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
-
-  msg.function = do_getaddr;
-  msg.msg.conn = conn;
-  msg.msg.msg.ad.ipaddr = addr;
-  msg.msg.msg.ad.port = port;
-  msg.msg.msg.ad.local = local;
-  err = TCPIP_APIMSG(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-
-/**
- * Bind a netconn to a specific local IP address and port.
- * Binding one netconn twice might not always be checked correctly!
- *
- * @param conn the netconn to bind
- * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY
- *             to bind to all addresses)
- * @param port the local port to bind the netconn to (not used for RAW)
- * @return ERR_OK if bound, any other err_t on failure
- */
-err_t
-netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
-
-  msg.function = do_bind;
-  msg.msg.conn = conn;
-  msg.msg.msg.bc.ipaddr = addr;
-  msg.msg.msg.bc.port = port;
-  err = TCPIP_APIMSG(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-
-/**
- * Connect a netconn to a specific remote IP address and port.
- *
- * @param conn the netconn to connect
- * @param addr the remote IP address to connect to
- * @param port the remote port to connect to (no used for RAW)
- * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise
- */
-err_t
-netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
-
-  msg.function = do_connect;
-  msg.msg.conn = conn;
-  msg.msg.msg.bc.ipaddr = addr;
-  msg.msg.msg.bc.port = port;
-  /* This is the only function which need to not block tcpip_thread */
-  err = tcpip_apimsg(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-
-/**
- * Disconnect a netconn from its current peer (only valid for UDP netconns).
- *
- * @param conn the netconn to disconnect
- * @return TODO: return value is not set here...
- */
-err_t
-netconn_disconnect(struct netconn *conn)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
-
-  msg.function = do_disconnect;
-  msg.msg.conn = conn;
-  err = TCPIP_APIMSG(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-
-/**
- * Set a TCP netconn into listen mode
- *
- * @param conn the tcp netconn to set to listen mode
- * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1
- * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
- *         don't return any error (yet?))
- */
-err_t
-netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
-{
-#if LWIP_TCP
-  struct api_msg msg;
-  err_t err;
-
-  /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
-  LWIP_UNUSED_ARG(backlog);
-
-  LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
-
-  msg.function = do_listen;
-  msg.msg.conn = conn;
-#if TCP_LISTEN_BACKLOG
-  msg.msg.msg.lb.backlog = backlog;
-#endif /* TCP_LISTEN_BACKLOG */
-  err = TCPIP_APIMSG(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-#else /* LWIP_TCP */
-  LWIP_UNUSED_ARG(conn);
-  LWIP_UNUSED_ARG(backlog);
-  return ERR_ARG;
-#endif /* LWIP_TCP */
-}
-
-/**
- * Accept a new connection on a TCP listening netconn.
- *
- * @param conn the TCP listen netconn
- * @param new_conn pointer where the new connection is stored
- * @return ERR_OK if a new connection has been received or an error
- *                code otherwise
- */
-err_t
-netconn_accept(struct netconn *conn, struct netconn **new_conn)
-{
-#if LWIP_TCP
-  struct netconn *newconn;
-  err_t err;
-#if TCP_LISTEN_BACKLOG
-  struct api_msg msg;
-#endif /* TCP_LISTEN_BACKLOG */
-
-  LWIP_ERROR("netconn_accept: invalid pointer",    (new_conn != NULL),                  return ERR_ARG;);
-  *new_conn = NULL;
-  LWIP_ERROR("netconn_accept: invalid conn",       (conn != NULL),                      return ERR_ARG;);
-  LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox),   return ERR_ARG;);
-
-  err = conn->last_err;
-  if (ERR_IS_FATAL(err)) {
-    /* don't recv on fatal errors: this might block the application task
-       waiting on acceptmbox forever! */
-    return err;
-  }
-
-#if LWIP_SO_RCVTIMEO
-  if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
-    NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
-    return ERR_TIMEOUT;
-  }
-#else
-  sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0);
-#endif /* LWIP_SO_RCVTIMEO*/
-  /* Register event with callback */
-  API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
-
-  if (newconn == NULL) {
-    /* connection has been aborted */
-    NETCONN_SET_SAFE_ERR(conn, ERR_ABRT);
-    return ERR_ABRT;
-  }
-#if TCP_LISTEN_BACKLOG
-  /* Let the stack know that we have accepted the connection. */
-  msg.function = do_recv;
-  msg.msg.conn = conn;
-  /* don't care for the return value of do_recv */
-  TCPIP_APIMSG(&msg);
-#endif /* TCP_LISTEN_BACKLOG */
-
-  *new_conn = newconn;
-  /* don't set conn->last_err: it's only ERR_OK, anyway */
-  return ERR_OK;
-#else /* LWIP_TCP */
-  LWIP_UNUSED_ARG(conn);
-  LWIP_UNUSED_ARG(new_conn);
-  return ERR_ARG;
-#endif /* LWIP_TCP */
-}
-
-/**
- * Receive data: actual implementation that doesn't care whether pbuf or netbuf
- * is received
- *
- * @param conn the netconn from which to receive data
- * @param new_buf pointer where a new pbuf/netbuf is stored when received data
- * @return ERR_OK if data has been received, an error code otherwise (timeout,
- *                memory error or another error)
- */
-static err_t
-netconn_recv_data(struct netconn *conn, void **new_buf)
-{
-  void *buf = NULL;
-  u16_t len;
-  err_t err;
-#if LWIP_TCP
-  struct api_msg msg;
-#endif /* LWIP_TCP */
-
-  LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
-  *new_buf = NULL;
-  LWIP_ERROR("netconn_recv: invalid conn",    (conn != NULL),    return ERR_ARG;);
-  LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
-
-  err = conn->last_err;
-  if (ERR_IS_FATAL(err)) {
-    /* don't recv on fatal errors: this might block the application task
-       waiting on recvmbox forever! */
-    /* @todo: this does not allow us to fetch data that has been put into recvmbox
-       before the fatal error occurred - is that a problem? */
-    return err;
-  }
-
-#if LWIP_SO_RCVTIMEO
-  if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
-    NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
-    return ERR_TIMEOUT;
-  }
-#else
-  sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
-#endif /* LWIP_SO_RCVTIMEO*/
-
-#if LWIP_TCP
-  if (conn->type == NETCONN_TCP) {
-    if (!netconn_get_noautorecved(conn) || (buf == NULL)) {
-      /* Let the stack know that we have taken the data. */
-      /* TODO: Speedup: Don't block and wait for the answer here
-         (to prevent multiple thread-switches). */
-      msg.function = do_recv;
-      msg.msg.conn = conn;
-      if (buf != NULL) {
-        msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len;
-      } else {
-        msg.msg.msg.r.len = 1;
-      }
-      /* don't care for the return value of do_recv */
-      TCPIP_APIMSG(&msg);
-    }
-
-    /* If we are closed, we indicate that we no longer wish to use the socket */
-    if (buf == NULL) {
-      API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
-      /* Avoid to lose any previous error code */
-      NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
-      return ERR_CLSD;
-    }
-    len = ((struct pbuf *)buf)->tot_len;
-  }
-#endif /* LWIP_TCP */
-#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
-  else
-#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
-#if (LWIP_UDP || LWIP_RAW)
-  {
-    LWIP_ASSERT("buf != NULL", buf != NULL);
-    len = netbuf_len((struct netbuf *)buf);
-  }
-#endif /* (LWIP_UDP || LWIP_RAW) */
-
-#if LWIP_SO_RCVBUF
-  SYS_ARCH_DEC(conn->recv_avail, len);
-#endif /* LWIP_SO_RCVBUF */
-  /* Register event with callback */
-  API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
-
-  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
-
-  *new_buf = buf;
-  /* don't set conn->last_err: it's only ERR_OK, anyway */
-  return ERR_OK;
-}
-
-/**
- * Receive data (in form of a pbuf) from a TCP netconn
- *
- * @param conn the netconn from which to receive data
- * @param new_buf pointer where a new pbuf is stored when received data
- * @return ERR_OK if data has been received, an error code otherwise (timeout,
- *                memory error or another error)
- *         ERR_ARG if conn is not a TCP netconn
- */
-err_t
-netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
-{
-  LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) &&
-             netconn_type(conn) == NETCONN_TCP, return ERR_ARG;);
-
-  return netconn_recv_data(conn, (void **)new_buf);
-}
-
-/**
- * Receive data (in form of a netbuf containing a packet buffer) from a netconn
- *
- * @param conn the netconn from which to receive data
- * @param new_buf pointer where a new netbuf is stored when received data
- * @return ERR_OK if data has been received, an error code otherwise (timeout,
- *                memory error or another error)
- */
-err_t
-netconn_recv(struct netconn *conn, struct netbuf **new_buf)
-{
-#if LWIP_TCP
-  struct netbuf *buf = NULL;
-  err_t err;
-#endif /* LWIP_TCP */
-
-  LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
-  *new_buf = NULL;
-  LWIP_ERROR("netconn_recv: invalid conn",    (conn != NULL),    return ERR_ARG;);
-  LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
-
-#if LWIP_TCP
-  if (conn->type == NETCONN_TCP) {
-    struct pbuf *p = NULL;
-    /* This is not a listening netconn, since recvmbox is set */
-
-    buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
-    if (buf == NULL) {
-      NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
-      return ERR_MEM;
-    }
-
-    err = netconn_recv_data(conn, (void **)&p);
-    if (err != ERR_OK) {
-      memp_free(MEMP_NETBUF, buf);
-      return err;
-    }
-    LWIP_ASSERT("p != NULL", p != NULL);
-
-    buf->p = p;
-    buf->ptr = p;
-    buf->port = 0;
-    ip_addr_set_any(&buf->addr);
-    *new_buf = buf;
-    /* don't set conn->last_err: it's only ERR_OK, anyway */
-    return ERR_OK;
-  } else
-#endif /* LWIP_TCP */
-  {
-#if (LWIP_UDP || LWIP_RAW)
-    return netconn_recv_data(conn, (void **)new_buf);
-#endif /* (LWIP_UDP || LWIP_RAW) */
-  }
-}
-
-/**
- * TCP: update the receive window: by calling this, the application
- * tells the stack that it has processed data and is able to accept
- * new data.
- * ATTENTION: use with care, this is mainly used for sockets!
- * Can only be used when calling netconn_set_noautorecved(conn, 1) before.
- *
- * @param conn the netconn for which to update the receive window
- * @param length amount of data processed (ATTENTION: this must be accurate!)
- */
-void
-netconn_recved(struct netconn *conn, u32_t length)
-{
-#if LWIP_TCP
-  if ((conn != NULL) && (conn->type == NETCONN_TCP) &&
-      (netconn_get_noautorecved(conn))) {
-    struct api_msg msg;
-    /* Let the stack know that we have taken the data. */
-    /* TODO: Speedup: Don't block and wait for the answer here
-       (to prevent multiple thread-switches). */
-    msg.function = do_recv;
-    msg.msg.conn = conn;
-    msg.msg.msg.r.len = length;
-    /* don't care for the return value of do_recv */
-    TCPIP_APIMSG(&msg);
-  }
-#else /* LWIP_TCP */
-  LWIP_UNUSED_ARG(conn);
-  LWIP_UNUSED_ARG(length);
-#endif /* LWIP_TCP */
-}
-
-/**
- * Send data (in form of a netbuf) to a specific remote IP address and port.
- * Only to be used for UDP and RAW netconns (not TCP).
- *
- * @param conn the netconn over which to send data
- * @param buf a netbuf containing the data to send
- * @param addr the remote IP address to which to send the data
- * @param port the remote port to which to send the data
- * @return ERR_OK if data was sent, any other err_t on error
- */
-err_t
-netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port)
-{
-  if (buf != NULL) {
-    ip_addr_set(&buf->addr, addr);
-    buf->port = port;
-    return netconn_send(conn, buf);
-  }
-  return ERR_VAL;
-}
-
-/**
- * Send data over a UDP or RAW netconn (that is already connected).
- *
- * @param conn the UDP or RAW netconn over which to send data
- * @param buf a netbuf containing the data to send
- * @return ERR_OK if data was sent, any other err_t on error
- */
-err_t
-netconn_send(struct netconn *conn, struct netbuf *buf)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_send: invalid conn",  (conn != NULL), return ERR_ARG;);
-
-  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
-  msg.function = do_send;
-  msg.msg.conn = conn;
-  msg.msg.msg.b = buf;
-  err = TCPIP_APIMSG(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-
-/**
- * Send data over a TCP netconn.
- *
- * @param conn the TCP netconn over which to send data
- * @param dataptr pointer to the application buffer that contains the data to send
- * @param size size of the application data to send
- * @param apiflags combination of following flags :
- * - NETCONN_COPY: data will be copied into memory belonging to the stack
- * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
- * - NETCONN_DONTBLOCK: only write the data if all dat can be written at once
- * @return ERR_OK if data was sent, any other err_t on error
- */
-err_t
-netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_write: invalid conn",  (conn != NULL), return ERR_ARG;);
-  LWIP_ERROR("netconn_write: invalid conn->type",  (conn->type == NETCONN_TCP), return ERR_VAL;);
-  if (size == 0) {
-    return ERR_OK;
-  }
-
-  /* @todo: for non-blocking write, check if 'size' would ever fit into
-            snd_queue or snd_buf */
-  msg.function = do_write;
-  msg.msg.conn = conn;
-  msg.msg.msg.w.dataptr = dataptr;
-  msg.msg.msg.w.apiflags = apiflags;
-  msg.msg.msg.w.len = size;
-  /* For locking the core: this _can_ be delayed on low memory/low send buffer,
-     but if it is, this is done inside api_msg.c:do_write(), so we can use the
-     non-blocking version here. */
-  err = TCPIP_APIMSG(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-
-/**
- * Close ot shutdown a TCP netconn (doesn't delete it).
- *
- * @param conn the TCP netconn to close or shutdown
- * @param how fully close or only shutdown one side?
- * @return ERR_OK if the netconn was closed, any other err_t on error
- */
-static err_t
-netconn_close_shutdown(struct netconn *conn, u8_t how)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_close: invalid conn",  (conn != NULL), return ERR_ARG;);
-
-  msg.function = do_close;
-  msg.msg.conn = conn;
-  /* shutting down both ends is the same as closing */
-  msg.msg.msg.sd.shut = how;
-  /* because of the LWIP_TCPIP_CORE_LOCKING implementation of do_close,
-     don't use TCPIP_APIMSG here */
-  err = tcpip_apimsg(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-
-/**
- * Close a TCP netconn (doesn't delete it).
- *
- * @param conn the TCP netconn to close
- * @return ERR_OK if the netconn was closed, any other err_t on error
- */
-err_t
-netconn_close(struct netconn *conn)
-{
-  /* shutting down both ends is the same as closing */
-  return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
-}
-
-/**
- * Shut down one or both sides of a TCP netconn (doesn't delete it).
- *
- * @param conn the TCP netconn to shut down
- * @return ERR_OK if the netconn was closed, any other err_t on error
- */
-err_t
-netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
-{
-  return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0));
-}
-
-#if LWIP_IGMP
-/**
- * Join multicast groups for UDP netconns.
- *
- * @param conn the UDP netconn for which to change multicast addresses
- * @param multiaddr IP address of the multicast group to join or leave
- * @param netif_addr the IP address of the network interface on which to send
- *                  the igmp message
- * @param join_or_leave flag whether to send a join- or leave-message
- * @return ERR_OK if the action was taken, any err_t on error
- */
-err_t
-netconn_join_leave_group(struct netconn *conn,
-                         ip_addr_t *multiaddr,
-                         ip_addr_t *netif_addr,
-                         enum netconn_igmp join_or_leave)
-{
-  struct api_msg msg;
-  err_t err;
-
-  LWIP_ERROR("netconn_join_leave_group: invalid conn",  (conn != NULL), return ERR_ARG;);
-
-  msg.function = do_join_leave_group;
-  msg.msg.conn = conn;
-  msg.msg.msg.jl.multiaddr = multiaddr;
-  msg.msg.msg.jl.netif_addr = netif_addr;
-  msg.msg.msg.jl.join_or_leave = join_or_leave;
-  err = TCPIP_APIMSG(&msg);
-
-  NETCONN_SET_SAFE_ERR(conn, err);
-  return err;
-}
-#endif /* LWIP_IGMP */
-
-#if LWIP_DNS
-/**
- * Execute a DNS query, only one IP address is returned
- *
- * @param name a string representation of the DNS host name to query
- * @param addr a preallocated ip_addr_t where to store the resolved IP address
- * @return ERR_OK: resolving succeeded
- *         ERR_MEM: memory error, try again later
- *         ERR_ARG: dns client not initialized or invalid hostname
- *         ERR_VAL: dns server response was invalid
- */
-err_t
-netconn_gethostbyname(const char *name, ip_addr_t *addr)
-{
-  struct dns_api_msg msg;
-  err_t err;
-  sys_sem_t sem;
-
-  LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
-  LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
-
-  err = sys_sem_new(&sem, 0);
-  if (err != ERR_OK) {
-    return err;
-  }
-
-  msg.name = name;
-  msg.addr = addr;
-  msg.err = &err;
-  msg.sem = &sem;
-
-  tcpip_callback(do_gethostbyname, &msg);
-  sys_sem_wait(&sem);
-  sys_sem_free(&sem);
-
-  return err;
-}
-#endif /* LWIP_DNS*/
-
-#endif /* LWIP_NETCONN */

+ 0 - 1535
components/net/lwip/src/api/api_msg.c

@@ -1,1535 +0,0 @@
-/**
- * @file
- * Sequential API Internal module
- *
- */
-
-/*
- * Copyright (c) 2001-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. 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 lwIP TCP/IP stack.
- * 
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/api_msg.h"
-
-#include "lwip/ip.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-#include "lwip/raw.h"
-
-#include "lwip/memp.h"
-#include "lwip/tcpip.h"
-#include "lwip/igmp.h"
-#include "lwip/dns.h"
-
-#include <string.h>
-
-#define SET_NONBLOCKING_CONNECT(conn, val)  do { if(val) { \
-  (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \
-} else { \
-  (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0)
-#define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0)
-
-/* forward declarations */
-#if LWIP_TCP
-static err_t do_writemore(struct netconn *conn);
-static void do_close_internal(struct netconn *conn);
-#endif
-
-#if LWIP_RAW
-/**
- * Receive callback function for RAW netconns.
- * Doesn't 'eat' the packet, only references it and sends it to
- * conn->recvmbox
- *
- * @see raw.h (struct raw_pcb.recv) for parameters and return value
- */
-static u8_t
-recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
-    ip_addr_t *addr)
-{
-  struct pbuf *q;
-  struct netbuf *buf;
-  struct netconn *conn;
-
-  LWIP_UNUSED_ARG(addr);
-  conn = (struct netconn *)arg;
-
-  if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox)) {
-#if LWIP_SO_RCVBUF
-    int recv_avail;
-    SYS_ARCH_GET(conn->recv_avail, recv_avail);
-    if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) {
-      return 0;
-    }
-#endif /* LWIP_SO_RCVBUF */
-    /* copy the whole packet into new pbufs */
-    q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
-    if(q != NULL) {
-      if (pbuf_copy(q, p) != ERR_OK) {
-        pbuf_free(q);
-        q = NULL;
-      }
-    }
-
-    if (q != NULL) {
-      u16_t len;
-      buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
-      if (buf == NULL) {
-        pbuf_free(q);
-        return 0;
-      }
-
-      buf->p = q;
-      buf->ptr = q;
-      ip_addr_copy(buf->addr, *ip_current_src_addr());
-      buf->port = pcb->protocol;
-
-      len = q->tot_len;
-      if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
-        netbuf_delete(buf);
-        return 0;
-      } else {
-#if LWIP_SO_RCVBUF
-        SYS_ARCH_INC(conn->recv_avail, len);
-#endif /* LWIP_SO_RCVBUF */
-        /* Register event with callback */
-        API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
-      }
-    }
-  }
-
-  return 0; /* do not eat the packet */
-}
-#endif /* LWIP_RAW*/
-
-#if LWIP_UDP
-/**
- * Receive callback function for UDP netconns.
- * Posts the packet to conn->recvmbox or deletes it on memory error.
- *
- * @see udp.h (struct udp_pcb.recv) for parameters
- */
-static void
-recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
-   ip_addr_t *addr, u16_t port)
-{
-  struct netbuf *buf;
-  struct netconn *conn;
-  u16_t len;
-#if LWIP_SO_RCVBUF
-  int recv_avail;
-#endif /* LWIP_SO_RCVBUF */
-
-  LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
-  LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
-  LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
-  conn = (struct netconn *)arg;
-  LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
-
-#if LWIP_SO_RCVBUF
-  SYS_ARCH_GET(conn->recv_avail, recv_avail);
-  if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) ||
-      ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
-#else  /* LWIP_SO_RCVBUF */
-  if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) {
-#endif /* LWIP_SO_RCVBUF */
-    pbuf_free(p);
-    return;
-  }
-
-  buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
-  if (buf == NULL) {
-    pbuf_free(p);
-    return;
-  } else {
-    buf->p = p;
-    buf->ptr = p;
-    ip_addr_set(&buf->addr, addr);
-    buf->port = port;
-#if LWIP_NETBUF_RECVINFO
-    {
-      const struct ip_hdr* iphdr = ip_current_header();
-      /* get the UDP header - always in the first pbuf, ensured by udp_input */
-      const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
-#if LWIP_CHECKSUM_ON_COPY
-      buf->flags = NETBUF_FLAG_DESTADDR;
-#endif /* LWIP_CHECKSUM_ON_COPY */
-      ip_addr_set(&buf->toaddr, ip_current_dest_addr());
-      buf->toport_chksum = udphdr->dest;
-    }
-#endif /* LWIP_NETBUF_RECVINFO */
-  }
-
-  len = p->tot_len;
-  if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
-    netbuf_delete(buf);
-    return;
-  } else {
-#if LWIP_SO_RCVBUF
-    SYS_ARCH_INC(conn->recv_avail, len);
-#endif /* LWIP_SO_RCVBUF */
-    /* Register event with callback */
-    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
-  }
-}
-#endif /* LWIP_UDP */
-
-#if LWIP_TCP
-/**
- * Receive callback function for TCP netconns.
- * Posts the packet to conn->recvmbox, but doesn't delete it on errors.
- *
- * @see tcp.h (struct tcp_pcb.recv) for parameters and return value
- */
-static err_t
-recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
-{
-  struct netconn *conn;
-  u16_t len;
-
-  LWIP_UNUSED_ARG(pcb);
-  LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
-  LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
-  conn = (struct netconn *)arg;
-  LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-  if (!sys_mbox_valid(&conn->recvmbox)) {
-    /* recvmbox already deleted */
-    if (p != NULL) {
-      tcp_recved(pcb, p->tot_len);
-      pbuf_free(p);
-    }
-    return ERR_OK;
-  }
-  /* Unlike for UDP or RAW pcbs, don't check for available space
-     using recv_avail since that could break the connection
-     (data is already ACKed) */
-
-  /* don't overwrite fatal errors! */
-  NETCONN_SET_SAFE_ERR(conn, err);
-
-  if (p != NULL) {
-    len = p->tot_len;
-  } else {
-    len = 0;
-  }
-
-  if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) {
-    /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
-    return ERR_MEM;
-  } else {
-#if LWIP_SO_RCVBUF
-    SYS_ARCH_INC(conn->recv_avail, len);
-#endif /* LWIP_SO_RCVBUF */
-    /* Register event with callback */
-    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
-  }
-
-  return ERR_OK;
-}
-
-/**
- * Poll callback function for TCP netconns.
- * Wakes up an application thread that waits for a connection to close
- * or data to be sent. The application thread then takes the
- * appropriate action to go on.
- *
- * Signals the conn->sem.
- * netconn_close waits for conn->sem if closing failed.
- *
- * @see tcp.h (struct tcp_pcb.poll) for parameters and return value
- */
-static err_t
-poll_tcp(void *arg, struct tcp_pcb *pcb)
-{
-  struct netconn *conn = (struct netconn *)arg;
-
-  LWIP_UNUSED_ARG(pcb);
-  LWIP_ASSERT("conn != NULL", (conn != NULL));
-
-  if (conn->state == NETCONN_WRITE) {
-    do_writemore(conn);
-  } else if (conn->state == NETCONN_CLOSE) {
-    do_close_internal(conn);
-  }
-  /* @todo: implement connect timeout here? */
-
-  /* Did a nonblocking write fail before? Then check available write-space. */
-  if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
-    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
-       let select mark this pcb as writable again. */
-    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
-      (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
-      conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
-      API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
-    }
-  }
-
-  return ERR_OK;
-}
-
-/**
- * Sent callback function for TCP netconns.
- * Signals the conn->sem and calls API_EVENT.
- * netconn_write waits for conn->sem if send buffer is low.
- *
- * @see tcp.h (struct tcp_pcb.sent) for parameters and return value
- */
-static err_t
-sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
-{
-  struct netconn *conn = (struct netconn *)arg;
-
-  LWIP_UNUSED_ARG(pcb);
-  LWIP_ASSERT("conn != NULL", (conn != NULL));
-
-  if (conn->state == NETCONN_WRITE) {
-    do_writemore(conn);
-  } else if (conn->state == NETCONN_CLOSE) {
-    do_close_internal(conn);
-  }
-
-  if (conn) {
-    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
-       let select mark this pcb as writable again. */
-    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
-      (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
-      conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
-      API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
-    }
-  }
-  
-  return ERR_OK;
-}
-
-/**
- * Error callback function for TCP netconns.
- * Signals conn->sem, posts to all conn mboxes and calls API_EVENT.
- * The application thread has then to decide what to do.
- *
- * @see tcp.h (struct tcp_pcb.err) for parameters
- */
-static void
-err_tcp(void *arg, err_t err)
-{
-  struct netconn *conn;
-  enum netconn_state old_state;
-  SYS_ARCH_DECL_PROTECT(lev);
-
-  conn = (struct netconn *)arg;
-  LWIP_ASSERT("conn != NULL", (conn != NULL));
-
-  conn->pcb.tcp = NULL;
-
-  /* no check since this is always fatal! */
-  SYS_ARCH_PROTECT(lev);
-  conn->last_err = err;
-  SYS_ARCH_UNPROTECT(lev);
-
-  /* reset conn->state now before waking up other threads */
-  old_state = conn->state;
-  conn->state = NETCONN_NONE;
-
-  /* Notify the user layer about a connection error. Used to signal
-     select. */
-  API_EVENT(conn, NETCONN_EVT_ERROR, 0);
-  /* Try to release selects pending on 'read' or 'write', too.
-     They will get an error if they actually try to read or write. */
-  API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
-  API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
-
-  /* pass NULL-message to recvmbox to wake up pending recv */
-  if (sys_mbox_valid(&conn->recvmbox)) {
-    /* use trypost to prevent deadlock */
-    sys_mbox_trypost(&conn->recvmbox, NULL);
-  }
-  /* pass NULL-message to acceptmbox to wake up pending accept */
-  if (sys_mbox_valid(&conn->acceptmbox)) {
-    /* use trypost to preven deadlock */
-    sys_mbox_trypost(&conn->acceptmbox, NULL);
-  }
-
-  if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
-      (old_state == NETCONN_CONNECT)) {
-    /* calling do_writemore/do_close_internal is not necessary
-       since the pcb has already been deleted! */
-    int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
-    SET_NONBLOCKING_CONNECT(conn, 0);
-
-    if (!was_nonblocking_connect) {
-      /* set error return code */
-      LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
-      conn->current_msg->err = err;
-      conn->current_msg = NULL;
-      /* wake up the waiting task */
-      sys_sem_signal(&conn->op_completed);
-    }
-  } else {
-    LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
-  }
-}
-
-/**
- * Setup a tcp_pcb with the correct callback function pointers
- * and their arguments.
- *
- * @param conn the TCP netconn to setup
- */
-static void
-setup_tcp(struct netconn *conn)
-{
-  struct tcp_pcb *pcb;
-
-  pcb = conn->pcb.tcp;
-  tcp_arg(pcb, conn);
-  tcp_recv(pcb, recv_tcp);
-  tcp_sent(pcb, sent_tcp);
-  tcp_poll(pcb, poll_tcp, 4);
-  tcp_err(pcb, err_tcp);
-}
-
-/**
- * Accept callback function for TCP netconns.
- * Allocates a new netconn and posts that to conn->acceptmbox.
- *
- * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value
- */
-static err_t
-accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
-{
-  struct netconn *newconn;
-  struct netconn *conn = (struct netconn *)arg;
-
-  LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state)));
-
-  if (!sys_mbox_valid(&conn->acceptmbox)) {
-    LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n"));
-    return ERR_VAL;
-  }
-
-  /* We have to set the callback here even though
-   * the new socket is unknown. conn->socket is marked as -1. */
-  newconn = netconn_alloc(conn->type, conn->callback);
-  if (newconn == NULL) {
-    return ERR_MEM;
-  }
-  newconn->pcb.tcp = newpcb;
-  setup_tcp(newconn);
-  /* no protection: when creating the pcb, the netconn is not yet known
-     to the application thread */
-  newconn->last_err = err;
-
-  if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) {
-    /* When returning != ERR_OK, the pcb is aborted in tcp_process(),
-       so do nothing here! */
-    newconn->pcb.tcp = NULL;
-    /* no need to drain since we know the recvmbox is empty. */
-    sys_mbox_free(&newconn->recvmbox);
-    sys_mbox_set_invalid(&newconn->recvmbox);
-    netconn_free(newconn);
-    return ERR_MEM;
-  } else {
-    /* Register event with callback */
-    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
-  }
-
-  return ERR_OK;
-}
-#endif /* LWIP_TCP */
-
-/**
- * Create a new pcb of a specific type.
- * Called from do_newconn().
- *
- * @param msg the api_msg_msg describing the connection type
- * @return msg->conn->err, but the return value is currently ignored
- */
-static void
-pcb_new(struct api_msg_msg *msg)
-{
-  LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
-
-  /* Allocate a PCB for this connection */
-  switch(NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
-  case NETCONN_RAW:
-    msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
-    if(msg->conn->pcb.raw == NULL) {
-      msg->err = ERR_MEM;
-      break;
-    }
-    raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
-    break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
-  case NETCONN_UDP:
-    msg->conn->pcb.udp = udp_new();
-    if(msg->conn->pcb.udp == NULL) {
-      msg->err = ERR_MEM;
-      break;
-    }
-#if LWIP_UDPLITE
-    if (msg->conn->type==NETCONN_UDPLITE) {
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
-    }
-#endif /* LWIP_UDPLITE */
-    if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
-      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
-    }
-    udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
-    break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-  case NETCONN_TCP:
-    msg->conn->pcb.tcp = tcp_new();
-    if(msg->conn->pcb.tcp == NULL) {
-      msg->err = ERR_MEM;
-      break;
-    }
-    setup_tcp(msg->conn);
-    break;
-#endif /* LWIP_TCP */
-  default:
-    /* Unsupported netconn type, e.g. protocol disabled */
-    msg->err = ERR_VAL;
-    break;
-  }
-}
-
-/**
- * Create a new pcb of a specific type inside a netconn.
- * Called from netconn_new_with_proto_and_callback.
- *
- * @param msg the api_msg_msg describing the connection type
- */
-void
-do_newconn(struct api_msg_msg *msg)
-{
-  msg->err = ERR_OK;
-  if(msg->conn->pcb.tcp == NULL) {
-    pcb_new(msg);
-  }
-  /* Else? This "new" connection already has a PCB allocated. */
-  /* Is this an error condition? Should it be deleted? */
-  /* We currently just are happy and return. */
-
-  TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Create a new netconn (of a specific type) that has a callback function.
- * The corresponding pcb is NOT created!
- *
- * @param t the type of 'connection' to create (@see enum netconn_type)
- * @param proto the IP protocol for RAW IP pcbs
- * @param callback a function to call on status changes (RX available, TX'ed)
- * @return a newly allocated struct netconn or
- *         NULL on memory error
- */
-struct netconn*
-netconn_alloc(enum netconn_type t, netconn_callback callback)
-{
-  struct netconn *conn;
-  int size;
-
-  conn = (struct netconn *)memp_malloc(MEMP_NETCONN);
-  if (conn == NULL) {
-    return NULL;
-  }
-
-  conn->last_err = ERR_OK;
-  conn->type = t;
-  conn->pcb.tcp = NULL;
-
-#if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \
-    (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE)
-  size = DEFAULT_RAW_RECVMBOX_SIZE;
-#else
-  switch(NETCONNTYPE_GROUP(t)) {
-#if LWIP_RAW
-  case NETCONN_RAW:
-    size = DEFAULT_RAW_RECVMBOX_SIZE;
-    break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
-  case NETCONN_UDP:
-    size = DEFAULT_UDP_RECVMBOX_SIZE;
-    break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-  case NETCONN_TCP:
-    size = DEFAULT_TCP_RECVMBOX_SIZE;
-    break;
-#endif /* LWIP_TCP */
-  default:
-    LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0);
-    break;
-  }
-#endif
-
-  if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) {
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-  if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) {
-    sys_sem_free(&conn->op_completed);
-    memp_free(MEMP_NETCONN, conn);
-    return NULL;
-  }
-
-#if LWIP_TCP
-  sys_mbox_set_invalid(&conn->acceptmbox);
-#endif
-  conn->state        = NETCONN_NONE;
-#if LWIP_SOCKET
-  /* initialize socket to -1 since 0 is a valid socket */
-  conn->socket       = -1;
-#endif /* LWIP_SOCKET */
-  conn->callback     = callback;
-#if LWIP_TCP
-  conn->current_msg  = NULL;
-  conn->write_offset = 0;
-#endif /* LWIP_TCP */
-#if LWIP_SO_RCVTIMEO
-  conn->recv_timeout = 0;
-#endif /* LWIP_SO_RCVTIMEO */
-#if LWIP_SO_RCVBUF
-  conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
-  conn->recv_avail   = 0;
-#endif /* LWIP_SO_RCVBUF */
-  conn->flags = 0;
-  return conn;
-}
-
-/**
- * Delete a netconn and all its resources.
- * The pcb is NOT freed (since we might not be in the right thread context do this).
- *
- * @param conn the netconn to free
- */
-void
-netconn_free(struct netconn *conn)
-{
-  LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
-  LWIP_ASSERT("recvmbox must be deallocated before calling this function",
-    !sys_mbox_valid(&conn->recvmbox));
-#if LWIP_TCP
-  LWIP_ASSERT("acceptmbox must be deallocated before calling this function",
-    !sys_mbox_valid(&conn->acceptmbox));
-#endif /* LWIP_TCP */
-
-  sys_sem_free(&conn->op_completed);
-  sys_sem_set_invalid(&conn->op_completed);
-
-  memp_free(MEMP_NETCONN, conn);
-}
-
-/**
- * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in
- * these mboxes
- *
- * @param conn the netconn to free
- * @bytes_drained bytes drained from recvmbox
- * @accepts_drained pending connections drained from acceptmbox
- */
-static void
-netconn_drain(struct netconn *conn)
-{
-  void *mem;
-#if LWIP_TCP
-  struct pbuf *p;
-#endif /* LWIP_TCP */
-
-  /* This runs in tcpip_thread, so we don't need to lock against rx packets */
-
-  /* Delete and drain the recvmbox. */
-  if (sys_mbox_valid(&conn->recvmbox)) {
-    while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) {
-#if LWIP_TCP
-      if (conn->type == NETCONN_TCP) {
-        if(mem != NULL) {
-          p = (struct pbuf*)mem;
-          /* pcb might be set to NULL already by err_tcp() */
-          if (conn->pcb.tcp != NULL) {
-            tcp_recved(conn->pcb.tcp, p->tot_len);
-          }
-          pbuf_free(p);
-        }
-      } else
-#endif /* LWIP_TCP */
-      {
-        netbuf_delete((struct netbuf *)mem);
-      }
-    }
-    sys_mbox_free(&conn->recvmbox);
-    sys_mbox_set_invalid(&conn->recvmbox);
-  }
-
-  /* Delete and drain the acceptmbox. */
-#if LWIP_TCP
-  if (sys_mbox_valid(&conn->acceptmbox)) {
-    while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) {
-      struct netconn *newconn = (struct netconn *)mem;
-      /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
-      /* pcb might be set to NULL already by err_tcp() */
-      if (conn->pcb.tcp != NULL) {
-        tcp_accepted(conn->pcb.tcp);
-      }
-      /* drain recvmbox */
-      netconn_drain(newconn);
-      if (newconn->pcb.tcp != NULL) {
-        tcp_abort(newconn->pcb.tcp);
-        newconn->pcb.tcp = NULL;
-      }
-      netconn_free(newconn);
-    }
-    sys_mbox_free(&conn->acceptmbox);
-    sys_mbox_set_invalid(&conn->acceptmbox);
-  }
-#endif /* LWIP_TCP */
-}
-
-#if LWIP_TCP
-/**
- * Internal helper function to close a TCP netconn: since this sometimes
- * doesn't work at the first attempt, this function is called from multiple
- * places.
- *
- * @param conn the TCP netconn to close
- */
-static void
-do_close_internal(struct netconn *conn)
-{
-  err_t err;
-  u8_t shut, shut_rx, shut_tx, close;
-
-  LWIP_ASSERT("invalid conn", (conn != NULL));
-  LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
-  LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
-  LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
-  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
-
-  shut = conn->current_msg->msg.sd.shut;
-  shut_rx = shut & NETCONN_SHUT_RD;
-  shut_tx = shut & NETCONN_SHUT_WR;
-  /* shutting down both ends is the same as closing */
-  close = shut == NETCONN_SHUT_RDWR;
-
-  /* Set back some callback pointers */
-  if (close) {
-    tcp_arg(conn->pcb.tcp, NULL);
-  }
-  if (conn->pcb.tcp->state == LISTEN) {
-    tcp_accept(conn->pcb.tcp, NULL);
-  } else {
-    /* some callbacks have to be reset if tcp_close is not successful */
-    if (shut_rx) {
-      tcp_recv(conn->pcb.tcp, NULL);
-      tcp_accept(conn->pcb.tcp, NULL);
-    }
-    if (shut_tx) {
-      tcp_sent(conn->pcb.tcp, NULL);
-    }
-    if (close) {
-      tcp_poll(conn->pcb.tcp, NULL, 4);
-      tcp_err(conn->pcb.tcp, NULL);
-    }
-  }
-  /* Try to close the connection */
-  if (shut == NETCONN_SHUT_RDWR) {
-    err = tcp_close(conn->pcb.tcp);
-  } else {
-    err = tcp_shutdown(conn->pcb.tcp, shut & NETCONN_SHUT_RD, shut & NETCONN_SHUT_WR);
-  }
-  if (err == ERR_OK) {
-    /* Closing succeeded */
-    conn->current_msg->err = ERR_OK;
-    conn->current_msg = NULL;
-    conn->state = NETCONN_NONE;
-    /* Set back some callback pointers as conn is going away */
-    conn->pcb.tcp = NULL;
-    /* Trigger select() in socket layer. Make sure everybody notices activity
-       on the connection, error first! */
-    if (close) {
-      API_EVENT(conn, NETCONN_EVT_ERROR, 0);
-    }
-    if (shut_rx) {
-      API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
-    }
-    if (shut_tx) {
-      API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
-    }
-    /* wake up the application task */
-    sys_sem_signal(&conn->op_completed);
-  } else {
-    /* Closing failed, restore some of the callbacks */
-    /* Closing of listen pcb will never fail! */
-    LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN));
-    tcp_sent(conn->pcb.tcp, sent_tcp);
-    tcp_poll(conn->pcb.tcp, poll_tcp, 4);
-    tcp_err(conn->pcb.tcp, err_tcp);
-    tcp_arg(conn->pcb.tcp, conn);
-    /* don't restore recv callback: we don't want to receive any more data */
-  }
-  /* If closing didn't succeed, we get called again either
-     from poll_tcp or from sent_tcp */
-}
-#endif /* LWIP_TCP */
-
-/**
- * Delete the pcb inside a netconn.
- * Called from netconn_delete.
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_delconn(struct api_msg_msg *msg)
-{
-  /* @todo TCP: abort running write/connect? */
- if ((msg->conn->state != NETCONN_NONE) &&
-     (msg->conn->state != NETCONN_LISTEN) &&
-     (msg->conn->state != NETCONN_CONNECT)) {
-    /* this only happens for TCP netconns */
-    LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP);
-    msg->err = ERR_INPROGRESS;
-  } else {
-    LWIP_ASSERT("blocking connect in progress",
-      (msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
-    /* Drain and delete mboxes */
-    netconn_drain(msg->conn);
-
-    if (msg->conn->pcb.tcp != NULL) {
-
-      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
-      case NETCONN_RAW:
-        raw_remove(msg->conn->pcb.raw);
-        break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
-      case NETCONN_UDP:
-        msg->conn->pcb.udp->recv_arg = NULL;
-        udp_remove(msg->conn->pcb.udp);
-        break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-      case NETCONN_TCP:
-        LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
-          msg->conn->write_offset == 0);
-        msg->conn->state = NETCONN_CLOSE;
-        msg->msg.sd.shut = NETCONN_SHUT_RDWR;
-        msg->conn->current_msg = msg;
-        do_close_internal(msg->conn);
-        /* API_EVENT is called inside do_close_internal, before releasing
-           the application thread, so we can return at this point! */
-        return;
-#endif /* LWIP_TCP */
-      default:
-        break;
-      }
-      msg->conn->pcb.tcp = NULL;
-    }
-    /* tcp netconns don't come here! */
-
-    /* @todo: this lets select make the socket readable and writable,
-       which is wrong! errfd instead? */
-    API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
-    API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
-  }
-  if (sys_sem_valid(&msg->conn->op_completed)) {
-    sys_sem_signal(&msg->conn->op_completed);
-  }
-}
-
-/**
- * Bind a pcb contained in a netconn
- * Called from netconn_bind.
- *
- * @param msg the api_msg_msg pointing to the connection and containing
- *            the IP address and port to bind to
- */
-void
-do_bind(struct api_msg_msg *msg)
-{
-  if (ERR_IS_FATAL(msg->conn->last_err)) {
-    msg->err = msg->conn->last_err;
-  } else {
-    msg->err = ERR_VAL;
-    if (msg->conn->pcb.tcp != NULL) {
-      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
-      case NETCONN_RAW:
-        msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
-        break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
-      case NETCONN_UDP:
-        msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
-        break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-      case NETCONN_TCP:
-        msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
-        break;
-#endif /* LWIP_TCP */
-      default:
-        break;
-      }
-    }
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-
-#if LWIP_TCP
-/**
- * TCP callback function if a connection (opened by tcp_connect/do_connect) has
- * been established (or reset by the remote host).
- *
- * @see tcp.h (struct tcp_pcb.connected) for parameters and return values
- */
-static err_t
-do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
-{
-  struct netconn *conn;
-  int was_blocking;
-
-  LWIP_UNUSED_ARG(pcb);
-
-  conn = (struct netconn *)arg;
-
-  if (conn == NULL) {
-    return ERR_VAL;
-  }
-
-  LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
-  LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect",
-    (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn));
-
-  if (conn->current_msg != NULL) {
-    conn->current_msg->err = err;
-  }
-  if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) {
-    setup_tcp(conn);
-  }
-  was_blocking = !IN_NONBLOCKING_CONNECT(conn);
-  SET_NONBLOCKING_CONNECT(conn, 0);
-  conn->current_msg = NULL;
-  conn->state = NETCONN_NONE;
-  if (!was_blocking) {
-    NETCONN_SET_SAFE_ERR(conn, ERR_OK);
-  }
-  API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
-
-  if (was_blocking) {
-    sys_sem_signal(&conn->op_completed);
-  }
-  return ERR_OK;
-}
-#endif /* LWIP_TCP */
-
-/**
- * Connect a pcb contained inside a netconn
- * Called from netconn_connect.
- *
- * @param msg the api_msg_msg pointing to the connection and containing
- *            the IP address and port to connect to
- */
-void
-do_connect(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.tcp == NULL) {
-    /* This may happen when calling netconn_connect() a second time */
-    msg->err = ERR_CLSD;
-  } else {
-    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
-  case NETCONN_RAW:
-    msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
-    break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
-  case NETCONN_UDP:
-    msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
-    break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-  case NETCONN_TCP:
-    /* Prevent connect while doing any other action. */
-    if (msg->conn->state != NETCONN_NONE) {
-      msg->err = ERR_ISCONN;
-    } else {
-      setup_tcp(msg->conn);
-      msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr,
-        msg->msg.bc.port, do_connected);
-      if (msg->err == ERR_OK) {
-        u8_t non_blocking = netconn_is_nonblocking(msg->conn);
-        msg->conn->state = NETCONN_CONNECT;
-        SET_NONBLOCKING_CONNECT(msg->conn, non_blocking);
-        if (non_blocking) {
-          msg->err = ERR_INPROGRESS;
-        } else {
-          msg->conn->current_msg = msg;
-          /* sys_sem_signal() is called from do_connected (or err_tcp()),
-          * when the connection is established! */
-          return;
-        }
-      }
-    }
-    break;
-#endif /* LWIP_TCP */
-  default:
-    LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0));
-    break;
-    }
-  }
-  sys_sem_signal(&msg->conn->op_completed);
-}
-
-/**
- * Connect a pcb contained inside a netconn
- * Only used for UDP netconns.
- * Called from netconn_disconnect.
- *
- * @param msg the api_msg_msg pointing to the connection to disconnect
- */
-void
-do_disconnect(struct api_msg_msg *msg)
-{
-#if LWIP_UDP
-  if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
-    udp_disconnect(msg->conn->pcb.udp);
-    msg->err = ERR_OK;
-  } else
-#endif /* LWIP_UDP */
-  {
-    msg->err = ERR_VAL;
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-
-#if LWIP_TCP
-/**
- * Set a TCP pcb contained in a netconn into listen mode
- * Called from netconn_listen.
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_listen(struct api_msg_msg *msg)
-{
-  if (ERR_IS_FATAL(msg->conn->last_err)) {
-    msg->err = msg->conn->last_err;
-  } else {
-    msg->err = ERR_CONN;
-    if (msg->conn->pcb.tcp != NULL) {
-      if (msg->conn->type == NETCONN_TCP) {
-        if (msg->conn->state == NETCONN_NONE) {
-#if TCP_LISTEN_BACKLOG
-          struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
-#else  /* TCP_LISTEN_BACKLOG */
-          struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
-#endif /* TCP_LISTEN_BACKLOG */
-          if (lpcb == NULL) {
-            /* in this case, the old pcb is still allocated */
-            msg->err = ERR_MEM;
-          } else {
-            /* delete the recvmbox and allocate the acceptmbox */
-            if (sys_mbox_valid(&msg->conn->recvmbox)) {
-              /** @todo: should we drain the recvmbox here? */
-              sys_mbox_free(&msg->conn->recvmbox);
-              sys_mbox_set_invalid(&msg->conn->recvmbox);
-            }
-            msg->err = ERR_OK;
-            if (!sys_mbox_valid(&msg->conn->acceptmbox)) {
-              msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE);
-            }
-            if (msg->err == ERR_OK) {
-              msg->conn->state = NETCONN_LISTEN;
-              msg->conn->pcb.tcp = lpcb;
-              tcp_arg(msg->conn->pcb.tcp, msg->conn);
-              tcp_accept(msg->conn->pcb.tcp, accept_function);
-            } else {
-              /* since the old pcb is already deallocated, free lpcb now */
-              tcp_close(lpcb);
-              msg->conn->pcb.tcp = NULL;
-            }
-          }
-        }
-      }
-    }
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-#endif /* LWIP_TCP */
-
-/**
- * Send some data on a RAW or UDP pcb contained in a netconn
- * Called from netconn_send
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_send(struct api_msg_msg *msg)
-{
-  if (ERR_IS_FATAL(msg->conn->last_err)) {
-    msg->err = msg->conn->last_err;
-  } else {
-    msg->err = ERR_CONN;
-    if (msg->conn->pcb.tcp != NULL) {
-      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
-      case NETCONN_RAW:
-        if (ip_addr_isany(&msg->msg.b->addr)) {
-          msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
-        } else {
-          msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr);
-        }
-        break;
-#endif
-#if LWIP_UDP
-      case NETCONN_UDP:
-#if LWIP_CHECKSUM_ON_COPY
-        if (ip_addr_isany(&msg->msg.b->addr)) {
-          msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p,
-            msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
-        } else {
-          msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,
-            &msg->msg.b->addr, msg->msg.b->port,
-            msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
-        }
-#else /* LWIP_CHECKSUM_ON_COPY */
-        if (ip_addr_isany(&msg->msg.b->addr)) {
-          msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
-        } else {
-          msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port);
-        }
-#endif /* LWIP_CHECKSUM_ON_COPY */
-        break;
-#endif /* LWIP_UDP */
-      default:
-        break;
-      }
-    }
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-
-#if LWIP_TCP
-/**
- * Indicate data has been received from a TCP pcb contained in a netconn
- * Called from netconn_recv
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_recv(struct api_msg_msg *msg)
-{
-  msg->err = ERR_OK;
-  if (msg->conn->pcb.tcp != NULL) {
-    if (msg->conn->type == NETCONN_TCP) {
-#if TCP_LISTEN_BACKLOG
-      if (msg->conn->pcb.tcp->state == LISTEN) {
-        tcp_accepted(msg->conn->pcb.tcp);
-      } else
-#endif /* TCP_LISTEN_BACKLOG */
-      {
-        u32_t remaining = msg->msg.r.len;
-        do {
-          u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining;
-          tcp_recved(msg->conn->pcb.tcp, recved);
-          remaining -= recved;
-        }while(remaining != 0);
-      }
-    }
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * See if more data needs to be written from a previous call to netconn_write.
- * Called initially from do_write. If the first call can't send all data
- * (because of low memory or empty send-buffer), this function is called again
- * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the
- * blocking application thread (waiting in netconn_write) is released.
- *
- * @param conn netconn (that is currently in state NETCONN_WRITE) to process
- * @return ERR_OK
- *         ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
- */
-static err_t
-do_writemore(struct netconn *conn)
-{
-  err_t err = ERR_OK;
-  void *dataptr;
-  u16_t len, available;
-  u8_t write_finished = 0;
-  size_t diff;
-  u8_t dontblock = netconn_is_nonblocking(conn) ||
-       (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK);
-  u8_t apiflags = conn->current_msg->msg.w.apiflags;
-
-  LWIP_ASSERT("conn != NULL", conn != NULL);
-  LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
-  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
-  LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
-  LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len",
-    conn->write_offset < conn->current_msg->msg.w.len);
-
-  dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
-  diff = conn->current_msg->msg.w.len - conn->write_offset;
-  if (diff > 0xffffUL) { /* max_u16_t */
-    len = 0xffff;
-#if LWIP_TCPIP_CORE_LOCKING
-    conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
-#endif
-    apiflags |= TCP_WRITE_FLAG_MORE;
-  } else {
-    len = (u16_t)diff;
-  }
-  available = tcp_sndbuf(conn->pcb.tcp);
-  if (available < len) {
-    /* don't try to write more than sendbuf */
-    len = available;
-#if LWIP_TCPIP_CORE_LOCKING
-    conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
-#endif
-    apiflags |= TCP_WRITE_FLAG_MORE;
-  }
-  if (dontblock && (len < conn->current_msg->msg.w.len)) {
-    /* failed to send all data at once -> nonblocking write not possible */
-    err = ERR_MEM;
-  }
-  if (err == ERR_OK) {
-    LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));
-    err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
-  }
-  if (dontblock && (err == ERR_MEM)) {
-    /* nonblocking write failed */
-    write_finished = 1;
-    err = ERR_WOULDBLOCK;
-    /* let poll_tcp check writable space to mark the pcb
-       writable again */
-    conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
-    /* let select mark this pcb as non-writable. */
-    API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
-  } else {
-    /* if OK or memory error, check available space */
-    if (((err == ERR_OK) || (err == ERR_MEM)) &&
-        ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
-         (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT))) {
-      /* The queued byte- or pbuf-count exceeds the configured low-water limit,
-         let select mark this pcb as non-writable. */
-      API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
-    }
-
-    if (err == ERR_OK) {
-      conn->write_offset += len;
-      if (conn->write_offset == conn->current_msg->msg.w.len) {
-        /* everything was written */
-        write_finished = 1;
-        conn->write_offset = 0;
-      }
-      tcp_output(conn->pcb.tcp);
-    } else if (err == ERR_MEM) {
-      /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
-         we do NOT return to the application thread, since ERR_MEM is
-         only a temporary error! */
-
-      /* tcp_write returned ERR_MEM, try tcp_output anyway */
-      tcp_output(conn->pcb.tcp);
-
-  #if LWIP_TCPIP_CORE_LOCKING
-      conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
-  #endif
-    } else {
-      /* On errors != ERR_MEM, we don't try writing any more but return
-         the error to the application thread. */
-      write_finished = 1;
-    }
-  }
-
-  if (write_finished) {
-    /* everything was written: set back connection state
-       and back to application task */
-    conn->current_msg->err = err;
-    conn->current_msg = NULL;
-    conn->state = NETCONN_NONE;
-#if LWIP_TCPIP_CORE_LOCKING
-    if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0)
-#endif
-    {
-      sys_sem_signal(&conn->op_completed);
-    }
-  }
-#if LWIP_TCPIP_CORE_LOCKING
-  else
-    return ERR_MEM;
-#endif
-  return ERR_OK;
-}
-#endif /* LWIP_TCP */
-
-/**
- * Send some data on a TCP pcb contained in a netconn
- * Called from netconn_write
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_write(struct api_msg_msg *msg)
-{
-  if (ERR_IS_FATAL(msg->conn->last_err)) {
-    msg->err = msg->conn->last_err;
-  } else {
-    if (msg->conn->type == NETCONN_TCP) {
-#if LWIP_TCP
-      if (msg->conn->state != NETCONN_NONE) {
-        /* netconn is connecting, closing or in blocking write */
-        msg->err = ERR_INPROGRESS;
-      } else if (msg->conn->pcb.tcp != NULL) {
-        msg->conn->state = NETCONN_WRITE;
-        /* set all the variables used by do_writemore */
-        LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
-          msg->conn->write_offset == 0);
-        LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0);
-        msg->conn->current_msg = msg;
-        msg->conn->write_offset = 0;
-#if LWIP_TCPIP_CORE_LOCKING
-        msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
-        if (do_writemore(msg->conn) != ERR_OK) {
-          LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
-          UNLOCK_TCPIP_CORE();
-          sys_arch_sem_wait(&msg->conn->op_completed, 0);
-          LOCK_TCPIP_CORE();
-          LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
-        }
-#else /* LWIP_TCPIP_CORE_LOCKING */
-        do_writemore(msg->conn);
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-        /* for both cases: if do_writemore was called, don't ACK the APIMSG
-           since do_writemore ACKs it! */
-        return;
-      } else {
-        msg->err = ERR_CONN;
-      }
-#else /* LWIP_TCP */
-      msg->err = ERR_VAL;
-#endif /* LWIP_TCP */
-#if (LWIP_UDP || LWIP_RAW)
-    } else {
-      msg->err = ERR_VAL;
-#endif /* (LWIP_UDP || LWIP_RAW) */
-    }
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Return a connection's local or remote address
- * Called from netconn_getaddr
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_getaddr(struct api_msg_msg *msg)
-{
-  if (msg->conn->pcb.ip != NULL) {
-    *(msg->msg.ad.ipaddr) = (msg->msg.ad.local ? msg->conn->pcb.ip->local_ip :
-                             msg->conn->pcb.ip->remote_ip);
-
-    msg->err = ERR_OK;
-    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
-    case NETCONN_RAW:
-      if (msg->msg.ad.local) {
-        *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
-      } else {
-        /* return an error as connecting is only a helper for upper layers */
-        msg->err = ERR_CONN;
-      }
-      break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
-    case NETCONN_UDP:
-      if (msg->msg.ad.local) {
-        *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
-      } else {
-        if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
-          msg->err = ERR_CONN;
-        } else {
-          *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
-        }
-      }
-      break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
-    case NETCONN_TCP:
-      *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port);
-      break;
-#endif /* LWIP_TCP */
-    default:
-      LWIP_ASSERT("invalid netconn_type", 0);
-      break;
-    }
-  } else {
-    msg->err = ERR_CONN;
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Close a TCP pcb contained in a netconn
- * Called from netconn_close
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_close(struct api_msg_msg *msg)
-{
-#if LWIP_TCP
-  /* @todo: abort running write/connect? */
-  if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) {
-    /* this only happens for TCP netconns */
-    LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP);
-    msg->err = ERR_INPROGRESS;
-  } else if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
-    if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) {
-      /* LISTEN doesn't support half shutdown */
-      msg->err = ERR_CONN;
-    } else {
-      if (msg->msg.sd.shut & NETCONN_SHUT_RD) {
-        /* Drain and delete mboxes */
-        netconn_drain(msg->conn);
-      }
-      LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
-        msg->conn->write_offset == 0);
-      msg->conn->state = NETCONN_CLOSE;
-      msg->conn->current_msg = msg;
-      do_close_internal(msg->conn);
-      /* for tcp netconns, do_close_internal ACKs the message */
-      return;
-    }
-  } else
-#endif /* LWIP_TCP */
-  {
-    msg->err = ERR_VAL;
-  }
-  sys_sem_signal(&msg->conn->op_completed);
-}
-
-#if LWIP_IGMP
-/**
- * Join multicast groups for UDP netconns.
- * Called from netconn_join_leave_group
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_join_leave_group(struct api_msg_msg *msg)
-{ 
-  if (ERR_IS_FATAL(msg->conn->last_err)) {
-    msg->err = msg->conn->last_err;
-  } else {
-    if (msg->conn->pcb.tcp != NULL) {
-      if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
-#if LWIP_UDP
-        if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
-          msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr);
-        } else {
-          msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr);
-        }
-#endif /* LWIP_UDP */
-#if (LWIP_TCP || LWIP_RAW)
-      } else {
-        msg->err = ERR_VAL;
-#endif /* (LWIP_TCP || LWIP_RAW) */
-      }
-    } else {
-      msg->err = ERR_CONN;
-    }
-  }
-  TCPIP_APIMSG_ACK(msg);
-}
-#endif /* LWIP_IGMP */
-
-#if LWIP_DNS
-/**
- * Callback function that is called when DNS name is resolved
- * (or on timeout). A waiting application thread is waked up by
- * signaling the semaphore.
- */
-static void
-do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
-{
-  struct dns_api_msg *msg = (struct dns_api_msg*)arg;
-
-  LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0);
-  LWIP_UNUSED_ARG(name);
-
-  if (ipaddr == NULL) {
-    /* timeout or memory error */
-    *msg->err = ERR_VAL;
-  } else {
-    /* address was resolved */
-    *msg->err = ERR_OK;
-    *msg->addr = *ipaddr;
-  }
-  /* wake up the application task waiting in netconn_gethostbyname */
-  sys_sem_signal(msg->sem);
-}
-
-/**
- * Execute a DNS query
- * Called from netconn_gethostbyname
- *
- * @param arg the dns_api_msg pointing to the query
- */
-void
-do_gethostbyname(void *arg)
-{
-  struct dns_api_msg *msg = (struct dns_api_msg*)arg;
-
-  *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg);
-  if (*msg->err != ERR_INPROGRESS) {
-    /* on error or immediate success, wake up the application
-     * task waiting in netconn_gethostbyname */
-    sys_sem_signal(msg->sem);
-  }
-}
-#endif /* LWIP_DNS */
-
-#endif /* LWIP_NETCONN */

+ 0 - 75
components/net/lwip/src/api/err.c

@@ -1,75 +0,0 @@
-/**
- * @file
- * Error Management module
- *
- */
-
-/*
- * Copyright (c) 2001-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. 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 lwIP TCP/IP stack.
- * 
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/err.h"
-
-#ifdef LWIP_DEBUG
-
-static const char *err_strerr[] = {
-           "Ok.",                    /* ERR_OK          0  */
-           "Out of memory error.",   /* ERR_MEM        -1  */
-           "Buffer error.",          /* ERR_BUF        -2  */
-           "Timeout.",               /* ERR_TIMEOUT    -3  */
-           "Routing problem.",       /* ERR_RTE        -4  */
-           "Operation in progress.", /* ERR_INPROGRESS -5  */
-           "Illegal value.",         /* ERR_VAL        -6  */
-           "Operation would block.", /* ERR_WOULDBLOCK -7  */
-           "Address in use.",        /* ERR_USE        -8  */
-           "Already connected.",     /* ERR_ISCONN     -9  */
-           "Connection aborted.",    /* ERR_ABRT       -10 */
-           "Connection reset.",      /* ERR_RST        -11 */
-           "Connection closed.",     /* ERR_CLSD       -12 */
-           "Not connected.",         /* ERR_CONN       -13 */
-           "Illegal argument.",      /* ERR_ARG        -14 */
-           "Low-level netif error.", /* ERR_IF         -15 */
-};
-
-/**
- * Convert an lwip internal error to a string representation.
- *
- * @param err an lwip internal err_t
- * @return a string representation for err
- */
-const char *
-lwip_strerr(err_t err)
-{
-  return err_strerr[-err];
-
-}
-
-#endif /* LWIP_DEBUG */

+ 0 - 245
components/net/lwip/src/api/netbuf.c

@@ -1,245 +0,0 @@
-/**
- * @file
- * Network buffer management
- *
- */
- 
-/*
- * Copyright (c) 2001-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. 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 lwIP TCP/IP stack.
- * 
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/netbuf.h"
-#include "lwip/memp.h"
-
-#include <string.h>
-
-/**
- * Create (allocate) and initialize a new netbuf.
- * The netbuf doesn't yet contain a packet buffer!
- *
- * @return a pointer to a new netbuf
- *         NULL on lack of memory
- */
-struct
-netbuf *netbuf_new(void)
-{
-  struct netbuf *buf;
-
-  buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
-  if (buf != NULL) {
-    buf->p = NULL;
-    buf->ptr = NULL;
-    ip_addr_set_any(&buf->addr);
-    buf->port = 0;
-#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY
-#if LWIP_CHECKSUM_ON_COPY
-    buf->flags = 0;
-#endif /* LWIP_CHECKSUM_ON_COPY */
-    buf->toport_chksum = 0;
-#if LWIP_NETBUF_RECVINFO
-    ip_addr_set_any(&buf->toaddr);
-#endif /* LWIP_NETBUF_RECVINFO */
-#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */
-    return buf;
-  } else {
-    return NULL;
-  }
-}
-
-/**
- * Deallocate a netbuf allocated by netbuf_new().
- *
- * @param buf pointer to a netbuf allocated by netbuf_new()
- */
-void
-netbuf_delete(struct netbuf *buf)
-{
-  if (buf != NULL) {
-    if (buf->p != NULL) {
-      pbuf_free(buf->p);
-      buf->p = buf->ptr = NULL;
-    }
-    memp_free(MEMP_NETBUF, buf);
-  }
-}
-
-/**
- * Allocate memory for a packet buffer for a given netbuf.
- *
- * @param buf the netbuf for which to allocate a packet buffer
- * @param size the size of the packet buffer to allocate
- * @return pointer to the allocated memory
- *         NULL if no memory could be allocated
- */
-void *
-netbuf_alloc(struct netbuf *buf, u16_t size)
-{
-  LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
-
-  /* Deallocate any previously allocated memory. */
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
-  if (buf->p == NULL) {
-     return NULL;
-  }
-  LWIP_ASSERT("check that first pbuf can hold size",
-             (buf->p->len >= size));
-  buf->ptr = buf->p;
-  return buf->p->payload;
-}
-
-/**
- * Free the packet buffer included in a netbuf
- *
- * @param buf pointer to the netbuf which contains the packet buffer to free
- */
-void
-netbuf_free(struct netbuf *buf)
-{
-  LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = buf->ptr = NULL;
-}
-
-/**
- * Let a netbuf reference existing (non-volatile) data.
- *
- * @param buf netbuf which should reference the data
- * @param dataptr pointer to the data to reference
- * @param size size of the data
- * @return ERR_OK if data is referenced
- *         ERR_MEM if data couldn't be referenced due to lack of memory
- */
-err_t
-netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size)
-{
-  LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;);
-  if (buf->p != NULL) {
-    pbuf_free(buf->p);
-  }
-  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
-  if (buf->p == NULL) {
-    buf->ptr = NULL;
-    return ERR_MEM;
-  }
-  buf->p->payload = (void*)dataptr;
-  buf->p->len = buf->p->tot_len = size;
-  buf->ptr = buf->p;
-  return ERR_OK;
-}
-
-/**
- * Chain one netbuf to another (@see pbuf_chain)
- *
- * @param head the first netbuf
- * @param tail netbuf to chain after head, freed by this function, may not be reference after returning
- */
-void
-netbuf_chain(struct netbuf *head, struct netbuf *tail)
-{
-  LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;);
-  LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;);
-  pbuf_cat(head->p, tail->p);
-  head->ptr = head->p;
-  memp_free(MEMP_NETBUF, tail);
-}
-
-/**
- * Get the data pointer and length of the data inside a netbuf.
- *
- * @param buf netbuf to get the data from
- * @param dataptr pointer to a void pointer where to store the data pointer
- * @param len pointer to an u16_t where the length of the data is stored
- * @return ERR_OK if the information was retreived,
- *         ERR_BUF on error.
- */
-err_t
-netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
-{
-  LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;);
-  LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
-  LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;);
-
-  if (buf->ptr == NULL) {
-    return ERR_BUF;
-  }
-  *dataptr = buf->ptr->payload;
-  *len = buf->ptr->len;
-  return ERR_OK;
-}
-
-/**
- * Move the current data pointer of a packet buffer contained in a netbuf
- * to the next part.
- * The packet buffer itself is not modified.
- *
- * @param buf the netbuf to modify
- * @return -1 if there is no next part
- *         1  if moved to the next part but now there is no next part
- *         0  if moved to the next part and there are still more parts
- */
-s8_t
-netbuf_next(struct netbuf *buf)
-{
-  LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;);
-  if (buf->ptr->next == NULL) {
-    return -1;
-  }
-  buf->ptr = buf->ptr->next;
-  if (buf->ptr->next == NULL) {
-    return 1;
-  }
-  return 0;
-}
-
-/**
- * Move the current data pointer of a packet buffer contained in a netbuf
- * to the beginning of the packet.
- * The packet buffer itself is not modified.
- *
- * @param buf the netbuf to modify
- */
-void
-netbuf_first(struct netbuf *buf)
-{
-  LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
-  buf->ptr = buf->p;
-}
-
-#endif /* LWIP_NETCONN */

+ 0 - 352
components/net/lwip/src/api/netdb.c

@@ -1,352 +0,0 @@
-/**
- * @file
- * API functions for name resolving
- *
- */
-
-/*
- * 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 lwIP TCP/IP stack.
- * 
- * Author: Simon Goldschmidt
- *
- */
-
-#include "lwip/netdb.h"
-
-#if LWIP_DNS && LWIP_SOCKET
-
-#include "lwip/err.h"
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-#include "lwip/ip_addr.h"
-#include "lwip/api.h"
-#include "lwip/dns.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-/** helper struct for gethostbyname_r to access the char* buffer */
-struct gethostbyname_r_helper {
-  ip_addr_t *addrs;
-  ip_addr_t addr;
-  char *aliases;
-};
-
-/** h_errno is exported in netdb.h for access by applications. */
-#if LWIP_DNS_API_DECLARE_H_ERRNO
-int h_errno;
-#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
-
-/** define "hostent" variables storage: 0 if we use a static (but unprotected)
- * set of variables for lwip_gethostbyname, 1 if we use a local storage */
-#ifndef LWIP_DNS_API_HOSTENT_STORAGE
-#define LWIP_DNS_API_HOSTENT_STORAGE 0
-#endif
-
-/** define "hostent" variables storage */
-#if LWIP_DNS_API_HOSTENT_STORAGE
-#define HOSTENT_STORAGE
-#else
-#define HOSTENT_STORAGE static
-#endif /* LWIP_DNS_API_STATIC_HOSTENT */
-
-/**
- * Returns an entry containing addresses of address family AF_INET
- * for the host with name name.
- * Due to dns_gethostbyname limitations, only one address is returned.
- *
- * @param name the hostname to resolve
- * @return an entry containing addresses of address family AF_INET
- *         for the host with name name
- */
-struct hostent*
-lwip_gethostbyname(const char *name)
-{
-  err_t err;
-  ip_addr_t addr;
-
-  /* buffer variables for lwip_gethostbyname() */
-  HOSTENT_STORAGE struct hostent s_hostent;
-  HOSTENT_STORAGE char *s_aliases;
-  HOSTENT_STORAGE ip_addr_t s_hostent_addr;
-  HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2];
-
-  /* query host IP address */
-  err = netconn_gethostbyname(name, &addr);
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
-    h_errno = HOST_NOT_FOUND;
-    return NULL;
-  }
-
-  /* fill hostent */
-  s_hostent_addr = addr;
-  s_phostent_addr[0] = &s_hostent_addr;
-  s_phostent_addr[1] = NULL;
-  s_hostent.h_name = (char*)name;
-  s_hostent.h_aliases = &s_aliases;
-  s_hostent.h_addrtype = AF_INET;
-  s_hostent.h_length = sizeof(ip_addr_t);
-  s_hostent.h_addr_list = (char**)&s_phostent_addr;
-
-#if DNS_DEBUG
-  /* dump hostent */
-  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name           == %s\n", s_hostent.h_name));
-  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases        == %p\n", s_hostent.h_aliases));
-  if (s_hostent.h_aliases != NULL) {
-    u8_t idx;
-    for ( idx=0; s_hostent.h_aliases[idx]; idx++) {
-      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]->   == %p\n", idx, s_hostent.h_aliases[idx]));
-      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]->   == %s\n", idx, s_hostent.h_aliases[idx]));
-    }
-  }
-  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype       == %d\n", s_hostent.h_addrtype));
-  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length         == %d\n", s_hostent.h_length));
-  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list      == %p\n", s_hostent.h_addr_list));
-  if (s_hostent.h_addr_list != NULL) {
-    u8_t idx;
-    for ( idx=0; s_hostent.h_addr_list[idx]; idx++) {
-      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]   == %p\n", idx, s_hostent.h_addr_list[idx]));
-      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx])));
-    }
-  }
-#endif /* DNS_DEBUG */
-
-#if LWIP_DNS_API_HOSTENT_STORAGE
-  /* this function should return the "per-thread" hostent after copy from s_hostent */
-  return sys_thread_hostent(&s_hostent);
-#else
-  return &s_hostent;
-#endif /* LWIP_DNS_API_HOSTENT_STORAGE */
-}
-
-/**
- * Thread-safe variant of lwip_gethostbyname: instead of using a static
- * buffer, this function takes buffer and errno pointers as arguments
- * and uses these for the result.
- *
- * @param name the hostname to resolve
- * @param ret pre-allocated struct where to store the result
- * @param buf pre-allocated buffer where to store additional data
- * @param buflen the size of buf
- * @param result pointer to a hostent pointer that is set to ret on success
- *               and set to zero on error
- * @param h_errnop pointer to an int where to store errors (instead of modifying
- *                 the global h_errno)
- * @return 0 on success, non-zero on error, additional error information
- *         is stored in *h_errnop instead of h_errno to be thread-safe
- */
-int
-lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
-                size_t buflen, struct hostent **result, int *h_errnop)
-{
-  err_t err;
-  struct gethostbyname_r_helper *h;
-  char *hostname;
-  size_t namelen;
-  int lh_errno;
-
-  if (h_errnop == NULL) {
-    /* ensure h_errnop is never NULL */
-    h_errnop = &lh_errno;
-  }
-
-  if (result == NULL) {
-    /* not all arguments given */
-    *h_errnop = EINVAL;
-    return -1;
-  }
-  /* first thing to do: set *result to nothing */
-  *result = NULL;
-  if ((name == NULL) || (ret == NULL) || (buf == 0)) {
-    /* not all arguments given */
-    *h_errnop = EINVAL;
-    return -1;
-  }
-
-  namelen = strlen(name);
-  if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
-    /* buf can't hold the data needed + a copy of name */
-    *h_errnop = ERANGE;
-    return -1;
-  }
-
-  h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
-  hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
-
-  /* query host IP address */
-  err = netconn_gethostbyname(name, &(h->addr));
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
-    *h_errnop = ENSRNOTFOUND;
-    return -1;
-  }
-
-  /* copy the hostname into buf */
-  MEMCPY(hostname, name, namelen);
-  hostname[namelen] = 0;
-
-  /* fill hostent */
-  h->addrs = &(h->addr);
-  h->aliases = NULL;
-  ret->h_name = (char*)hostname;
-  ret->h_aliases = &(h->aliases);
-  ret->h_addrtype = AF_INET;
-  ret->h_length = sizeof(ip_addr_t);
-  ret->h_addr_list = (char**)&(h->addrs);
-
-  /* set result != NULL */
-  *result = ret;
-
-  /* return success */
-  return 0;
-}
-
-/**
- * Frees one or more addrinfo structures returned by getaddrinfo(), along with
- * any additional storage associated with those structures. If the ai_next field
- * of the structure is not null, the entire list of structures is freed.
- *
- * @param ai struct addrinfo to free
- */
-void
-lwip_freeaddrinfo(struct addrinfo *ai)
-{
-  struct addrinfo *next;
-
-  while (ai != NULL) {
-    next = ai->ai_next;
-    memp_free(MEMP_NETDB, ai);
-    ai = next;
-  }
-}
-
-/**
- * Translates the name of a service location (for example, a host name) and/or
- * a service name and returns a set of socket addresses and associated
- * information to be used in creating a socket with which to address the
- * specified service.
- * Memory for the result is allocated internally and must be freed by calling
- * lwip_freeaddrinfo()!
- *
- * Due to a limitation in dns_gethostbyname, only the first address of a
- * host is returned.
- * Also, service names are not supported (only port numbers)!
- *
- * @param nodename descriptive name or address string of the host
- *                 (may be NULL -> local address)
- * @param servname port number as string of NULL 
- * @param hints structure containing input values that set socktype and protocol
- * @param res pointer to a pointer where to store the result (set to NULL on failure)
- * @return 0 on success, non-zero on failure
- */
-int
-lwip_getaddrinfo(const char *nodename, const char *servname,
-       const struct addrinfo *hints, struct addrinfo **res)
-{
-  err_t err;
-  ip_addr_t addr;
-  struct addrinfo *ai;
-  struct sockaddr_in *sa = NULL;
-  int port_nr = 0;
-  size_t total_size;
-  size_t namelen = 0;
-
-  if (res == NULL) {
-    return EAI_FAIL;
-  }
-  *res = NULL;
-  if ((nodename == NULL) && (servname == NULL)) {
-    return EAI_NONAME;
-  }
-
-  if (servname != NULL) {
-    /* service name specified: convert to port number
-     * @todo?: currently, only ASCII integers (port numbers) are supported! */
-    port_nr = atoi(servname);
-    if ((port_nr <= 0) || (port_nr > 0xffff)) {
-      return EAI_SERVICE;
-    }
-  }
-
-  if (nodename != NULL) {
-    /* service location specified, try to resolve */
-    err = netconn_gethostbyname(nodename, &addr);
-    if (err != ERR_OK) {
-      return EAI_FAIL;
-    }
-  } else {
-    /* service location specified, use loopback address */
-    ip_addr_set_loopback(&addr);
-  }
-
-  total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in);
-  if (nodename != NULL) {
-    namelen = strlen(nodename);
-    LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
-    total_size += namelen + 1;
-  }
-  /* If this fails, please report to lwip-devel! :-) */
-  LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
-    total_size <= NETDB_ELEM_SIZE);
-  ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
-  if (ai == NULL) {
-    goto memerr;
-  }
-  memset(ai, 0, total_size);
-  sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo));
-  /* set up sockaddr */
-  inet_addr_from_ipaddr(&sa->sin_addr, &addr);
-  sa->sin_family = AF_INET;
-  sa->sin_len = sizeof(struct sockaddr_in);
-  sa->sin_port = htons((u16_t)port_nr);
-
-  /* set up addrinfo */
-  ai->ai_family = AF_INET;
-  if (hints != NULL) {
-    /* copy socktype & protocol from hints if specified */
-    ai->ai_socktype = hints->ai_socktype;
-    ai->ai_protocol = hints->ai_protocol;
-  }
-  if (nodename != NULL) {
-    /* copy nodename to canonname if specified */
-    ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
-    MEMCPY(ai->ai_canonname, nodename, namelen);
-    ai->ai_canonname[namelen] = 0;
-  }
-  ai->ai_addrlen = sizeof(struct sockaddr_in);
-  ai->ai_addr = (struct sockaddr*)sa;
-
-  *res = ai;
-
-  return 0;
-memerr:
-  if (ai != NULL) {
-    memp_free(MEMP_NETDB, ai);
-  }
-  return EAI_MEMORY;
-}
-
-#endif /* LWIP_DNS && LWIP_SOCKET */

+ 0 - 160
components/net/lwip/src/api/netifapi.c

@@ -1,160 +0,0 @@
-/**
- * @file
- * Network Interface Sequential API module
- *
- */
-
-/*
- * 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 lwIP TCP/IP stack.
- * 
- */
-
-#include "lwip/opt.h"
-
-#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/netifapi.h"
-#include "lwip/tcpip.h"
-
-/**
- * Call netif_add() inside the tcpip_thread context.
- */
-void
-do_netifapi_netif_add(struct netifapi_msg_msg *msg)
-{
-  if (!netif_add( msg->netif,
-                  msg->msg.add.ipaddr,
-                  msg->msg.add.netmask,
-                  msg->msg.add.gw,
-                  msg->msg.add.state,
-                  msg->msg.add.init,
-                  msg->msg.add.input)) {
-    msg->err = ERR_IF;
-  } else {
-    msg->err = ERR_OK;
-  }
-  TCPIP_NETIFAPI_ACK(msg);
-}
-
-/**
- * Call netif_set_addr() inside the tcpip_thread context.
- */
-void
-do_netifapi_netif_set_addr(struct netifapi_msg_msg *msg)
-{
-  netif_set_addr( msg->netif,
-                  msg->msg.add.ipaddr,
-                  msg->msg.add.netmask,
-                  msg->msg.add.gw);
-  msg->err = ERR_OK;
-  TCPIP_NETIFAPI_ACK(msg);
-}
-
-/**
- * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
- * tcpip_thread context.
- */
-void
-do_netifapi_netif_common(struct netifapi_msg_msg *msg)
-{
-  if (msg->msg.common.errtfunc != NULL) {
-    msg->err = msg->msg.common.errtfunc(msg->netif);
-  } else {
-    msg->err = ERR_OK;
-    msg->msg.common.voidfunc(msg->netif);
-  }
-  TCPIP_NETIFAPI_ACK(msg);
-}
-
-/**
- * Call netif_add() in a thread-safe way by running that function inside the
- * tcpip_thread context.
- *
- * @note for params @see netif_add()
- */
-err_t
-netifapi_netif_add(struct netif *netif,
-                   ip_addr_t *ipaddr,
-                   ip_addr_t *netmask,
-                   ip_addr_t *gw,
-                   void *state,
-                   netif_init_fn init,
-                   netif_input_fn input)
-{
-  struct netifapi_msg msg;
-  msg.function = do_netifapi_netif_add;
-  msg.msg.netif = netif;
-  msg.msg.msg.add.ipaddr  = ipaddr;
-  msg.msg.msg.add.netmask = netmask;
-  msg.msg.msg.add.gw      = gw;
-  msg.msg.msg.add.state   = state;
-  msg.msg.msg.add.init    = init;
-  msg.msg.msg.add.input   = input;
-  TCPIP_NETIFAPI(&msg);
-  return msg.msg.err;
-}
-
-/**
- * Call netif_set_addr() in a thread-safe way by running that function inside the
- * tcpip_thread context.
- *
- * @note for params @see netif_set_addr()
- */
-err_t
-netifapi_netif_set_addr(struct netif *netif,
-                        ip_addr_t *ipaddr,
-                        ip_addr_t *netmask,
-                        ip_addr_t *gw)
-{
-  struct netifapi_msg msg;
-  msg.function = do_netifapi_netif_set_addr;
-  msg.msg.netif = netif;
-  msg.msg.msg.add.ipaddr  = ipaddr;
-  msg.msg.msg.add.netmask = netmask;
-  msg.msg.msg.add.gw      = gw;
-  TCPIP_NETIFAPI(&msg);
-  return msg.msg.err;
-}
-
-/**
- * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
- * way by running that function inside the tcpip_thread context.
- *
- * @note use only for functions where there is only "netif" parameter.
- */
-err_t
-netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
-                       netifapi_errt_fn errtfunc)
-{
-  struct netifapi_msg msg;
-  msg.function = do_netifapi_netif_common;
-  msg.msg.netif = netif;
-  msg.msg.msg.common.voidfunc = voidfunc;
-  msg.msg.msg.common.errtfunc = errtfunc;
-  TCPIP_NETIFAPI(&msg);
-  return msg.msg.err;
-}
-
-#endif /* LWIP_NETIF_API */

+ 0 - 2347
components/net/lwip/src/api/sockets.c

@@ -1,2347 +0,0 @@
-/**
- * @file
- * Sockets BSD-Like API module
- *
- */
-
-/*
- * Copyright (c) 2001-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. 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 lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>
- *
- */
-
-#include "lwip/opt.h"
-
-#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/sockets.h"
-#include "lwip/api.h"
-#include "lwip/sys.h"
-#include "lwip/igmp.h"
-#include "lwip/inet.h"
-#include "lwip/tcp.h"
-#include "lwip/raw.h"
-#include "lwip/udp.h"
-#include "lwip/tcpip.h"
-#include "lwip/pbuf.h"
-#if LWIP_CHECKSUM_ON_COPY
-#include "lwip/inet_chksum.h"
-#endif
-
-#include <string.h>
-
-#define NUM_SOCKETS MEMP_NUM_NETCONN
-
-/** Contains all internal pointers and states used for a socket */
-struct lwip_sock {
-  /** sockets currently are built on netconns, each socket has one netconn */
-  struct netconn *conn;
-  /** data that was left from the previous read */
-  void *lastdata;
-  /** offset in the data that was left from the previous read */
-  u16_t lastoffset;
-  /** number of times data was received, set by event_callback(),
-      tested by the receive and select functions */
-  s16_t rcvevent;
-  /** number of times data was ACKed (free send buffer), set by event_callback(),
-      tested by select */
-  u16_t sendevent;
-  /** error happened for this socket, set by event_callback(), tested by select */
-  u16_t errevent; 
-  /** last error that occurred on this socket */
-  int err;
-  /** counter of how many threads are waiting for this socket using select */
-  int select_waiting;
-};
-
-/** Description for a task waiting in select */
-struct lwip_select_cb {
-  /** Pointer to the next waiting task */
-  struct lwip_select_cb *next;
-  /** Pointer to the previous waiting task */
-  struct lwip_select_cb *prev;
-  /** readset passed to select */
-  fd_set *readset;
-  /** writeset passed to select */
-  fd_set *writeset;
-  /** unimplemented: exceptset passed to select */
-  fd_set *exceptset;
-  /** don't signal the same semaphore twice: set to 1 when signalled */
-  int sem_signalled;
-  /** semaphore to wake up a task waiting for select */
-  sys_sem_t sem;
-};
-
-/** This struct is used to pass data to the set/getsockopt_internal
- * functions running in tcpip_thread context (only a void* is allowed) */
-struct lwip_setgetsockopt_data {
-  /** socket struct for which to change options */
-  struct lwip_sock *sock;
-#ifdef LWIP_DEBUG
-  /** socket index for which to change options */
-  int s;
-#endif /* LWIP_DEBUG */
-  /** level of the option to process */
-  int level;
-  /** name of the option to process */
-  int optname;
-  /** set: value to set the option to
-    * get: value of the option is stored here */
-  void *optval;
-  /** size of *optval */
-  socklen_t *optlen;
-  /** if an error occures, it is temporarily stored here */
-  err_t err;
-};
-
-/** The global array of available sockets */
-static struct lwip_sock sockets[NUM_SOCKETS];
-/** The global list of tasks waiting for select */
-static struct lwip_select_cb *select_cb_list;
-/** This counter is increased from lwip_select when the list is chagned
-    and checked in event_callback to see if it has changed. */
-static volatile int select_cb_ctr;
-
-/** Table to quickly map an lwIP error (err_t) to a socket error
-  * by using -err as an index */
-static const int err_to_errno_table[] = {
-  0,             /* ERR_OK          0      No error, everything OK. */
-  ENOMEM,        /* ERR_MEM        -1      Out of memory error.     */
-  ENOBUFS,       /* ERR_BUF        -2      Buffer error.            */
-  EWOULDBLOCK,   /* ERR_TIMEOUT    -3      Timeout                  */
-  EHOSTUNREACH,  /* ERR_RTE        -4      Routing problem.         */
-  EINPROGRESS,   /* ERR_INPROGRESS -5      Operation in progress    */
-  EINVAL,        /* ERR_VAL        -6      Illegal value.           */
-  EWOULDBLOCK,   /* ERR_WOULDBLOCK -7      Operation would block.   */
-  EADDRINUSE,    /* ERR_USE        -8      Address in use.          */
-  EALREADY,      /* ERR_ISCONN     -9      Already connected.       */
-  ECONNABORTED,  /* ERR_ABRT       -10     Connection aborted.      */
-  ECONNRESET,    /* ERR_RST        -11     Connection reset.        */
-  ENOTCONN,      /* ERR_CLSD       -12     Connection closed.       */
-  ENOTCONN,      /* ERR_CONN       -13     Not connected.           */
-  EIO,           /* ERR_ARG        -14     Illegal argument.        */
-  -1,            /* ERR_IF         -15     Low-level netif error    */
-};
-
-#define ERR_TO_ERRNO_TABLE_SIZE \
-  (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0]))
-
-#define err_to_errno(err) \
-  ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \
-    err_to_errno_table[-(err)] : EIO)
-
-#ifdef ERRNO
-#ifndef set_errno
-#define set_errno(err) errno = (err)
-#endif
-#else /* ERRNO */
-#define set_errno(err)
-#endif /* ERRNO */
-
-#define sock_set_errno(sk, e) do { \
-  sk->err = (e); \
-  set_errno(sk->err); \
-} while (0)
-
-/* Forward delcaration of some functions */
-static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
-static void lwip_getsockopt_internal(void *arg);
-static void lwip_setsockopt_internal(void *arg);
-
-/**
- * Initialize this module. This function has to be called before any other
- * functions in this module!
- */
-void
-lwip_socket_init(void)
-{
-}
-
-/**
- * Map a externally used socket index to the internal socket representation.
- *
- * @param s externally used socket index
- * @return struct lwip_sock for the socket or NULL if not found
- */
-static struct lwip_sock *
-get_socket(int s)
-{
-  struct lwip_sock *sock;
-
-  if ((s < 0) || (s >= NUM_SOCKETS)) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));
-    set_errno(EBADF);
-    return NULL;
-  }
-
-  sock = &sockets[s];
-
-  if (!sock->conn) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));
-    set_errno(EBADF);
-    return NULL;
-  }
-
-  return sock;
-}
-
-/**
- * Same as get_socket but doesn't set errno
- *
- * @param s externally used socket index
- * @return struct lwip_sock for the socket or NULL if not found
- */
-static struct lwip_sock *
-tryget_socket(int s)
-{
-  if ((s < 0) || (s >= NUM_SOCKETS)) {
-    return NULL;
-  }
-  if (!sockets[s].conn) {
-    return NULL;
-  }
-  return &sockets[s];
-}
-
-/**
- * Allocate a new socket for a given netconn.
- *
- * @param newconn the netconn for which to allocate a socket
- * @param accepted 1 if socket has been created by accept(),
- *                 0 if socket has been created by socket()
- * @return the index of the new socket; -1 on error
- */
-static int
-alloc_socket(struct netconn *newconn, int accepted)
-{
-  int i;
-  SYS_ARCH_DECL_PROTECT(lev);
-
-  /* allocate a new socket identifier */
-  for (i = 0; i < NUM_SOCKETS; ++i) {
-    /* Protect socket array */
-    SYS_ARCH_PROTECT(lev);
-    if (!sockets[i].conn) {
-      sockets[i].conn       = newconn;
-      /* The socket is not yet known to anyone, so no need to protect
-         after having marked it as used. */
-      SYS_ARCH_UNPROTECT(lev);
-      sockets[i].lastdata   = NULL;
-      sockets[i].lastoffset = 0;
-      sockets[i].rcvevent   = 0;
-      /* TCP sendbuf is empty, but the socket is not yet writable until connected
-       * (unless it has been created by accept()). */
-      sockets[i].sendevent  = (newconn->type == NETCONN_TCP ? (accepted != 0) : 1);
-      sockets[i].errevent   = 0;
-      sockets[i].err        = 0;
-      sockets[i].select_waiting = 0;
-      return i;
-    }
-    SYS_ARCH_UNPROTECT(lev);
-  }
-  return -1;
-}
-
-/** Free a socket. The socket's netconn must have been
- * delete before!
- *
- * @param sock the socket to free
- * @param is_tcp != 0 for TCP sockets, used to free lastdata
- */
-static void
-free_socket(struct lwip_sock *sock, int is_tcp)
-{
-  void *lastdata;
-  SYS_ARCH_DECL_PROTECT(lev);
-
-  lastdata         = sock->lastdata;
-  sock->lastdata   = NULL;
-  sock->lastoffset = 0;
-  sock->err        = 0;
-
-  /* Protect socket array */
-  SYS_ARCH_PROTECT(lev);
-  sock->conn       = NULL;
-  SYS_ARCH_UNPROTECT(lev);
-  /* don't use 'sock' after this line, as another task might have allocated it */
-
-  if (lastdata != NULL) {
-    if (is_tcp) {
-      pbuf_free((struct pbuf *)lastdata);
-    } else {
-      netbuf_delete((struct netbuf *)lastdata);
-    }
-  }
-}
-
-/* Below this, the well-known socket functions are implemented.
- * Use google.com or opengroup.org to get a good description :-)
- *
- * Exceptions are documented!
- */
-
-int
-lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
-{
-  struct lwip_sock *sock, *nsock;
-  struct netconn *newconn;
-  ip_addr_t naddr;
-  u16_t port;
-  int newsock;
-  struct sockaddr_in sin;
-  err_t err;
-  SYS_ARCH_DECL_PROTECT(lev);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s));
-    sock_set_errno(sock, EWOULDBLOCK);
-    return -1;
-  }
-
-  /* wait for a new connection */
-  err = netconn_accept(sock->conn, &newconn);
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-  LWIP_ASSERT("newconn != NULL", newconn != NULL);
-  /* Prevent automatic window updates, we do this on our own! */
-  netconn_set_noautorecved(newconn, 1);
-
-  /* get the IP address and port of the remote host */
-  err = netconn_peer(newconn, &naddr, &port);
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
-    netconn_delete(newconn);
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  /* Note that POSIX only requires us to check addr is non-NULL. addrlen must
-   * not be NULL if addr is valid.
-   */
-  if (NULL != addr) {
-    LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL);
-    memset(&sin, 0, sizeof(sin));
-    sin.sin_len = sizeof(sin);
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(port);
-    inet_addr_from_ipaddr(&sin.sin_addr, &naddr);
-
-    if (*addrlen > sizeof(sin))
-      *addrlen = sizeof(sin);
-
-    MEMCPY(addr, &sin, *addrlen);
-  }
-
-  newsock = alloc_socket(newconn, 1);
-  if (newsock == -1) {
-    netconn_delete(newconn);
-    sock_set_errno(sock, ENFILE);
-    return -1;
-  }
-  LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS));
-  LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback);
-  nsock = &sockets[newsock];
-
-  /* See event_callback: If data comes in right away after an accept, even
-   * though the server task might not have created a new socket yet.
-   * In that case, newconn->socket is counted down (newconn->socket--),
-   * so nsock->rcvevent is >= 1 here!
-   */
-  SYS_ARCH_PROTECT(lev);
-  nsock->rcvevent += (s16_t)(-1 - newconn->socket);
-  newconn->socket = newsock;
-  SYS_ARCH_UNPROTECT(lev);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
-  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port));
-
-  sock_set_errno(sock, 0);
-  return newsock;
-}
-
-int
-lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
-{
-  struct lwip_sock *sock;
-  ip_addr_t local_addr;
-  u16_t local_port;
-  err_t err;
-  const struct sockaddr_in *name_in;
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  /* check size, familiy and alignment of 'name' */
-  LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
-             ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)),
-             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
-  name_in = (const struct sockaddr_in *)(void*)name;
-
-  inet_addr_to_ipaddr(&local_addr, &name_in->sin_addr);
-  local_port = name_in->sin_port;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, &local_addr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port)));
-
-  err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_close(int s)
-{
-  struct lwip_sock *sock;
-  int is_tcp = 0;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  if(sock->conn != NULL) {
-    is_tcp = netconn_type(sock->conn) == NETCONN_TCP;
-  } else {
-    LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL);
-  }
-
-  netconn_delete(sock->conn);
-
-  free_socket(sock, is_tcp);
-  set_errno(0);
-  return 0;
-}
-
-int
-lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
-{
-  struct lwip_sock *sock;
-  err_t err;
-  const struct sockaddr_in *name_in;
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  /* check size, familiy and alignment of 'name' */
-  LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
-             ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)),
-             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
-  name_in = (const struct sockaddr_in *)(void*)name;
-
-  if (name_in->sin_family == AF_UNSPEC) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));
-    err = netconn_disconnect(sock->conn);
-  } else {
-    ip_addr_t remote_addr;
-    u16_t remote_port;
-
-    inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr);
-    remote_port = name_in->sin_port;
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
-    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
-    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port)));
-
-    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
-  }
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-/**
- * Set a socket into listen mode.
- * The socket may not have been used for another connection previously.
- *
- * @param s the socket to set to listening mode
- * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1)
- * @return 0 on success, non-zero on failure
- */
-int
-lwip_listen(int s, int backlog)
-{
-  struct lwip_sock *sock;
-  err_t err;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  /* limit the "backlog" parameter to fit in an u8_t */
-  backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff);
-
-  err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog);
-
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
-
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_recvfrom(int s, void *mem, size_t len, int flags,
-        struct sockaddr *from, socklen_t *fromlen)
-{
-  struct lwip_sock *sock;
-  void             *buf = NULL;
-  struct pbuf      *p;
-  u16_t            buflen, copylen;
-  int              off = 0;
-  ip_addr_t        *addr;
-  u16_t            port;
-  u8_t             done = 0;
-  err_t            err;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags));
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  do {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata));
-    /* Check if there is data left from the last recv operation. */
-    if (sock->lastdata) {
-      buf = sock->lastdata;
-    } else {
-      /* If this is non-blocking call, then check first */
-      if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && 
-          (sock->rcvevent <= 0)) {
-        if (off > 0) {
-          /* update receive window */
-          netconn_recved(sock->conn, (u32_t)off);
-          /* already received data, return that */
-          sock_set_errno(sock, 0);
-          return off;
-        }
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));
-        sock_set_errno(sock, EWOULDBLOCK);
-        return -1;
-      }
-
-      /* No data was left from the previous operation, so we try to get
-         some from the network. */
-      if (netconn_type(sock->conn) == NETCONN_TCP) {
-        err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf);
-      } else {
-        err = netconn_recv(sock->conn, (struct netbuf **)&buf);
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n",
-        err, buf));
-
-      if (err != ERR_OK) {
-        if (off > 0) {
-          /* update receive window */
-          netconn_recved(sock->conn, (u32_t)off);
-          /* already received data, return that */
-          sock_set_errno(sock, 0);
-          return off;
-        }
-        /* We should really do some error checking here. */
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n",
-          s, lwip_strerr(err)));
-        sock_set_errno(sock, err_to_errno(err));
-        if (err == ERR_CLSD) {
-          return 0;
-        } else {
-          return -1;
-        }
-      }
-      LWIP_ASSERT("buf != NULL", buf != NULL);
-      sock->lastdata = buf;
-    }
-
-    if (netconn_type(sock->conn) == NETCONN_TCP) {
-      p = (struct pbuf *)buf;
-    } else {
-      p = ((struct netbuf *)buf)->p;
-    }
-    buflen = p->tot_len;
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n",
-      buflen, len, off, sock->lastoffset));
-
-    buflen -= sock->lastoffset;
-
-    if (len > buflen) {
-      copylen = buflen;
-    } else {
-      copylen = (u16_t)len;
-    }
-
-    /* copy the contents of the received buffer into
-    the supplied memory pointer mem */
-    pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset);
-
-    off += copylen;
-
-    if (netconn_type(sock->conn) == NETCONN_TCP) {
-      LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen);
-      len -= copylen;
-      if ( (len <= 0) || 
-           (p->flags & PBUF_FLAG_PUSH) || 
-           (sock->rcvevent <= 0) || 
-           ((flags & MSG_PEEK)!=0)) {
-        done = 1;
-      }
-    } else {
-      done = 1;
-    }
-
-    /* Check to see from where the data was.*/
-    if (done) {
-      ip_addr_t fromaddr;
-      if (from && fromlen) {
-        struct sockaddr_in sin;
-
-        if (netconn_type(sock->conn) == NETCONN_TCP) {
-          addr = &fromaddr;
-          netconn_getaddr(sock->conn, addr, &port, 0);
-        } else {
-          addr = netbuf_fromaddr((struct netbuf *)buf);
-          port = netbuf_fromport((struct netbuf *)buf);
-        }
-
-        memset(&sin, 0, sizeof(sin));
-        sin.sin_len = sizeof(sin);
-        sin.sin_family = AF_INET;
-        sin.sin_port = htons(port);
-        inet_addr_from_ipaddr(&sin.sin_addr, addr);
-
-        if (*fromlen > sizeof(sin)) {
-          *fromlen = sizeof(sin);
-        }
-
-        MEMCPY(from, &sin, *fromlen);
-
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
-        ip_addr_debug_print(SOCKETS_DEBUG, addr);
-        LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off));
-      } else {
-#if SOCKETS_DEBUG
-        if (netconn_type(sock->conn) == NETCONN_TCP) {
-          addr = &fromaddr;
-          netconn_getaddr(sock->conn, addr, &port, 0);
-        } else {
-          addr = netbuf_fromaddr((struct netbuf *)buf);
-          port = netbuf_fromport((struct netbuf *)buf);
-        }
-
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
-        ip_addr_debug_print(SOCKETS_DEBUG, addr);
-        LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off));
-#endif /*  SOCKETS_DEBUG */
-      }
-    }
-
-    /* If we don't peek the incoming message... */
-    if ((flags & MSG_PEEK) == 0) {
-      /* If this is a TCP socket, check if there is data left in the
-         buffer. If so, it should be saved in the sock structure for next
-         time around. */
-      if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) {
-        sock->lastdata = buf;
-        sock->lastoffset += copylen;
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf));
-      } else {
-        sock->lastdata = NULL;
-        sock->lastoffset = 0;
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf));
-        if (netconn_type(sock->conn) == NETCONN_TCP) {
-          pbuf_free((struct pbuf *)buf);
-        } else {
-          netbuf_delete((struct netbuf *)buf);
-        }
-      }
-    }
-  } while (!done);
-
-  if (off > 0) {
-    /* update receive window */
-    netconn_recved(sock->conn, (u32_t)off);
-  }
-  sock_set_errno(sock, 0);
-  return off;
-}
-
-int
-lwip_read(int s, void *mem, size_t len)
-{
-  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
-}
-
-int
-lwip_recv(int s, void *mem, size_t len, int flags)
-{
-  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
-}
-
-int
-lwip_send(int s, const void *data, size_t size, int flags)
-{
-  struct lwip_sock *sock;
-  err_t err;
-  u8_t write_flags;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n",
-                              s, data, size, flags));
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  if (sock->conn->type != NETCONN_TCP) {
-#if (LWIP_UDP || LWIP_RAW)
-    return lwip_sendto(s, data, size, flags, NULL, 0);
-#else /* (LWIP_UDP || LWIP_RAW) */
-    sock_set_errno(sock, err_to_errno(ERR_ARG));
-    return -1;
-#endif /* (LWIP_UDP || LWIP_RAW) */
-  }
-
-  if ((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) {
-    if ((size > TCP_SND_BUF) || ((size / TCP_MSS) > TCP_SND_QUEUELEN)) {
-      /* too much data to ever send nonblocking! */
-      sock_set_errno(sock, EMSGSIZE);
-      return -1;
-    }
-  }
-
-  write_flags = NETCONN_COPY |
-    ((flags & MSG_MORE)     ? NETCONN_MORE      : 0) |
-    ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
-  err = netconn_write(sock->conn, data, size, write_flags);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%"SZT_F"\n", s, err, size));
-  sock_set_errno(sock, err_to_errno(err));
-  return (err == ERR_OK ? (int)size : -1);
-}
-
-int
-lwip_sendto(int s, const void *data, size_t size, int flags,
-       const struct sockaddr *to, socklen_t tolen)
-{
-  struct lwip_sock *sock;
-  err_t err;
-  u16_t short_size;
-  const struct sockaddr_in *to_in;
-  u16_t remote_port;
-#if !LWIP_TCPIP_CORE_LOCKING
-  struct netbuf buf;
-#endif
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  if (sock->conn->type == NETCONN_TCP) {
-#if LWIP_TCP
-    return lwip_send(s, data, size, flags);
-#else /* LWIP_TCP */
-    LWIP_UNUSED_ARG(flags);
-    sock_set_errno(sock, err_to_errno(ERR_ARG));
-    return -1;
-#endif /* LWIP_TCP */
-  }
-
-  /* @todo: split into multiple sendto's? */
-  LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff);
-  short_size = (u16_t)size;
-  LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) ||
-             ((tolen == sizeof(struct sockaddr_in)) &&
-             ((to->sa_family) == AF_INET) && ((((mem_ptr_t)to) % 4) == 0))),
-             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
-  to_in = (const struct sockaddr_in *)(void*)to;
-
-#if LWIP_TCPIP_CORE_LOCKING
-  /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */
-  {
-    struct pbuf* p;
-    ip_addr_t *remote_addr;
-
-#if LWIP_NETIF_TX_SINGLE_PBUF
-    p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM);
-    if (p != NULL) {
-#if LWIP_CHECKSUM_ON_COPY
-      u16_t chksum = 0;
-      if (sock->conn->type != NETCONN_RAW) {
-        chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size);
-      } else
-#endif /* LWIP_CHECKSUM_ON_COPY */
-      MEMCPY(p->payload, data, size);
-#else /* LWIP_NETIF_TX_SINGLE_PBUF */
-    p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF);
-    if (p != NULL) {
-      p->payload = (void*)data;
-#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
-
-      if (to_in != NULL) {
-        inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr);
-        remote_port = ntohs(to_in->sin_port);
-      } else {
-        remote_addr = &sock->conn->pcb.raw->remote_ip;
-        if (sock->conn->type == NETCONN_RAW) {
-          remote_port = 0;
-        } else {
-          remote_port = sock->conn->pcb.udp->remote_port;
-        }
-      }
-
-      LOCK_TCPIP_CORE();
-      if (sock->conn->type == NETCONN_RAW) {
-        err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr);
-      } else {
-#if LWIP_UDP
-#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF
-        err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p,
-          remote_addr, remote_port, 1, chksum);
-#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */
-        err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p,
-          remote_addr, remote_port);
-#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */
-#else /* LWIP_UDP */
-        err = ERR_ARG;
-#endif /* LWIP_UDP */
-      }
-      UNLOCK_TCPIP_CORE();
-      
-      pbuf_free(p);
-    } else {
-      err = ERR_MEM;
-    }
-  }
-#else /* LWIP_TCPIP_CORE_LOCKING */
-  /* initialize a buffer */
-  buf.p = buf.ptr = NULL;
-#if LWIP_CHECKSUM_ON_COPY
-  buf.flags = 0;
-#endif /* LWIP_CHECKSUM_ON_COPY */
-  if (to) {
-    inet_addr_to_ipaddr(&buf.addr, &to_in->sin_addr);
-    remote_port           = ntohs(to_in->sin_port);
-    netbuf_fromport(&buf) = remote_port;
-  } else {
-    remote_port           = 0;
-    ip_addr_set_any(&buf.addr);
-    netbuf_fromport(&buf) = 0;
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=",
-              s, data, short_size, flags));
-  ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port));
-
-  /* make the buffer point to the data that should be sent */
-#if LWIP_NETIF_TX_SINGLE_PBUF
-  /* Allocate a new netbuf and copy the data into it. */
-  if (netbuf_alloc(&buf, short_size) == NULL) {
-    err = ERR_MEM;
-  } else {
-#if LWIP_CHECKSUM_ON_COPY
-    if (sock->conn->type != NETCONN_RAW) {
-      u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size);
-      netbuf_set_chksum(&buf, chksum);
-      err = ERR_OK;
-    } else
-#endif /* LWIP_CHECKSUM_ON_COPY */
-    {
-      err = netbuf_take(&buf, data, short_size);
-    }
-  }
-#else /* LWIP_NETIF_TX_SINGLE_PBUF */
-  err = netbuf_ref(&buf, data, short_size);
-#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
-  if (err == ERR_OK) {
-    /* send the data */
-    err = netconn_send(sock->conn, &buf);
-  }
-
-  /* deallocated the buffer */
-  netbuf_free(&buf);
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-  sock_set_errno(sock, err_to_errno(err));
-  return (err == ERR_OK ? short_size : -1);
-}
-
-int
-lwip_socket(int domain, int type, int protocol)
-{
-  struct netconn *conn;
-  int i;
-
-  LWIP_UNUSED_ARG(domain);
-
-  /* create a netconn */
-  switch (type) {
-  case SOCK_RAW:
-    conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ",
-                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  case SOCK_DGRAM:
-    conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ?
-                 NETCONN_UDPLITE : NETCONN_UDP, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ",
-                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    break;
-  case SOCK_STREAM:
-    conn = netconn_new_with_callback(NETCONN_TCP, event_callback);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ",
-                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
-    if (conn != NULL) {
-      /* Prevent automatic window updates, we do this on our own! */
-      netconn_set_noautorecved(conn, 1);
-    }
-    break;
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n",
-                                 domain, type, protocol));
-    set_errno(EINVAL);
-    return -1;
-  }
-
-  if (!conn) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));
-    set_errno(ENOBUFS);
-    return -1;
-  }
-
-  i = alloc_socket(conn, 0);
-
-  if (i == -1) {
-    netconn_delete(conn);
-    set_errno(ENFILE);
-    return -1;
-  }
-  conn->socket = i;
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));
-  set_errno(0);
-  return i;
-}
-
-int
-lwip_write(int s, const void *data, size_t size)
-{
-  return lwip_send(s, data, size, 0);
-}
-
-/**
- * Go through the readset and writeset lists and see which socket of the sockets
- * set in the sets has events. On return, readset, writeset and exceptset have
- * the sockets enabled that had events.
- *
- * exceptset is not used for now!!!
- *
- * @param maxfdp1 the highest socket index in the sets
- * @param readset_in:    set of sockets to check for read events
- * @param writeset_in:   set of sockets to check for write events
- * @param exceptset_in:  set of sockets to check for error events
- * @param readset_out:   set of sockets that had read events
- * @param writeset_out:  set of sockets that had write events
- * @param exceptset_out: set os sockets that had error events
- * @return number of sockets that had events (read/write/exception) (>= 0)
- */
-static int
-lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in,
-             fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out)
-{
-  int i, nready = 0;
-  fd_set lreadset, lwriteset, lexceptset;
-  struct lwip_sock *sock;
-  SYS_ARCH_DECL_PROTECT(lev);
-
-  FD_ZERO(&lreadset);
-  FD_ZERO(&lwriteset);
-  FD_ZERO(&lexceptset);
-
-  /* Go through each socket in each list to count number of sockets which
-     currently match */
-  for(i = 0; i < maxfdp1; i++) {
-    void* lastdata = NULL;
-    s16_t rcvevent = 0;
-    u16_t sendevent = 0;
-    u16_t errevent = 0;
-    /* First get the socket's status (protected)... */
-    SYS_ARCH_PROTECT(lev);
-    sock = tryget_socket(i);
-    if (sock != NULL) {
-      lastdata = sock->lastdata;
-      rcvevent = sock->rcvevent;
-      sendevent = sock->sendevent;
-      errevent = sock->errevent;
-    }
-    SYS_ARCH_UNPROTECT(lev);
-    /* ... then examine it: */
-    /* See if netconn of this socket is ready for read */
-    if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) {
-      FD_SET(i, &lreadset);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
-      nready++;
-    }
-    /* See if netconn of this socket is ready for write */
-    if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) {
-      FD_SET(i, &lwriteset);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
-      nready++;
-    }
-    /* See if netconn of this socket had an error */
-    if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) {
-      FD_SET(i, &lexceptset);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i));
-      nready++;
-    }
-  }
-  /* copy local sets to the ones provided as arguments */
-  *readset_out = lreadset;
-  *writeset_out = lwriteset;
-  *exceptset_out = lexceptset;
-
-  LWIP_ASSERT("nready >= 0", nready >= 0);
-  return nready;
-}
-
-/**
- * Processing exceptset is not yet implemented.
- */
-int
-lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-            struct timeval *timeout)
-{
-  u32_t waitres = 0;
-  int nready;
-  fd_set lreadset, lwriteset, lexceptset;
-  u32_t msectimeout;
-  struct lwip_select_cb select_cb;
-  err_t err;
-  int i;
-  SYS_ARCH_DECL_PROTECT(lev);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
-                  maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
-                  timeout ? (s32_t)timeout->tv_sec : (s32_t)-1,
-                  timeout ? (s32_t)timeout->tv_usec : (s32_t)-1));
-
-  /* Go through each socket in each list to count number of sockets which
-     currently match */
-  nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
-
-  /* If we don't have any current events, then suspend if we are supposed to */
-  if (!nready) {
-    if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
-      /* This is OK as the local fdsets are empty and nready is zero,
-         or we would have returned earlier. */
-      goto return_copy_fdsets;
-    }
-
-    /* None ready: add our semaphore to list:
-       We don't actually need any dynamic memory. Our entry on the
-       list is only valid while we are in this function, so it's ok
-       to use local variables. */
-
-    select_cb.next = NULL;
-    select_cb.prev = NULL;
-    select_cb.readset = readset;
-    select_cb.writeset = writeset;
-    select_cb.exceptset = exceptset;
-    select_cb.sem_signalled = 0;
-    err = sys_sem_new(&select_cb.sem, 0);
-    if (err != ERR_OK) {
-      /* failed to create semaphore */
-      set_errno(ENOMEM);
-      return -1;
-    }
-
-    /* Protect the select_cb_list */
-    SYS_ARCH_PROTECT(lev);
-
-    /* Put this select_cb on top of list */
-    select_cb.next = select_cb_list;
-    if (select_cb_list != NULL) {
-      select_cb_list->prev = &select_cb;
-    }
-    select_cb_list = &select_cb;
-    /* Increasing this counter tells even_callback that the list has changed. */
-    select_cb_ctr++;
-
-    /* Now we can safely unprotect */
-    SYS_ARCH_UNPROTECT(lev);
-
-    /* Increase select_waiting for each socket we are interested in */
-    for(i = 0; i < maxfdp1; i++) {
-      if ((readset && FD_ISSET(i, readset)) ||
-          (writeset && FD_ISSET(i, writeset)) ||
-          (exceptset && FD_ISSET(i, exceptset))) {
-        struct lwip_sock *sock = tryget_socket(i);
-        LWIP_ASSERT("sock != NULL", sock != NULL);
-        SYS_ARCH_PROTECT(lev);
-        sock->select_waiting++;
-        LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
-        SYS_ARCH_UNPROTECT(lev);
-      }
-    }
-
-    /* Call lwip_selscan again: there could have been events between
-       the last scan (whithout us on the list) and putting us on the list! */
-    nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
-    if (!nready) {
-      /* Still none ready, just wait to be woken */
-      if (timeout == 0) {
-        /* Wait forever */
-        msectimeout = 0;
-      } else {
-        msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
-        if (msectimeout == 0) {
-          /* Wait 1ms at least (0 means wait forever) */
-          msectimeout = 1;
-        }
-      }
-
-      waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout);
-    }
-    /* Increase select_waiting for each socket we are interested in */
-    for(i = 0; i < maxfdp1; i++) {
-      if ((readset && FD_ISSET(i, readset)) ||
-          (writeset && FD_ISSET(i, writeset)) ||
-          (exceptset && FD_ISSET(i, exceptset))) {
-        struct lwip_sock *sock = tryget_socket(i);
-        LWIP_ASSERT("sock != NULL", sock != NULL);
-        SYS_ARCH_PROTECT(lev);
-        sock->select_waiting--;
-        LWIP_ASSERT("sock->select_waiting >= 0", sock->select_waiting >= 0);
-        SYS_ARCH_UNPROTECT(lev);
-      }
-    }
-    /* Take us off the list */
-    SYS_ARCH_PROTECT(lev);
-    if (select_cb.next != NULL) {
-      select_cb.next->prev = select_cb.prev;
-    }
-    if (select_cb_list == &select_cb) {
-      LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL);
-      select_cb_list = select_cb.next;
-    } else {
-      LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL);
-      select_cb.prev->next = select_cb.next;
-    }
-    /* Increasing this counter tells even_callback that the list has changed. */
-    select_cb_ctr++;
-    SYS_ARCH_UNPROTECT(lev);
-
-    sys_sem_free(&select_cb.sem);
-    if (waitres == SYS_ARCH_TIMEOUT)  {
-      /* Timeout */
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
-      /* This is OK as the local fdsets are empty and nready is zero,
-         or we would have returned earlier. */
-      goto return_copy_fdsets;
-    }
-
-    /* See what's set */
-    nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
-  }
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
-return_copy_fdsets:
-  set_errno(0);
-  if (readset) {
-    *readset = lreadset;
-  }
-  if (writeset) {
-    *writeset = lwriteset;
-  }
-  if (exceptset) {
-    *exceptset = lexceptset;
-  }
-
-
-  return nready;
-}
-
-/**
- * Callback registered in the netconn layer for each socket-netconn.
- * Processes recvevent (data available) and wakes up tasks waiting for select.
- */
-static void
-event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
-{
-  int s;
-  struct lwip_sock *sock;
-  struct lwip_select_cb *scb;
-  int last_select_cb_ctr;
-  SYS_ARCH_DECL_PROTECT(lev);
-
-  LWIP_UNUSED_ARG(len);
-
-  /* Get socket */
-  if (conn) {
-    s = conn->socket;
-    if (s < 0) {
-      /* Data comes in right away after an accept, even though
-       * the server task might not have created a new socket yet.
-       * Just count down (or up) if that's the case and we
-       * will use the data later. Note that only receive events
-       * can happen before the new socket is set up. */
-      SYS_ARCH_PROTECT(lev);
-      if (conn->socket < 0) {
-        if (evt == NETCONN_EVT_RCVPLUS) {
-          conn->socket--;
-        }
-        SYS_ARCH_UNPROTECT(lev);
-        return;
-      }
-      s = conn->socket;
-      SYS_ARCH_UNPROTECT(lev);
-    }
-
-    sock = get_socket(s);
-    if (!sock) {
-      return;
-    }
-  } else {
-    return;
-  }
-
-  SYS_ARCH_PROTECT(lev);
-  /* Set event as required */
-  switch (evt) {
-    case NETCONN_EVT_RCVPLUS:
-      sock->rcvevent++;
-      break;
-    case NETCONN_EVT_RCVMINUS:
-      sock->rcvevent--;
-      break;
-    case NETCONN_EVT_SENDPLUS:
-      sock->sendevent = 1;
-      break;
-    case NETCONN_EVT_SENDMINUS:
-      sock->sendevent = 0;
-      break;
-    case NETCONN_EVT_ERROR:
-      sock->errevent = 1;
-      break;
-    default:
-      LWIP_ASSERT("unknown event", 0);
-      break;
-  }
-
-  if (sock->select_waiting == 0) {
-    /* noone is waiting for this socket, no need to check select_cb_list */
-    SYS_ARCH_UNPROTECT(lev);
-    return;
-  }
-
-  /* Now decide if anyone is waiting for this socket */
-  /* NOTE: This code goes through the select_cb_list list multiple times
-     ONLY IF a select was actually waiting. We go through the list the number
-     of waiting select calls + 1. This list is expected to be small. */
-
-  /* At this point, SYS_ARCH is still protected! */
-again:
-  for (scb = select_cb_list; scb != NULL; scb = scb->next) {
-    if (scb->sem_signalled == 0) {
-      /* semaphore not signalled yet */
-      int do_signal = 0;
-      /* Test this select call for our socket */
-      if (sock->rcvevent > 0) {
-        if (scb->readset && FD_ISSET(s, scb->readset)) {
-          do_signal = 1;
-        }
-      }
-      if (sock->sendevent != 0) {
-        if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) {
-          do_signal = 1;
-        }
-      }
-      if (sock->errevent != 0) {
-        if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) {
-          do_signal = 1;
-        }
-      }
-      if (do_signal) {
-        scb->sem_signalled = 1;
-        /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might
-           lead to the select thread taking itself off the list, invalidagin the semaphore. */
-        sys_sem_signal(&scb->sem);
-      }
-    }
-    /* unlock interrupts with each step */
-    last_select_cb_ctr = select_cb_ctr;
-    SYS_ARCH_UNPROTECT(lev);
-    /* this makes sure interrupt protection time is short */
-    SYS_ARCH_PROTECT(lev);
-    if (last_select_cb_ctr != select_cb_ctr) {
-      /* someone has changed select_cb_list, restart at the beginning */
-      goto again;
-    }
-  }
-  SYS_ARCH_UNPROTECT(lev);
-}
-
-/**
- * Unimplemented: Close one end of a full-duplex connection.
- * Currently, the full connection is closed.
- */
-int
-lwip_shutdown(int s, int how)
-{
-  struct lwip_sock *sock;
-  err_t err;
-  u8_t shut_rx = 0, shut_tx = 0;
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  if (sock->conn != NULL) {
-    if (netconn_type(sock->conn) != NETCONN_TCP) {
-      sock_set_errno(sock, EOPNOTSUPP);
-      return EOPNOTSUPP;
-    }
-  } else {
-    sock_set_errno(sock, ENOTCONN);
-    return ENOTCONN;
-  }
-
-  if (how == SHUT_RD) {
-    shut_rx = 1;
-  } else if (how == SHUT_WR) {
-    shut_tx = 1;
-  } else if(how == SHUT_RDWR) {
-    shut_rx = 1;
-    shut_tx = 1;
-  } else {
-    sock_set_errno(sock, EINVAL);
-    return EINVAL;
-  }
-  err = netconn_shutdown(sock->conn, shut_rx, shut_tx);
-
-  sock_set_errno(sock, err_to_errno(err));
-  return (err == ERR_OK ? 0 : -1);
-}
-
-static int
-lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
-{
-  struct lwip_sock *sock;
-  struct sockaddr_in sin;
-  ip_addr_t naddr;
-
-  sock = get_socket(s);
-  if (!sock) {
-    return -1;
-  }
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_len = sizeof(sin);
-  sin.sin_family = AF_INET;
-
-  /* get the IP address and port */
-  netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local);
-
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
-  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port));
-
-  sin.sin_port = htons(sin.sin_port);
-  inet_addr_from_ipaddr(&sin.sin_addr, &naddr);
-
-  if (*namelen > sizeof(sin)) {
-    *namelen = sizeof(sin);
-  }
-
-  MEMCPY(name, &sin, *namelen);
-  sock_set_errno(sock, 0);
-  return 0;
-}
-
-int
-lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
-{
-  return lwip_getaddrname(s, name, namelen, 0);
-}
-
-int
-lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
-{
-  return lwip_getaddrname(s, name, namelen, 1);
-}
-
-int
-lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
-{
-  err_t err = ERR_OK;
-  struct lwip_sock *sock = get_socket(s);
-  struct lwip_setgetsockopt_data data;
-
-  if (!sock) {
-    return -1;
-  }
-
-  if ((NULL == optval) || (NULL == optlen)) {
-    sock_set_errno(sock, EFAULT);
-    return -1;
-  }
-
-  /* Do length and type checks for the various options first, to keep it readable. */
-  switch (level) {
-   
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch (optname) {
-       
-    case SO_ACCEPTCONN:
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_ERROR:
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_CONTIMEO: */
-    /* UNIMPL case SO_SNDTIMEO: */
-#if LWIP_SO_RCVTIMEO
-    case SO_RCVTIMEO:
-#endif /* LWIP_SO_RCVTIMEO */
-#if LWIP_SO_RCVBUF
-    case SO_RCVBUF:
-#endif /* LWIP_SO_RCVBUF */
-    /* UNIMPL case SO_OOBINLINE: */
-    /* UNIMPL case SO_SNDBUF: */
-    /* UNIMPL case SO_RCVLOWAT: */
-    /* UNIMPL case SO_SNDLOWAT: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    case SO_TYPE:
-    /* UNIMPL case SO_USELOOPBACK: */
-      if (*optlen < sizeof(int)) {
-        err = EINVAL;
-      }
-      break;
-
-    case SO_NO_CHECK:
-      if (*optlen < sizeof(int)) {
-        err = EINVAL;
-      }
-#if LWIP_UDP
-      if ((sock->conn->type != NETCONN_UDP) ||
-          ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
-        /* this flag is only available for UDP, not for UDP lite */
-        err = EAFNOSUPPORT;
-      }
-#endif /* LWIP_UDP */
-      break;
-
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
-                                  s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-                     
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch (optname) {
-    /* UNIMPL case IP_HDRINCL: */
-    /* UNIMPL case IP_RCVDSTADDR: */
-    /* UNIMPL case IP_RCVIF: */
-    case IP_TTL:
-    case IP_TOS:
-      if (*optlen < sizeof(int)) {
-        err = EINVAL;
-      }
-      break;
-#if LWIP_IGMP
-    case IP_MULTICAST_TTL:
-      if (*optlen < sizeof(u8_t)) {
-        err = EINVAL;
-      }
-      break;
-    case IP_MULTICAST_IF:
-      if (*optlen < sizeof(struct in_addr)) {
-        err = EINVAL;
-      }
-      break;
-    case IP_MULTICAST_LOOP:
-      if (*optlen < sizeof(u8_t)) {
-        err = EINVAL;
-      }
-      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
-        err = EAFNOSUPPORT;
-      }
-      break;
-#endif /* LWIP_IGMP */
-
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
-                                  s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-         
-#if LWIP_TCP
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    if (*optlen < sizeof(int)) {
-      err = EINVAL;
-      break;
-    }
-    
-    /* If this is no TCP socket, ignore any options. */
-    if (sock->conn->type != NETCONN_TCP)
-      return 0;
-
-    switch (optname) {
-    case TCP_NODELAY:
-    case TCP_KEEPALIVE:
-#if LWIP_TCP_KEEPALIVE
-    case TCP_KEEPIDLE:
-    case TCP_KEEPINTVL:
-    case TCP_KEEPCNT:
-#endif /* LWIP_TCP_KEEPALIVE */
-      break;
-       
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
-                                  s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_TCP */
-#if LWIP_UDP && LWIP_UDPLITE
-/* Level: IPPROTO_UDPLITE */
-  case IPPROTO_UDPLITE:
-    if (*optlen < sizeof(int)) {
-      err = EINVAL;
-      break;
-    }
-    
-    /* If this is no UDP lite socket, ignore any options. */
-    if (sock->conn->type != NETCONN_UDPLITE) {
-      return 0;
-    }
-
-    switch (optname) {
-    case UDPLITE_SEND_CSCOV:
-    case UDPLITE_RECV_CSCOV:
-      break;
-       
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
-                                  s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_UDP && LWIP_UDPLITE*/
-/* UNDEFINED LEVEL */
-  default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
-                                  s, level, optname));
-      err = ENOPROTOOPT;
-  }  /* switch */
-
-   
-  if (err != ERR_OK) {
-    sock_set_errno(sock, err);
-    return -1;
-  }
-
-  /* Now do the actual option processing */
-  data.sock = sock;
-#ifdef LWIP_DEBUG
-  data.s = s;
-#endif /* LWIP_DEBUG */
-  data.level = level;
-  data.optname = optname;
-  data.optval = optval;
-  data.optlen = optlen;
-  data.err = err;
-  tcpip_callback(lwip_getsockopt_internal, &data);
-  sys_arch_sem_wait(&sock->conn->op_completed, 0);
-  /* maybe lwip_getsockopt_internal has changed err */
-  err = data.err;
-
-  sock_set_errno(sock, err);
-  return err ? -1 : 0;
-}
-
-static void
-lwip_getsockopt_internal(void *arg)
-{
-  struct lwip_sock *sock;
-#ifdef LWIP_DEBUG
-  int s;
-#endif /* LWIP_DEBUG */
-  int level, optname;
-  void *optval;
-  struct lwip_setgetsockopt_data *data;
-
-  LWIP_ASSERT("arg != NULL", arg != NULL);
-
-  data = (struct lwip_setgetsockopt_data*)arg;
-  sock = data->sock;
-#ifdef LWIP_DEBUG
-  s = data->s;
-#endif /* LWIP_DEBUG */
-  level = data->level;
-  optname = data->optname;
-  optval = data->optval;
-
-  switch (level) {
-
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch (optname) {
-
-    /* The option flags */
-    case SO_ACCEPTCONN:
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINCLUDE: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /*case SO_USELOOPBACK: UNIMPL */
-      *(int*)optval = sock->conn->pcb.ip->so_options & optname;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n",
-                                  s, optname, (*(int*)optval?"on":"off")));
-      break;
-
-    case SO_TYPE:
-      switch (NETCONNTYPE_GROUP(sock->conn->type)) {
-      case NETCONN_RAW:
-        *(int*)optval = SOCK_RAW;
-        break;
-      case NETCONN_TCP:
-        *(int*)optval = SOCK_STREAM;
-        break;
-      case NETCONN_UDP:
-        *(int*)optval = SOCK_DGRAM;
-        break;
-      default: /* unrecognized socket type */
-        *(int*)optval = sock->conn->type;
-        LWIP_DEBUGF(SOCKETS_DEBUG,
-                    ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n",
-                    s, *(int *)optval));
-      }  /* switch (sock->conn->type) */
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n",
-                  s, *(int *)optval));
-      break;
-
-    case SO_ERROR:
-      /* only overwrite ERR_OK or tempoary errors */
-      if ((sock->err == 0) || (sock->err == EINPROGRESS)) {
-        sock_set_errno(sock, err_to_errno(sock->conn->last_err));
-      } 
-      *(int *)optval = sock->err;
-      sock->err = 0;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n",
-                  s, *(int *)optval));
-      break;
-
-#if LWIP_SO_RCVTIMEO
-    case SO_RCVTIMEO:
-      *(int *)optval = netconn_get_recvtimeout(sock->conn);
-      break;
-#endif /* LWIP_SO_RCVTIMEO */
-#if LWIP_SO_RCVBUF
-    case SO_RCVBUF:
-      *(int *)optval = netconn_get_recvbufsize(sock->conn);
-      break;
-#endif /* LWIP_SO_RCVBUF */
-#if LWIP_UDP
-    case SO_NO_CHECK:
-      *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0;
-      break;
-#endif /* LWIP_UDP*/
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch (optname) {
-    case IP_TTL:
-      *(int*)optval = sock->conn->pcb.ip->ttl;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n",
-                  s, *(int *)optval));
-      break;
-    case IP_TOS:
-      *(int*)optval = sock->conn->pcb.ip->tos;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n",
-                  s, *(int *)optval));
-      break;
-#if LWIP_IGMP
-    case IP_MULTICAST_TTL:
-      *(u8_t*)optval = sock->conn->pcb.ip->ttl;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n",
-                  s, *(int *)optval));
-      break;
-    case IP_MULTICAST_IF:
-      inet_addr_from_ipaddr((struct in_addr*)optval, &sock->conn->pcb.udp->multicast_ip);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n",
-                  s, *(u32_t *)optval));
-      break;
-    case IP_MULTICAST_LOOP:
-      if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) {
-        *(u8_t*)optval = 1;
-      } else {
-        *(u8_t*)optval = 0;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n",
-                  s, *(int *)optval));
-      break;
-#endif /* LWIP_IGMP */
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-
-#if LWIP_TCP
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    switch (optname) {
-    case TCP_NODELAY:
-      *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n",
-                  s, (*(int*)optval)?"on":"off") );
-      break;
-    case TCP_KEEPALIVE:
-      *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n",
-                  s, *(int *)optval));
-      break;
-
-#if LWIP_TCP_KEEPALIVE
-    case TCP_KEEPIDLE:
-      *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n",
-                  s, *(int *)optval));
-      break;
-    case TCP_KEEPINTVL:
-      *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n",
-                  s, *(int *)optval));
-      break;
-    case TCP_KEEPCNT:
-      *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n",
-                  s, *(int *)optval));
-      break;
-#endif /* LWIP_TCP_KEEPALIVE */
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_TCP */
-#if LWIP_UDP && LWIP_UDPLITE
-  /* Level: IPPROTO_UDPLITE */
-  case IPPROTO_UDPLITE:
-    switch (optname) {
-    case UDPLITE_SEND_CSCOV:
-      *(int*)optval = sock->conn->pcb.udp->chksum_len_tx;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n",
-                  s, (*(int*)optval)) );
-      break;
-    case UDPLITE_RECV_CSCOV:
-      *(int*)optval = sock->conn->pcb.udp->chksum_len_rx;
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n",
-                  s, (*(int*)optval)) );
-      break;
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_UDP */
-  default:
-    LWIP_ASSERT("unhandled level", 0);
-    break;
-  } /* switch (level) */
-  sys_sem_signal(&sock->conn->op_completed);
-}
-
-int
-lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
-{
-  struct lwip_sock *sock = get_socket(s);
-  err_t err = ERR_OK;
-  struct lwip_setgetsockopt_data data;
-
-  if (!sock) {
-    return -1;
-  }
-
-  if (NULL == optval) {
-    sock_set_errno(sock, EFAULT);
-    return -1;
-  }
-
-  /* Do length and type checks for the various options first, to keep it readable. */
-  switch (level) {
-
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch (optname) {
-
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case case SO_CONTIMEO: */
-    /* UNIMPL case case SO_SNDTIMEO: */
-#if LWIP_SO_RCVTIMEO
-    case SO_RCVTIMEO:
-#endif /* LWIP_SO_RCVTIMEO */
-#if LWIP_SO_RCVBUF
-    case SO_RCVBUF:
-#endif /* LWIP_SO_RCVBUF */
-    /* UNIMPL case SO_OOBINLINE: */
-    /* UNIMPL case SO_SNDBUF: */
-    /* UNIMPL case SO_RCVLOWAT: */
-    /* UNIMPL case SO_SNDLOWAT: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /* UNIMPL case SO_USELOOPBACK: */
-      if (optlen < sizeof(int)) {
-        err = EINVAL;
-      }
-      break;
-    case SO_NO_CHECK:
-      if (optlen < sizeof(int)) {
-        err = EINVAL;
-      }
-#if LWIP_UDP
-      if ((sock->conn->type != NETCONN_UDP) ||
-          ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
-        /* this flag is only available for UDP, not for UDP lite */
-        err = EAFNOSUPPORT;
-      }
-#endif /* LWIP_UDP */
-      break;
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
-                  s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch (optname) {
-    /* UNIMPL case IP_HDRINCL: */
-    /* UNIMPL case IP_RCVDSTADDR: */
-    /* UNIMPL case IP_RCVIF: */
-    case IP_TTL:
-    case IP_TOS:
-      if (optlen < sizeof(int)) {
-        err = EINVAL;
-      }
-      break;
-#if LWIP_IGMP
-    case IP_MULTICAST_TTL:
-      if (optlen < sizeof(u8_t)) {
-        err = EINVAL;
-      }
-      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
-        err = EAFNOSUPPORT;
-      }
-      break;
-    case IP_MULTICAST_IF:
-      if (optlen < sizeof(struct in_addr)) {
-        err = EINVAL;
-      }
-      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
-        err = EAFNOSUPPORT;
-      }
-      break;
-    case IP_MULTICAST_LOOP:
-      if (optlen < sizeof(u8_t)) {
-        err = EINVAL;
-      }
-      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
-        err = EAFNOSUPPORT;
-      }
-      break;
-    case IP_ADD_MEMBERSHIP:
-    case IP_DROP_MEMBERSHIP:
-      if (optlen < sizeof(struct ip_mreq)) {
-        err = EINVAL;
-      }
-      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
-        err = EAFNOSUPPORT;
-      }
-      break;
-#endif /* LWIP_IGMP */
-      default:
-        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
-                    s, optname));
-        err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-
-#if LWIP_TCP
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    if (optlen < sizeof(int)) {
-      err = EINVAL;
-      break;
-    }
-
-    /* If this is no TCP socket, ignore any options. */
-    if (sock->conn->type != NETCONN_TCP)
-      return 0;
-
-    switch (optname) {
-    case TCP_NODELAY:
-    case TCP_KEEPALIVE:
-#if LWIP_TCP_KEEPALIVE
-    case TCP_KEEPIDLE:
-    case TCP_KEEPINTVL:
-    case TCP_KEEPCNT:
-#endif /* LWIP_TCP_KEEPALIVE */
-      break;
-
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
-                  s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_TCP */
-#if LWIP_UDP && LWIP_UDPLITE
-/* Level: IPPROTO_UDPLITE */
-  case IPPROTO_UDPLITE:
-    if (optlen < sizeof(int)) {
-      err = EINVAL;
-      break;
-    }
-
-    /* If this is no UDP lite socket, ignore any options. */
-    if (sock->conn->type != NETCONN_UDPLITE)
-      return 0;
-
-    switch (optname) {
-    case UDPLITE_SEND_CSCOV:
-    case UDPLITE_RECV_CSCOV:
-      break;
-
-    default:
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
-                  s, optname));
-      err = ENOPROTOOPT;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_UDP && LWIP_UDPLITE */
-/* UNDEFINED LEVEL */
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
-                s, level, optname));
-    err = ENOPROTOOPT;
-  }  /* switch (level) */
-
-
-  if (err != ERR_OK) {
-    sock_set_errno(sock, err);
-    return -1;
-  }
-
-
-  /* Now do the actual option processing */
-  data.sock = sock;
-#ifdef LWIP_DEBUG
-  data.s = s;
-#endif /* LWIP_DEBUG */
-  data.level = level;
-  data.optname = optname;
-  data.optval = (void*)optval;
-  data.optlen = &optlen;
-  data.err = err;
-  tcpip_callback(lwip_setsockopt_internal, &data);
-  sys_arch_sem_wait(&sock->conn->op_completed, 0);
-  /* maybe lwip_setsockopt_internal has changed err */
-  err = data.err;
-
-  sock_set_errno(sock, err);
-  return err ? -1 : 0;
-}
-
-static void
-lwip_setsockopt_internal(void *arg)
-{
-  struct lwip_sock *sock;
-#ifdef LWIP_DEBUG
-  int s;
-#endif /* LWIP_DEBUG */
-  int level, optname;
-  const void *optval;
-  struct lwip_setgetsockopt_data *data;
-
-  LWIP_ASSERT("arg != NULL", arg != NULL);
-
-  data = (struct lwip_setgetsockopt_data*)arg;
-  sock = data->sock;
-#ifdef LWIP_DEBUG
-  s = data->s;
-#endif /* LWIP_DEBUG */
-  level = data->level;
-  optname = data->optname;
-  optval = data->optval;
-
-  switch (level) {
-
-/* Level: SOL_SOCKET */
-  case SOL_SOCKET:
-    switch (optname) {
-
-    /* The option flags */
-    case SO_BROADCAST:
-    /* UNIMPL case SO_DEBUG: */
-    /* UNIMPL case SO_DONTROUTE: */
-    case SO_KEEPALIVE:
-    /* UNIMPL case SO_OOBINCLUDE: */
-#if SO_REUSE
-    case SO_REUSEADDR:
-    case SO_REUSEPORT:
-#endif /* SO_REUSE */
-    /* UNIMPL case SO_USELOOPBACK: */
-      if (*(int*)optval) {
-        sock->conn->pcb.ip->so_options |= optname;
-      } else {
-        sock->conn->pcb.ip->so_options &= ~optname;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
-                  s, optname, (*(int*)optval?"on":"off")));
-      break;
-#if LWIP_SO_RCVTIMEO
-    case SO_RCVTIMEO:
-      netconn_set_recvtimeout(sock->conn, *(int*)optval);
-      break;
-#endif /* LWIP_SO_RCVTIMEO */
-#if LWIP_SO_RCVBUF
-    case SO_RCVBUF:
-      netconn_set_recvbufsize(sock->conn, *(int*)optval);
-      break;
-#endif /* LWIP_SO_RCVBUF */
-#if LWIP_UDP
-    case SO_NO_CHECK:
-      if (*(int*)optval) {
-        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM);
-      } else {
-        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM);
-      }
-      break;
-#endif /* LWIP_UDP */
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-
-/* Level: IPPROTO_IP */
-  case IPPROTO_IP:
-    switch (optname) {
-    case IP_TTL:
-      sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n",
-                  s, sock->conn->pcb.ip->ttl));
-      break;
-    case IP_TOS:
-      sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n",
-                  s, sock->conn->pcb.ip->tos));
-      break;
-#if LWIP_IGMP
-    case IP_MULTICAST_TTL:
-      sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval);
-      break;
-    case IP_MULTICAST_IF:
-      inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval);
-      break;
-    case IP_MULTICAST_LOOP:
-      if (*(u8_t*)optval) {
-        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP);
-      } else {
-        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP);
-      }
-      break;
-    case IP_ADD_MEMBERSHIP:
-    case IP_DROP_MEMBERSHIP:
-      {
-        /* If this is a TCP or a RAW socket, ignore these options. */
-        struct ip_mreq *imr = (struct ip_mreq *)optval;
-        ip_addr_t if_addr;
-        ip_addr_t multi_addr;
-        inet_addr_to_ipaddr(&if_addr, &imr->imr_interface);
-        inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr);
-        if(optname == IP_ADD_MEMBERSHIP){
-          data->err = igmp_joingroup(&if_addr, &multi_addr);
-        } else {
-          data->err = igmp_leavegroup(&if_addr, &multi_addr);
-        }
-        if(data->err != ERR_OK) {
-          data->err = EADDRNOTAVAIL;
-        }
-      }
-      break;
-#endif /* LWIP_IGMP */
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-
-#if LWIP_TCP
-/* Level: IPPROTO_TCP */
-  case IPPROTO_TCP:
-    switch (optname) {
-    case TCP_NODELAY:
-      if (*(int*)optval) {
-        tcp_nagle_disable(sock->conn->pcb.tcp);
-      } else {
-        tcp_nagle_enable(sock->conn->pcb.tcp);
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n",
-                  s, (*(int *)optval)?"on":"off") );
-      break;
-    case TCP_KEEPALIVE:
-      sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n",
-                  s, sock->conn->pcb.tcp->keep_idle));
-      break;
-
-#if LWIP_TCP_KEEPALIVE
-    case TCP_KEEPIDLE:
-      sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n",
-                  s, sock->conn->pcb.tcp->keep_idle));
-      break;
-    case TCP_KEEPINTVL:
-      sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n",
-                  s, sock->conn->pcb.tcp->keep_intvl));
-      break;
-    case TCP_KEEPCNT:
-      sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n",
-                  s, sock->conn->pcb.tcp->keep_cnt));
-      break;
-#endif /* LWIP_TCP_KEEPALIVE */
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_TCP*/
-#if LWIP_UDP && LWIP_UDPLITE
-  /* Level: IPPROTO_UDPLITE */
-  case IPPROTO_UDPLITE:
-    switch (optname) {
-    case UDPLITE_SEND_CSCOV:
-      if ((*(int*)optval != 0) && ((*(int*)optval < 8)) || (*(int*)optval > 0xffff)) {
-        /* don't allow illegal values! */
-        sock->conn->pcb.udp->chksum_len_tx = 8;
-      } else {
-        sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(int*)optval;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n",
-                  s, (*(int*)optval)) );
-      break;
-    case UDPLITE_RECV_CSCOV:
-      if ((*(int*)optval != 0) && ((*(int*)optval < 8)) || (*(int*)optval > 0xffff)) {
-        /* don't allow illegal values! */
-        sock->conn->pcb.udp->chksum_len_rx = 8;
-      } else {
-        sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(int*)optval;
-      }
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n",
-                  s, (*(int*)optval)) );
-      break;
-    default:
-      LWIP_ASSERT("unhandled optname", 0);
-      break;
-    }  /* switch (optname) */
-    break;
-#endif /* LWIP_UDP */
-  default:
-    LWIP_ASSERT("unhandled level", 0);
-    break;
-  }  /* switch (level) */
-  sys_sem_signal(&sock->conn->op_completed);
-}
-
-int
-lwip_ioctl(int s, long cmd, void *argp)
-{
-  struct lwip_sock *sock = get_socket(s);
-  u8_t val;
-#if LWIP_SO_RCVBUF
-  u16_t buflen = 0;
-  s16_t recv_avail;
-#endif /* LWIP_SO_RCVBUF */
-
-  if (!sock) {
-    return -1;
-  }
-
-  switch (cmd) {
-#if LWIP_SO_RCVBUF
-  case FIONREAD:
-    if (!argp) {
-      sock_set_errno(sock, EINVAL);
-      return -1;
-    }
-
-    SYS_ARCH_GET(sock->conn->recv_avail, recv_avail);
-    if (recv_avail < 0) {
-      recv_avail = 0;
-    }
-    *((u16_t*)argp) = (u16_t)recv_avail;
-
-    /* Check if there is data left from the last recv operation. /maq 041215 */
-    if (sock->lastdata) {
-      struct pbuf *p = (struct pbuf *)sock->lastdata;
-      if (netconn_type(sock->conn) != NETCONN_TCP) {
-        p = ((struct netbuf *)p)->p;
-      }
-      buflen = p->tot_len;
-      buflen -= sock->lastoffset;
-
-      *((u16_t*)argp) += buflen;
-    }
-
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp)));
-    sock_set_errno(sock, 0);
-    return 0;
-#endif /* LWIP_SO_RCVBUF */
-
-  case FIONBIO:
-    val = 0;
-    if (argp && *(u32_t*)argp) {
-      val = 1;
-    }
-    netconn_set_nonblocking(sock->conn, val);
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val));
-    sock_set_errno(sock, 0);
-    return 0;
-
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
-    sock_set_errno(sock, ENOSYS); /* not yet implemented */
-    return -1;
-  } /* switch (cmd) */
-}
-
-/** A minimal implementation of fcntl.
- * Currently only the commands F_GETFL and F_SETFL are implemented.
- * Only the flag O_NONBLOCK is implemented.
- */
-int
-lwip_fcntl(int s, int cmd, int val)
-{
-  struct lwip_sock *sock = get_socket(s);
-  int ret = -1;
-
-  if (!sock || !sock->conn) {
-    return -1;
-  }
-
-  switch (cmd) {
-  case F_GETFL:
-    ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0;
-    break;
-  case F_SETFL:
-    if ((val & ~O_NONBLOCK) == 0) {
-      /* only O_NONBLOCK, all other bits are zero */
-      netconn_set_nonblocking(sock->conn, val & O_NONBLOCK);
-      ret = 0;
-    }
-    break;
-  default:
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val));
-    break;
-  }
-  return ret;
-}
-
-#endif /* LWIP_SOCKET */

+ 0 - 460
components/net/lwip/src/api/tcpip.c

@@ -1,460 +0,0 @@
-/**
- * @file
- * Sequential API Main thread module
- *
- */
-
-/*
- * Copyright (c) 2001-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. 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 lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/sys.h"
-#include "lwip/memp.h"
-#include "lwip/mem.h"
-#include "lwip/pbuf.h"
-#include "lwip/tcpip.h"
-#include "lwip/init.h"
-#include "netif/etharp.h"
-#include "netif/ppp_oe.h"
-
-/* global variables */
-static tcpip_init_done_fn tcpip_init_done;
-static void *tcpip_init_done_arg;
-static sys_mbox_t mbox;
-
-#if LWIP_TCPIP_CORE_LOCKING
-/** The global semaphore to lock the stack. */
-sys_mutex_t lock_tcpip_core;
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-
-
-/**
- * The main lwIP thread. This thread has exclusive access to lwIP core functions
- * (unless access to them is not locked). Other threads communicate with this
- * thread using message boxes.
- *
- * It also starts all the timers to make sure they are running in the right
- * thread context.
- *
- * @param arg unused argument
- */
-static void
-tcpip_thread(void *arg)
-{
-  struct tcpip_msg *msg;
-  LWIP_UNUSED_ARG(arg);
-
-  if (tcpip_init_done != NULL) {
-    tcpip_init_done(tcpip_init_done_arg);
-  }
-
-  LOCK_TCPIP_CORE();
-  while (1) {                          /* MAIN Loop */
-    UNLOCK_TCPIP_CORE();
-    LWIP_TCPIP_THREAD_ALIVE();
-    /* wait for a message, timeouts are processed while waiting */
-    sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
-    LOCK_TCPIP_CORE();
-    switch (msg->type) {
-#if LWIP_NETCONN
-    case TCPIP_MSG_API:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
-      msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
-      break;
-#endif /* LWIP_NETCONN */
-
-#if !LWIP_TCPIP_CORE_LOCKING_INPUT
-    case TCPIP_MSG_INPKT:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
-#if LWIP_ETHERNET
-      if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
-        ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
-      } else
-#endif /* LWIP_ETHERNET */
-      {
-        ip_input(msg->msg.inp.p, msg->msg.inp.netif);
-      }
-      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
-      break;
-#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
-
-#if LWIP_NETIF_API
-    case TCPIP_MSG_NETIFAPI:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
-      msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
-      break;
-#endif /* LWIP_NETIF_API */
-
-    case TCPIP_MSG_CALLBACK:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
-      msg->msg.cb.function(msg->msg.cb.ctx);
-      memp_free(MEMP_TCPIP_MSG_API, msg);
-      break;
-
-#if LWIP_TCPIP_TIMEOUT
-    case TCPIP_MSG_TIMEOUT:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
-      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
-      memp_free(MEMP_TCPIP_MSG_API, msg);
-      break;
-    case TCPIP_MSG_UNTIMEOUT:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
-      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
-      memp_free(MEMP_TCPIP_MSG_API, msg);
-      break;
-#endif /* LWIP_TCPIP_TIMEOUT */
-
-    default:
-      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
-      LWIP_ASSERT("tcpip_thread: invalid message", 0);
-      break;
-    }
-  }
-}
-
-/**
- * Pass a received packet to tcpip_thread for input processing
- *
- * @param p the received packet, p->payload pointing to the Ethernet header or
- *          to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
- *          NETIF_FLAG_ETHERNET flags)
- * @param inp the network interface on which the packet was received
- */
-err_t
-tcpip_input(struct pbuf *p, struct netif *inp)
-{
-#if LWIP_TCPIP_CORE_LOCKING_INPUT
-  err_t ret;
-  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
-  LOCK_TCPIP_CORE();
-#if LWIP_ETHERNET
-  if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
-    ret = ethernet_input(p, inp);
-  } else
-#endif /* LWIP_ETHERNET */
-  {
-    ret = ip_input(p, inp);
-  }
-  UNLOCK_TCPIP_CORE();
-  return ret;
-#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
-  struct tcpip_msg *msg;
-
-  if (sys_mbox_valid(&mbox)) {
-    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
-    if (msg == NULL) {
-      return ERR_MEM;
-    }
-
-    msg->type = TCPIP_MSG_INPKT;
-    msg->msg.inp.p = p;
-    msg->msg.inp.netif = inp;
-    if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
-      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
-      return ERR_MEM;
-    }
-    return ERR_OK;
-  }
-  return ERR_VAL;
-#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
-}
-
-/**
- * Call a specific function in the thread context of
- * tcpip_thread for easy access synchronization.
- * A function called in that way may access lwIP core code
- * without fearing concurrent access.
- *
- * @param f the function to call
- * @param ctx parameter passed to f
- * @param block 1 to block until the request is posted, 0 to non-blocking mode
- * @return ERR_OK if the function was called, another err_t if not
- */
-err_t
-tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
-{
-  struct tcpip_msg *msg;
-
-  if (sys_mbox_valid(&mbox)) {
-    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
-    if (msg == NULL) {
-      return ERR_MEM;
-    }
-
-    msg->type = TCPIP_MSG_CALLBACK;
-    msg->msg.cb.function = function;
-    msg->msg.cb.ctx = ctx;
-    if (block) {
-      sys_mbox_post(&mbox, msg);
-    } else {
-      if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
-        memp_free(MEMP_TCPIP_MSG_API, msg);
-        return ERR_MEM;
-      }
-    }
-    return ERR_OK;
-  }
-  return ERR_VAL;
-}
-
-#if LWIP_TCPIP_TIMEOUT
-/**
- * call sys_timeout in tcpip_thread
- *
- * @param msec time in milliseconds for timeout
- * @param h function to be called on timeout
- * @param arg argument to pass to timeout function h
- * @return ERR_MEM on memory error, ERR_OK otherwise
- */
-err_t
-tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
-{
-  struct tcpip_msg *msg;
-
-  if (sys_mbox_valid(&mbox)) {
-    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
-    if (msg == NULL) {
-      return ERR_MEM;
-    }
-
-    msg->type = TCPIP_MSG_TIMEOUT;
-    msg->msg.tmo.msecs = msecs;
-    msg->msg.tmo.h = h;
-    msg->msg.tmo.arg = arg;
-    sys_mbox_post(&mbox, msg);
-    return ERR_OK;
-  }
-  return ERR_VAL;
-}
-
-/**
- * call sys_untimeout in tcpip_thread
- *
- * @param msec time in milliseconds for timeout
- * @param h function to be called on timeout
- * @param arg argument to pass to timeout function h
- * @return ERR_MEM on memory error, ERR_OK otherwise
- */
-err_t
-tcpip_untimeout(sys_timeout_handler h, void *arg)
-{
-  struct tcpip_msg *msg;
-
-  if (sys_mbox_valid(&mbox)) {
-    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
-    if (msg == NULL) {
-      return ERR_MEM;
-    }
-
-    msg->type = TCPIP_MSG_UNTIMEOUT;
-    msg->msg.tmo.h = h;
-    msg->msg.tmo.arg = arg;
-    sys_mbox_post(&mbox, msg);
-    return ERR_OK;
-  }
-  return ERR_VAL;
-}
-#endif /* LWIP_TCPIP_TIMEOUT */
-
-#if LWIP_NETCONN
-/**
- * Call the lower part of a netconn_* function
- * This function is then running in the thread context
- * of tcpip_thread and has exclusive access to lwIP core code.
- *
- * @param apimsg a struct containing the function to call and its parameters
- * @return ERR_OK if the function was called, another err_t if not
- */
-err_t
-tcpip_apimsg(struct api_msg *apimsg)
-{
-  struct tcpip_msg msg;
-#ifdef LWIP_DEBUG
-  /* catch functions that don't set err */
-  apimsg->msg.err = ERR_VAL;
-#endif
-  
-  if (sys_mbox_valid(&mbox)) {
-    msg.type = TCPIP_MSG_API;
-    msg.msg.apimsg = apimsg;
-    sys_mbox_post(&mbox, &msg);
-    sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
-    return apimsg->msg.err;
-  }
-  return ERR_VAL;
-}
-
-#if LWIP_TCPIP_CORE_LOCKING
-/**
- * Call the lower part of a netconn_* function
- * This function has exclusive access to lwIP core code by locking it
- * before the function is called.
- *
- * @param apimsg a struct containing the function to call and its parameters
- * @return ERR_OK (only for compatibility fo tcpip_apimsg())
- */
-err_t
-tcpip_apimsg_lock(struct api_msg *apimsg)
-{
-#ifdef LWIP_DEBUG
-  /* catch functions that don't set err */
-  apimsg->msg.err = ERR_VAL;
-#endif
-
-  LOCK_TCPIP_CORE();
-  apimsg->function(&(apimsg->msg));
-  UNLOCK_TCPIP_CORE();
-  return apimsg->msg.err;
-
-}
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-#endif /* LWIP_NETCONN */
-
-#if LWIP_NETIF_API
-#if !LWIP_TCPIP_CORE_LOCKING
-/**
- * Much like tcpip_apimsg, but calls the lower part of a netifapi_*
- * function.
- *
- * @param netifapimsg a struct containing the function to call and its parameters
- * @return error code given back by the function that was called
- */
-err_t
-tcpip_netifapi(struct netifapi_msg* netifapimsg)
-{
-  struct tcpip_msg msg;
-  
-  if (sys_mbox_valid(&mbox)) {
-    err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
-    if (err != ERR_OK) {
-      netifapimsg->msg.err = err;
-      return err;
-    }
-    
-    msg.type = TCPIP_MSG_NETIFAPI;
-    msg.msg.netifapimsg = netifapimsg;
-    sys_mbox_post(&mbox, &msg);
-    sys_sem_wait(&netifapimsg->msg.sem);
-    sys_sem_free(&netifapimsg->msg.sem);
-    return netifapimsg->msg.err;
-  }
-  return ERR_VAL;
-}
-#else /* !LWIP_TCPIP_CORE_LOCKING */
-/**
- * Call the lower part of a netifapi_* function
- * This function has exclusive access to lwIP core code by locking it
- * before the function is called.
- *
- * @param netifapimsg a struct containing the function to call and its parameters
- * @return ERR_OK (only for compatibility fo tcpip_netifapi())
- */
-err_t
-tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
-{
-  LOCK_TCPIP_CORE();  
-  netifapimsg->function(&(netifapimsg->msg));
-  UNLOCK_TCPIP_CORE();
-  return netifapimsg->msg.err;
-}
-#endif /* !LWIP_TCPIP_CORE_LOCKING */
-#endif /* LWIP_NETIF_API */
-
-/**
- * Initialize this module:
- * - initialize all sub modules
- * - start the tcpip_thread
- *
- * @param initfunc a function to call when tcpip_thread is running and finished initializing
- * @param arg argument to pass to initfunc
- */
-void
-tcpip_init(tcpip_init_done_fn initfunc, void *arg)
-{
-  lwip_init();
-
-  tcpip_init_done = initfunc;
-  tcpip_init_done_arg = arg;
-  if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
-    LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
-  }
-#if LWIP_TCPIP_CORE_LOCKING
-  if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
-    LWIP_ASSERT("failed to create lock_tcpip_core", 0);
-  }
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-
-  sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
-}
-
-/**
- * Simple callback function used with tcpip_callback to free a pbuf
- * (pbuf_free has a wrong signature for tcpip_callback)
- *
- * @param p The pbuf (chain) to be dereferenced.
- */
-static void
-pbuf_free_int(void *p)
-{
-  struct pbuf *q = (struct pbuf *)p;
-  pbuf_free(q);
-}
-
-/**
- * A simple wrapper function that allows you to free a pbuf from interrupt context.
- *
- * @param p The pbuf (chain) to be dereferenced.
- * @return ERR_OK if callback could be enqueued, an err_t if not
- */
-err_t
-pbuf_free_callback(struct pbuf *p)
-{
-  return tcpip_callback_with_block(pbuf_free_int, p, 0);
-}
-
-/**
- * A simple wrapper function that allows you to free heap memory from
- * interrupt context.
- *
- * @param m the heap memory to free
- * @return ERR_OK if callback could be enqueued, an err_t if not
- */
-err_t
-mem_free_callback(void *m)
-{
-  return tcpip_callback_with_block(mem_free, m, 0);
-}
-
-#endif /* !NO_SYS */

+ 0 - 35
components/net/lwip/src/arch/include/arch/bpstruct.h

@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2001-2003 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 lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack(1)
-#endif

+ 0 - 107
components/net/lwip/src/arch/include/arch/cc.h

@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2001, 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 lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- * $Id: cc.h,v 1.1.1.1 2004/12/16 14:17:13 bear Exp $
- */
-#ifndef __ARCH_CC_H__
-#define __ARCH_CC_H__
-
-#include <rthw.h>
-#include <rtthread.h>
-
-typedef rt_uint8_t	u8_t;
-typedef rt_int8_t	s8_t;
-typedef rt_uint16_t	u16_t;
-typedef rt_int16_t	s16_t;
-typedef rt_uint32_t	u32_t;
-typedef rt_int32_t	s32_t;
-typedef rt_uint32_t	mem_ptr_t;
-
-#define U16_F "hu"
-#define S16_F "hd"
-#define X16_F "hx"
-#define U32_F "lu"
-#define S32_F "ld"
-#define X32_F "lx"
-
-#ifdef RT_USING_NEWLIB
-#include <errno.h>
-/* some errno not defined in newlib */
-#define ENSRNOTFOUND 163  /* Domain name not found */
-/* WARNING: ESHUTDOWN also not defined in newlib. We chose
-			180 here because the number "108" which is used
-			in arch.h has been assigned to another error code. */
-#define ESHUTDOWN 180
-#elif RT_USING_MINILIBC
-#include <errno.h>
-#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */
-#else
-#define LWIP_PROVIDE_ERRNO
-#endif
-
-#ifdef RT_USING_MINILIBC
-#include <time.h>
-#define LWIP_TIMEVAL_PRIVATE 0
-#endif
-
-#if defined(__CC_ARM)   /* ARMCC compiler */
-#define PACK_STRUCT_FIELD(x) x
-#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
-#define PACK_STRUCT_BEGIN
-#define PACK_STRUCT_END
-#elif defined(__IAR_SYSTEMS_ICC__)   /* IAR Compiler */
-#define PACK_STRUCT_BEGIN
-#define PACK_STRUCT_STRUCT
-#define PACK_STRUCT_END
-#define PACK_STRUCT_FIELD(x) x
-#define PACK_STRUCT_USE_INCLUDES
-#elif defined(__GNUC__)     /* GNU GCC Compiler */
-#define PACK_STRUCT_FIELD(x) x
-#define PACK_STRUCT_STRUCT __attribute__((packed))
-#define PACK_STRUCT_BEGIN
-#define PACK_STRUCT_END
-#elif defined(_MSC_VER)
-#define PACK_STRUCT_FIELD(x) x
-#define PACK_STRUCT_STRUCT
-#define PACK_STRUCT_BEGIN
-#define PACK_STRUCT_END
-#endif
-
-void sys_arch_assert(const char* file, int line);
-#define LWIP_PLATFORM_DIAG(x)	do {rt_kprintf x;} while(0)
-#define LWIP_PLATFORM_ASSERT(x) do {rt_kprintf(x); sys_arch_assert(__FILE__, __LINE__);}while(0)
-
-
-#include "string.h"
-
-#endif /* __ARCH_CC_H__ */
-

+ 0 - 35
components/net/lwip/src/arch/include/arch/epstruct.h

@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2001-2003 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 lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack()
-#endif

+ 0 - 52
components/net/lwip/src/arch/include/arch/perf.h

@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2001, 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 lwIP TCP/IP stack.
- * 
- * Author: Adam Dunkels <adam@sics.se>
- *
- * $Id: perf.h,v 1.1.1.1 2004/12/16 14:17:13 bear Exp $
- */
-#ifndef __ARCH_PERF_H__
-#define __ARCH_PERF_H__
-
-//#include <sys/times.h>
-
-#define PERF_START    /* null definition */
-#define PERF_STOP(x)  /* null definition */
-
-/*
-void perf_print(unsigned long c1l, unsigned long c1h,
-		unsigned long c2l, unsigned long c2h,
-		char *key);
-
-void perf_print_times(struct tms *start, struct tms *end, char *key);
-
-void perf_init(char *fname);
-*/
-#endif /* __ARCH_PERF_H__ */

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác