From c3ff7276a9bf69e33c89036720bb16daafe14f64 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 9 Mar 2018 14:21:54 +0100 Subject: [PATCH] Initial commit --- .gitignore | 2 + Makefile | 143 +++ README.md | 14 + driver/new_uart.c | 471 +++++++ easygpio/easygpio.c | 343 ++++++ easygpio/easygpio.h | 114 ++ firewall.txt | 14 + firmware/0x00000.bin | Bin 0 -> 36240 bytes firmware/0x10000.bin | Bin 0 -> 231972 bytes include/driver/uart.h | 233 ++++ include/driver/uart_register.h | 156 +++ include/lwip/app/dhcpserver.h | 106 ++ include/lwip/lwip_napt.h | 115 ++ include/lwip/netif.h | 323 +++++ include/lwip/opt.h | 2054 +++++++++++++++++++++++++++++++ include/lwipopts.h | 2097 ++++++++++++++++++++++++++++++++ include/string.h | 1 + liblwip_open_napt.a | Bin 0 -> 323816 bytes user/acl.c | 310 +++++ user/acl.h | 51 + user/config_flash.c | 153 +++ user/config_flash.h | 81 ++ user/ringbuf.c | 250 ++++ user/ringbuf.h | 167 +++ user/sys_time.c | 36 + user/sys_time.h | 13 + user/user_config.h | 38 + user/user_main.c | 1494 +++++++++++++++++++++++ 28 files changed, 8779 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 driver/new_uart.c create mode 100644 easygpio/easygpio.c create mode 100644 easygpio/easygpio.h create mode 100644 firewall.txt create mode 100644 firmware/0x00000.bin create mode 100644 firmware/0x10000.bin create mode 100644 include/driver/uart.h create mode 100644 include/driver/uart_register.h create mode 100644 include/lwip/app/dhcpserver.h create mode 100644 include/lwip/lwip_napt.h create mode 100644 include/lwip/netif.h create mode 100644 include/lwip/opt.h create mode 100644 include/lwipopts.h create mode 100644 include/string.h create mode 100644 liblwip_open_napt.a create mode 100644 user/acl.c create mode 100644 user/acl.h create mode 100644 user/config_flash.c create mode 100644 user/config_flash.h create mode 100644 user/ringbuf.c create mode 100644 user/ringbuf.h create mode 100644 user/sys_time.c create mode 100644 user/sys_time.h create mode 100644 user/user_config.h create mode 100644 user/user_main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dc84959 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..61ef537 --- /dev/null +++ b/Makefile @@ -0,0 +1,143 @@ +# Makefile for ESP8266 projects +# +# Thanks to: +# - zarya +# - Jeroen Domburg (Sprite_tm) +# - Christian Klippel (mamalala) +# - Tommie Gannert (tommie) +# +# Changelog: +# - 2014-10-06: Changed the variables to include the header file directory +# - 2014-10-06: Added global var for the Xtensa tool root +# - 2014-11-23: Updated for SDK 0.9.3 +# - 2014-12-25: Replaced esptool by esptool.py + +BUILD_AREA = /Volumes/case-sensitive/esp8266-dev + +# Output directors to store intermediate compiled files +# relative to the project directory +BUILD_BASE = build +FW_BASE = firmware + +# base directory for the compiler +XTENSA_TOOLS_ROOT ?= $(BUILD_AREA)/esp-open-sdk/xtensa-lx106-elf/bin + +# # base directory of the ESP8266 SDK package, absolute +SDK_BASE ?= $(BUILD_AREA)/esp-open-sdk/sdk + +# # esptool.py path and port +ESPTOOL ?= $(BUILD_AREA)/esp-open-sdk/esptool/esptool.py +#ESPTOOL ?= /home/martin/.local/bin/esptool.py +ESPPORT ?= /dev/tty.wchusbserial1420 +ESPTOOLBAUD ?= 115200 +ESPTOOLOPTS = -ff 40m -fm dio -fs 32m + +# name for the target project +TARGET = app + +# which modules (subdirectories) of the project to include in compiling +MODULES = driver user easygpio +EXTRA_INCDIR = include $(BUILD_AREA)/esp-open-sdk/esp-open-lwip/include +#EXTRA_INCDIR = include + +# libraries used in this project, mainly provided by the SDK +LIBS = c gcc hal pp phy net80211 lwip_open_napt wpa main + +# compiler flags using during compilation of source files +CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -DLWIP_OPEN_SRC -DUSE_OPTIMIZE_PRINTF + +# linker flags used to generate the main object file +LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -L. + +# linker script used for the above linkier step +LD_SCRIPT = eagle.app.v6.ld + +# various paths from the SDK used in this project +SDK_LIBDIR = lib +SDK_LDDIR = ld +SDK_INCDIR = include include/json + +# we create two different files for uploading into the flash +# these are the names and options to generate them +FW_FILE_1_ADDR = 0x00000 +FW_FILE_2_ADDR = 0x10000 + +# select which tools to use as compiler, librarian and linker +CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc +AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar +LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc + + + +#### +#### no user configurable options below here +#### +SRC_DIR := $(MODULES) +BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES)) + +SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR)) +SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) + +SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) +OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) +LIBS := $(addprefix -l,$(LIBS)) +APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) +TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) + +LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) + +INCDIR := $(addprefix -I,$(SRC_DIR)) +EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) +MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) + +FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_FILE_1_ADDR).bin) +FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_FILE_2_ADDR).bin) + +V ?= $(VERBOSE) +ifeq ("$(V)","1") +Q := +vecho := @true +else +Q := @ +vecho := @echo +endif + +vpath %.c $(SRC_DIR) + +define compile-objects +$1/%.o: %.c + $(vecho) "CC $$<" + $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ +endef + +.PHONY: all checkdirs flash clean + +all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2) + +$(FW_BASE)/%.bin: $(TARGET_OUT) | $(FW_BASE) + $(vecho) "FW $(FW_BASE)/" + $(Q) $(ESPTOOL) elf2image -o $(FW_BASE)/ $(TARGET_OUT) + +$(TARGET_OUT): $(APP_AR) + $(vecho) "LD $@" + $(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ + +$(APP_AR): $(OBJ) + $(vecho) "AR $@" + $(Q) $(AR) cru $@ $^ + +checkdirs: $(BUILD_DIR) $(FW_BASE) + +$(BUILD_DIR): + $(Q) mkdir -p $@ + +$(FW_BASE): + $(Q) mkdir -p $@ + +flash: $(FW_FILE_1) $(FW_FILE_2) + $(ESPTOOL) --port $(ESPPORT) --baud $(ESPTOOLBAUD) write_flash $(ESPTOOLOPTS) $(FW_FILE_1_ADDR) $(FW_FILE_1) $(FW_FILE_2_ADDR) $(FW_FILE_2) + +clean: + $(Q) rm -rf $(FW_BASE) $(BUILD_BASE) + +$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir)))) diff --git a/README.md b/README.md new file mode 100644 index 0000000..85401d2 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# ESPerPass +A 3DS HomePass implementation for the ESP8266 programmable WiFi chip. +Inspired by [this reddit post](https://www.reddit.com/r/3DS/comments/80k0qb/homepass_for_cheap_using_an_esp8266/) +and largely based on the great work done by [Martin Ger's ESP WiFi Repeater](https://github.com/martin-ger/esp_wifi_repeater). + +## Instructions (need improvement) +1. Flash firmware. +2. Connect ESP8266 to USB and connect with terminal program. +3. Power cycle ESP8266. +3. Follow instructions in terminal program. + +## TODO +* Implement firewall rules to restrict connections to official servers. +* Implement mac address list management through console. diff --git a/driver/new_uart.c b/driver/new_uart.c new file mode 100644 index 0000000..dde2a24 --- /dev/null +++ b/driver/new_uart.c @@ -0,0 +1,471 @@ +/* + * File : uart.c + * Copyright (C) 2013 - 2016, Espressif Systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of version 3 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, see . + */ +#include "ets_sys.h" +#include "osapi.h" +#include "driver/uart.h" +#include "osapi.h" +#include "driver/uart_register.h" +#include "mem.h" +#include "os_type.h" + +#ifdef _ENABLE_RING_BUFFER + static ringbuf_t rxBuff; + static ringbuf_t txBuff; +#endif + +#ifdef _ENABLE_CONSOLE_INTEGRATION + uint8_t linked_to_console = 0; +#endif + +extern UartDevice UartDev; + +/* Local variables */ +static uint8 uart_recvTaskPrio = 0; + +/* Internal Functions */ +static void ICACHE_FLASH_ATTR uart_config(uint8 uart_no); +static void uart0_rx_intr_handler(void *para); + +/* Public APIs */ +void ICACHE_FLASH_ATTR UART_init(UartBautRate uart0_br, UartBautRate uart1_br, uint8 recv_task_priority); + +#define ENABLE_DEBUG + +#ifdef ENABLE_DEBUG + #define DBG + #define DBG1 os_printf + #define DBG2 os_printf +#else + #define DBG + #define DBG1 + #define DBG2 +#endif + +#if _ENABLE_CONSOLE_INTEGRATION == 1 +void ICACHE_FLASH_ATTR UART_init_console(UartBautRate uart0_br, + uint8 recv_task_priority, + ringbuf_t rxbuffer, + ringbuf_t txBuffer) +{ + /* Set the task which should receive the signals once the data is received */ + uart_recvTaskPrio = recv_task_priority; + + UartDev.baut_rate = uart0_br; + rxBuff = rxbuffer; + txBuff = txBuffer; + linked_to_console = 1; + + uart_config(UART0); + UART_SetPrintPort(UART0); + + UartDev.baut_rate = uart0_br; + uart_config(UART1); + + ETS_UART_INTR_ENABLE(); +} +#endif + +void ICACHE_FLASH_ATTR UART_init(UartBautRate uart0_br, UartBautRate uart1_br, uint8 recv_task_priority) +{ + /* Set the task which should receive the signals once the data is received */ + uart_recvTaskPrio = recv_task_priority; + + UartDev.baut_rate = uart0_br; + uart_config(UART0); + + UART_SetPrintPort(UART0); + + UartDev.baut_rate = uart1_br; + uart_config(UART1); + + ETS_UART_INTR_ENABLE(); + + #if _ENABLE_CONSOLE_INTEGRATION == 0 + #if _ENABLE_RING_BUFFER == 1 + rxBuff = ringbuf_new(RX_RING_BUFFER_SIZE); + #endif + #endif +} + + + +/****************************************************************************** + * FunctionName : uart_config + * Description : Internal used function + * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled + * UART1 just used for debug output + * Parameters : uart_no, use UART0 or UART1 defined ahead + * Returns : NONE +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR uart_config(uint8 uart_no) +{ + if (uart_no == UART1) + { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); + } + else + { + /* rcv_buff size if 0x100 */ + ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + + #if UART_HW_RTS + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); //HW FLOW CONTROL RTS PIN + #endif + + #if UART_HW_CTS + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); //HW FLOW CONTROL CTS PIN + #endif + } + uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE + + WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M) << UART_PARITY_EN_S) //SET BIT AND PARITY MODE + | ((UartDev.parity & UART_PARITY_M) <>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; + + if (fifo_len) + { + max_unload = (fifo_len>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; + //DBG1("RX FIFO FULL [%d]\r\n", fifo_len ); + + if (fifo_len) + { + //DBG1("Rx Fifo contains %d characters have to unload\r\n", fifo_len); + + for (index=0;index>UART_RXFIFO_CNT_S)& UART_RXFIFO_CNT); + uart_rx_intr_disable(UART0); + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); + system_os_post(uart_recvTaskPrio, SIG_UART0, 0); + #endif + + goto end_int_handler; + } + + if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) + { + /* The Time out threshold for Rx/Tx is being execeeded */ + DBG1("Rx Timeout Threshold not being met \r\n"); + uart_rx_intr_disable(UART0); + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); + + system_os_post(uart_recvTaskPrio, SIG_UART0, 0); + goto end_int_handler; + } + + if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)) + { + /* The Tx FIFO is empty, the FIFO needs to be fed with new data */ + DBG1("Tx FIFO is empty\r\n"); + CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); + + #if UART_BUFF_EN + tx_start_uart_buffer(UART0); + #endif + //system_os_post(uart_recvTaskPrio, 1, 0); + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR); + } + +end_int_handler: + return; +} + +/****************************************************************************** + * FunctionName : uart_tx_one_char_no_wait + * Description : uart tx a single char without waiting for fifo + * Parameters : uint8 uart - uart port + * uint8 TxChar - char to tx + * Returns : STATUS +*******************************************************************************/ +STATUS uart_tx_one_char(uint8 uart, uint8 TxChar) +{ + while (true) + { + uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { + break; + } + } + + WRITE_PERI_REG(UART_FIFO(uart) , TxChar); + return OK; +} + +/****************************************************************************** + * FunctionName : uart_tx_one_char_no_wait + * Description : uart tx a single char without waiting for fifo + * Parameters : uint8 uart - uart port + * uint8 TxChar - char to tx + * Returns : STATUS +*******************************************************************************/ +STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar) +{ + uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT); + if (fifo_cnt < 126) + { + WRITE_PERI_REG(UART_FIFO(uart) , TxChar); + } + return OK; +} + + +/****************************************************************************** + * FunctionName : uart0_write_char_no_wait + * Description : tx a single char without waiting for uart 0. + helper function for os_printf output to fifo or tx buffer + * Parameters : uint8 uart - uart port + * uint8 TxChar - char to tx + * Returns : STATUS +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR uart0_write_char_no_wait(char c) +{ +#if UART_BUFF_EN //send to uart0 fifo but do not wait + uint8 chr; + if (c == '\n'){ + chr = '\r'; + tx_buff_enq(&chr, 1); + chr = '\n'; + tx_buff_enq(&chr, 1); + }else if (c == '\r'){ + + }else{ + tx_buff_enq(&c,1); + } +#else //send to uart tx buffer + if (c == '\n') + { + uart_tx_one_char(UART0, '\r'); + uart_tx_one_char(UART0, '\n'); + + //uart_tx_one_char_no_wait(UART0, '\r'); + //uart_tx_one_char_no_wait(UART0, '\n'); + } + else + if (c == '\r') + { + uart_tx_one_char(UART0, c); + } + else + { + uart_tx_one_char(UART0, c); + //uart_tx_one_char_no_wait(UART0, c); + } +#endif +} + + +/****************************************************************************** + * FunctionName : UART_SetPrintPort + * Description : + * + * Parameters : + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR UART_SetPrintPort(uint8 uart_no) +{ + if(uart_no==1) + { + //os_install_putc1(uart1_write_char); + } + else + { + /*option 1: do not wait if uart fifo is full,drop current character*/ + //os_install_putc1(uart0_write_char_no_wait); + /*option 2: wait for a while if uart fifo is full*/ + //os_install_putc1(uart0_write_char); + } +} + diff --git a/easygpio/easygpio.c b/easygpio/easygpio.c new file mode 100644 index 0000000..0d386b1 --- /dev/null +++ b/easygpio/easygpio.c @@ -0,0 +1,343 @@ +/* +* easygpio.c +* +* Copyright (c) 2015, eadf (https://github.com/eadf) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* * Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Redis nor the names of its contributors may be used +* to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "easygpio.h" +#include "gpio.h" +#include "osapi.h" +#include "ets_sys.h" + +#define EASYGPIO_USE_GPIO_INPUT_GET + +static void ICACHE_FLASH_ATTR +gpio16_output_conf(void) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, + (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbcUL) | 0x1UL); // mux configuration for XPD_DCDC to output rtc_gpio0 + + WRITE_PERI_REG(RTC_GPIO_CONF, + (READ_PERI_REG(RTC_GPIO_CONF) & 0xfffffffeUL) | 0x0UL); //mux configuration for out enable + + WRITE_PERI_REG(RTC_GPIO_ENABLE, + (READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL) | 0x1UL); //out enable +} + +static void ICACHE_FLASH_ATTR +gpio16_input_conf(void) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, + (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbcUL) | 0x1UL); // mux configuration for XPD_DCDC and rtc_gpio0 connection + + WRITE_PERI_REG(RTC_GPIO_CONF, + (READ_PERI_REG(RTC_GPIO_CONF) & 0xfffffffeUL) | 0x0UL); //mux configuration for out enable + + WRITE_PERI_REG(RTC_GPIO_ENABLE, + READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL); //out disable +} + +/** + * Returns the number of active pins in the gpioMask. + */ +uint8_t ICACHE_FLASH_ATTR +easygpio_countBits(uint32_t gpioMask) { + + uint8_t i=0; + uint8_t numberOfPins=0; + for (i=0; i<32; i++){ + numberOfPins += (gpioMask & BIT(i))?1:0; + } + return numberOfPins; +} + +/** + * Returns the gpio name and func for a specific pin. + */ +bool ICACHE_FLASH_ATTR +easygpio_getGPIONameFunc(uint8_t gpio_pin, uint32_t *gpio_name, uint8_t *gpio_func) { + + if (gpio_pin == 6 || gpio_pin == 7 || gpio_pin == 8 || gpio_pin == 11 || gpio_pin >= 17) { + os_printf("easygpio_getGPIONameFunc Error: There is no GPIO%d, check your code\n", gpio_pin); + return false; + } + if (gpio_pin == 16) { + os_printf("easygpio_getGPIONameFunc Error: GPIO16 does not have gpio_name and gpio_func\n"); + return false; + } + switch ( gpio_pin ) { + case 0: + *gpio_func = FUNC_GPIO0; + *gpio_name = PERIPHS_IO_MUX_GPIO0_U; + return true; + case 1: + *gpio_func = FUNC_GPIO1; + *gpio_name = PERIPHS_IO_MUX_U0TXD_U; + return true; + case 2: + *gpio_func = FUNC_GPIO2; + *gpio_name = PERIPHS_IO_MUX_GPIO2_U; + return true; + case 3: + *gpio_func = FUNC_GPIO3; + *gpio_name = PERIPHS_IO_MUX_U0RXD_U; + return true; + case 4: + *gpio_func = FUNC_GPIO4; + *gpio_name = PERIPHS_IO_MUX_GPIO4_U; + return true; + case 5: + *gpio_func = FUNC_GPIO5; + *gpio_name = PERIPHS_IO_MUX_GPIO5_U; + return true; + case 9: + *gpio_func = FUNC_GPIO9; + *gpio_name = PERIPHS_IO_MUX_SD_DATA2_U; + return true; + case 10: + *gpio_func = FUNC_GPIO10; + *gpio_name = PERIPHS_IO_MUX_SD_DATA3_U; + return true; + case 12: + *gpio_func = FUNC_GPIO12; + *gpio_name = PERIPHS_IO_MUX_MTDI_U; + return true; + case 13: + *gpio_func = FUNC_GPIO13; + *gpio_name = PERIPHS_IO_MUX_MTCK_U; + return true; + case 14: + *gpio_func = FUNC_GPIO14; + *gpio_name = PERIPHS_IO_MUX_MTMS_U; + return true; + case 15: + *gpio_func = FUNC_GPIO15; + *gpio_name = PERIPHS_IO_MUX_MTDO_U; + return true; + default: + return false; + } + return true; +} + +/** + * Sets the pull up registers for a pin. + */ +static void ICACHE_FLASH_ATTR +easygpio_setupPullsByName(uint32_t gpio_name, EasyGPIO_PullStatus pullStatus) { + + if (EASYGPIO_PULLUP == pullStatus) { + PIN_PULLUP_EN(gpio_name); + } else { + PIN_PULLUP_DIS(gpio_name); + } +} + +/** + * Sets the pull registers for a pin. + */ +bool ICACHE_FLASH_ATTR +easygpio_pullMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus) { + uint32_t gpio_name; + uint8_t gpio_func; + + if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) { + return false; + } + + easygpio_setupPullsByName(gpio_name, pullStatus); + return true; +} + +/** + * Sets the 'gpio_pin' pin as a GPIO and sets the pull register for that pin. + * 'pullStatus' has no effect on output pins or GPIO16 + */ +bool ICACHE_FLASH_ATTR +easygpio_pinMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, EasyGPIO_PinMode pinMode) { + uint32_t gpio_name; + uint8_t gpio_func; + + if (16==gpio_pin) { + // ignoring pull status on GPIO16 for now + if (EASYGPIO_OUTPUT == pinMode) { + gpio16_output_conf(); + } else { + gpio16_input_conf(); + } + return true; + } else if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) { + return false; + } + + PIN_FUNC_SELECT(gpio_name, gpio_func); + easygpio_setupPullsByName(gpio_name, pullStatus); + + if (EASYGPIO_OUTPUT != pinMode) { + GPIO_DIS_OUTPUT(GPIO_ID_PIN(gpio_pin)); + } else { + // must enable the pin or else the WRITE_PERI_REG won't work + gpio_output_set(0, 0, BIT(GPIO_ID_PIN(gpio_pin)),0); + } + return true; +} + +/** + * Sets the 'gpio_pin' pin as a GPIO and sets the interrupt to trigger on that pin. + * The 'interruptArg' is the function argument that will be sent to your interruptHandler + */ +bool ICACHE_FLASH_ATTR +easygpio_attachInterrupt(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, void (*interruptHandler)(void *arg), void *interruptArg) { + uint32_t gpio_name; + uint8_t gpio_func; + + if (gpio_pin == 16) { + os_printf("easygpio_setupInterrupt Error: GPIO16 does not have interrupts\n"); + return false; + } + if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) { + return false; + } + + ETS_GPIO_INTR_ATTACH(interruptHandler, interruptArg); + ETS_GPIO_INTR_DISABLE(); + + PIN_FUNC_SELECT(gpio_name, gpio_func); + + easygpio_setupPullsByName(gpio_name, pullStatus); + + // disable output + GPIO_DIS_OUTPUT(gpio_pin); + + gpio_register_set(GPIO_PIN_ADDR(gpio_pin), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) + | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) + | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); + + //clear gpio14 status + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(gpio_pin)); + ETS_GPIO_INTR_ENABLE(); + + return true; +} + +/** + * Detach the interrupt handler from the 'gpio_pin' pin. + */ +bool ICACHE_FLASH_ATTR +easygpio_detachInterrupt(uint8_t gpio_pin) { + + if (gpio_pin == 16) { + os_printf("easygpio_setupInterrupt Error: GPIO16 does not have interrupts\n"); + return false; + } + + // Don't know how to detach interrupt, yet. + // Quick and dirty fix - just disable the interrupt + gpio_pin_intr_state_set(GPIO_ID_PIN(gpio_pin), GPIO_PIN_INTR_DISABLE); + return true; +} + +/** + * Uniform way of setting GPIO output value. Handles GPIO 0-16. + * + * You can not rely on that this function will switch the gpio to an output like GPIO_OUTPUT_SET does. + * Use easygpio_outputEnable() to change an input gpio to output mode. + */ +void +easygpio_outputSet(uint8_t gpio_pin, uint8_t value) { + if (16==gpio_pin) { + WRITE_PERI_REG(RTC_GPIO_OUT, + (READ_PERI_REG(RTC_GPIO_OUT) & 0xfffffffeUL) | (0x1UL & value)); + } else { +#ifdef EASYGPIO_USE_GPIO_OUTPUT_SET + GPIO_OUTPUT_SET(GPIO_ID_PIN(gpio_pin), value); +#else + if (value&1){ + WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR, READ_PERI_REG(PERIPHS_GPIO_BASEADDR) | BIT(gpio_pin)); + } else { + WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR, READ_PERI_REG(PERIPHS_GPIO_BASEADDR) & ~BIT(gpio_pin)); + } +#endif + } +} + +/** + * Uniform way of getting GPIO input value. Handles GPIO 0-16. + * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. + * If you know that you won't be using GPIO16 then you'd better off by just using GPIO_INPUT_GET(). + */ +uint8_t +easygpio_inputGet(uint8_t gpio_pin) { + if (16==gpio_pin) { + return (READ_PERI_REG(RTC_GPIO_IN_DATA) & 1UL); + } else { +#ifdef EASYGPIO_USE_GPIO_INPUT_GET + return GPIO_INPUT_GET(GPIO_ID_PIN(gpio_pin)); +#else + // this does *not* work, maybe GPIO_IN_ADDRESS is the wrong address + return ((GPIO_REG_READ(GPIO_IN_ADDRESS) > gpio_pin) & 1UL); +#endif + } +} + +/** + * Uniform way of turning an output GPIO pin into input mode. Handles GPIO 0-16. + * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. + * This function does the same thing as GPIO_DIS_OUTPUT, but works on GPIO16 too. + */ +void easygpio_outputDisable(uint8_t gpio_pin) { + if (16==gpio_pin) { + WRITE_PERI_REG(RTC_GPIO_ENABLE, + READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL); //out disable + } else { + GPIO_DIS_OUTPUT(GPIO_ID_PIN(gpio_pin)); + } +} + +/** + * Uniform way of turning an input GPIO pin into output mode. Handles GPIO 0-16. + * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. + * + * This function: + * - should only be used to convert a input pin into an output pin. + * - is a little bit slower than easygpio_outputSet() so you should use that + * function to just change output value. + * - does the same thing as GPIO_OUTPUT_SET, but works on GPIO16 too. + */ +void easygpio_outputEnable(uint8_t gpio_pin, uint8_t value) { + if (16==gpio_pin) { + // write the value before flipping to output + // - so we don't flash previous value for a few ns. + WRITE_PERI_REG(RTC_GPIO_OUT, + (READ_PERI_REG(RTC_GPIO_OUT) & 0xfffffffeUL) | (0x1UL & value)); + + WRITE_PERI_REG(RTC_GPIO_ENABLE, + (READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL) | 0x1UL); //out enable + + } else { + GPIO_OUTPUT_SET(GPIO_ID_PIN(gpio_pin), value); + } +} diff --git a/easygpio/easygpio.h b/easygpio/easygpio.h new file mode 100644 index 0000000..82c7f26 --- /dev/null +++ b/easygpio/easygpio.h @@ -0,0 +1,114 @@ +/* +* easygpio.h +* +* Copyright (c) 2015, eadf (https://github.com/eadf) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* * Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Redis nor the names of its contributors may be used +* to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_ +#define EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_ + +#include "c_types.h" + +typedef enum { + EASYGPIO_INPUT=0, + EASYGPIO_OUTPUT=1 +} EasyGPIO_PinMode; + +typedef enum { + EASYGPIO_PULLUP=3, + EASYGPIO_NOPULL=4 +} EasyGPIO_PullStatus; + +/** + * Returns the gpio name and func for a specific pin. + */ +bool easygpio_getGPIONameFunc(uint8_t gpio_pin, uint32_t *gpio_name, uint8_t *gpio_func); + +/** + * Sets the 'gpio_pin' pin as a GPIO and sets the interrupt to trigger on that pin. + * The 'interruptArg' is the function argument that will be sent to your interruptHandler + * (this way you can several interrupts with one interruptHandler) + */ +bool easygpio_attachInterrupt(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, void (*interruptHandler)(void *arg), void *interruptArg); + +/** + * Deatach the interrupt handler from the 'gpio_pin' pin. + */ +bool easygpio_detachInterrupt(uint8_t gpio_pin); + +/** + * Returns the number of active pins in the gpioMask. + */ +uint8_t easygpio_countBits(uint32_t gpioMask); + +/** + * Sets the 'gpio_pin' pin as a GPIO and enables/disables the pull-up on that pin. + * 'pullStatus' has no effect on output pins or GPIO16 + */ +bool easygpio_pinMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, EasyGPIO_PinMode pinMode); + +/** + * Enable or disable the internal pull up for a pin. + */ +bool easygpio_pullMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus); + +/** + * Uniform way of getting GPIO input value. Handles GPIO 0-16. + * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. + * If you know that you won't be using GPIO16 then you'd better off by just using GPIO_INPUT_GET(). + */ +uint8_t easygpio_inputGet(uint8_t gpio_pin); + +/** + * Uniform way of setting GPIO output value. Handles GPIO 0-16. + * + * You can not rely on that this function will switch the gpio to an output like GPIO_OUTPUT_SET does. + * Use easygpio_outputEnable() to change an input gpio to output mode. + */ +void easygpio_outputSet(uint8_t gpio_pin, uint8_t value); + +/** + * Uniform way of turning an output GPIO pin into input mode. Handles GPIO 0-16. + * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. + * This function does the same thing as GPIO_DIS_OUTPUT, but works on GPIO16 too. + */ +void easygpio_outputDisable(uint8_t gpio_pin); + +/** + * Uniform way of turning an input GPIO pin into output mode. Handles GPIO 0-16. + * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. + * + * This function: + * - should only be used to convert a input pin into an output pin. + * - is a little bit slower than easygpio_outputSet() so you should use that + * function to just change output value. + * - does the same thing as GPIO_OUTPUT_SET, but works on GPIO16 too. + */ +void easygpio_outputEnable(uint8_t gpio_pin, uint8_t value); + +#endif /* EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_ */ diff --git a/firewall.txt b/firewall.txt new file mode 100644 index 0000000..6d9ea93 --- /dev/null +++ b/firewall.txt @@ -0,0 +1,14 @@ +# Scrapbook of firewall rules to restrict connections only +# to official servers. + +# Clear outging rules +acl from_sta clear + +# Allow outgoing connections to specified IP +acl from_sta IP any 185.43.124.6 allow + +# Allow outgoing DNS requests +acl from_sta UDP any any any 53 allow + +# Deny everything else +acl from_sta IP any any deny diff --git a/firmware/0x00000.bin b/firmware/0x00000.bin new file mode 100644 index 0000000000000000000000000000000000000000..a1de31c8c71f399fdb477ed103a9b81587e0f0c7 GIT binary patch literal 36240 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 literal 0 HcmV?d00001 diff --git a/firmware/0x10000.bin b/firmware/0x10000.bin new file mode 100644 index 0000000000000000000000000000000000000000..ccf58079c4697b59bd8339a59e255878b374b3ba GIT binary patch literal 231972 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

VZGmY4c%N8iXC-J3 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

5L2_RnrYFI}SvMm9WCZHF4o*?8n8WL~9*^~m> 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%0DI*TfQS}(l6;ezO9Ed^rcfyFG$;AR0*WP?Vxaf}L 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 AvH$=8 literal 0 HcmV?d00001 diff --git a/include/driver/uart.h b/include/driver/uart.h new file mode 100644 index 0000000..b9bf4ed --- /dev/null +++ b/include/driver/uart.h @@ -0,0 +1,233 @@ +/* + * File : uart.h + * Copyright (C) 2013 - 2016, Espressif Systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of version 3 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, see . + */ +#ifndef UART_APP_H +#define UART_APP_H + +#include "uart_register.h" +#include "eagle_soc.h" +#include "c_types.h" + +#define UART_TX_BUFFER_SIZE 256 //Ring buffer length of tx buffer +#define UART_RX_BUFFER_SIZE 256 //Ring buffer length of rx buffer + +#define UART_BUFF_EN 0 //use uart buffer , FOR UART0 +#define UART_SELFTEST 0 //set 1:enable the loop test demo for uart buffer, FOR UART0 + +#define UART_HW_RTS 0 //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0 +#define UART_HW_CTS 0 //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0 + +#define _ENABLE_CONSOLE_INTEGRATION 1 +#define _ENABLE_RING_BUFFER 1 + +#ifdef _ENABLE_RING_BUFFER + #include "ringbuf.h" + #define RX_RING_BUFFER_SIZE 250 +#endif + + + +#define UART0 0 +#define UART1 1 + + +typedef enum { + FIVE_BITS = 0x0, + SIX_BITS = 0x1, + SEVEN_BITS = 0x2, + EIGHT_BITS = 0x3 +} UartBitsNum4Char; + +typedef enum { + ONE_STOP_BIT = 0x1, + ONE_HALF_STOP_BIT = 0x2, + TWO_STOP_BIT = 0x3 +} UartStopBitsNum; + +typedef enum { + NONE_BITS = 0x2, + ODD_BITS = 1, + EVEN_BITS = 0 +} UartParityMode; + +typedef enum { + STICK_PARITY_DIS = 0, + STICK_PARITY_EN = 1 +} UartExistParity; + +typedef enum { + UART_None_Inverse = 0x0, + UART_Rxd_Inverse = UART_RXD_INV, + UART_CTS_Inverse = UART_CTS_INV, + UART_Txd_Inverse = UART_TXD_INV, + UART_RTS_Inverse = UART_RTS_INV, +} UART_LineLevelInverse; + + +typedef enum { + BIT_RATE_300 = 300, + BIT_RATE_600 = 600, + BIT_RATE_1200 = 1200, + BIT_RATE_2400 = 2400, + BIT_RATE_4800 = 4800, + BIT_RATE_9600 = 9600, + BIT_RATE_19200 = 19200, + BIT_RATE_38400 = 38400, + BIT_RATE_57600 = 57600, + BIT_RATE_74880 = 74880, + BIT_RATE_115200 = 115200, + BIT_RATE_230400 = 230400, + BIT_RATE_460800 = 460800, + BIT_RATE_921600 = 921600, + BIT_RATE_1843200 = 1843200, + BIT_RATE_3686400 = 3686400, +} UartBautRate; + +typedef enum { + NONE_CTRL, + HARDWARE_CTRL, + XON_XOFF_CTRL +} UartFlowCtrl; + +typedef enum { + USART_HardwareFlowControl_None = 0x0, + USART_HardwareFlowControl_RTS = 0x1, + USART_HardwareFlowControl_CTS = 0x2, + USART_HardwareFlowControl_CTS_RTS = 0x3 +} UART_HwFlowCtrl; + +typedef enum { + EMPTY, + UNDER_WRITE, + WRITE_OVER +} RcvMsgBuffState; + +typedef struct { + uint32 RcvBuffSize; + uint8 *pRcvMsgBuff; + uint8 *pWritePos; + uint8 *pReadPos; + uint8 TrigLvl; //JLU: may need to pad + RcvMsgBuffState BuffState; +} RcvMsgBuff; + +typedef struct { + uint32 TrxBuffSize; + uint8 *pTrxBuff; +} TrxMsgBuff; + +typedef enum { + BAUD_RATE_DET, + WAIT_SYNC_FRM, + SRCH_MSG_HEAD, + RCV_MSG_BODY, + RCV_ESC_CHAR, +} RcvMsgState; + +typedef struct { + UartBautRate baut_rate; + UartBitsNum4Char data_bits; + UartExistParity exist_parity; + UartParityMode parity; + UartStopBitsNum stop_bits; + UartFlowCtrl flow_ctrl; + RcvMsgBuff rcv_buff; + TrxMsgBuff trx_buff; + RcvMsgState rcv_state; + int received; + int buff_uart_no; //indicate which uart use tx/rx buffer +} UartDevice; + +void uart_init(UartBautRate uart0_br, UartBautRate uart1_br); +void uart0_sendStr(const char *str); + + +/////////////////////////////////////// +#define UART_FIFO_LEN 128 //define the tx fifo length +#define UART_TX_EMPTY_THRESH_VAL 0x10 + + + struct UartBuffer{ + uint32 UartBuffSize; + uint8 *pUartBuff; + uint8 *pInPos; + uint8 *pOutPos; + STATUS BuffState; + uint16 Space; //remanent space of the buffer + uint8 TcpControl; + struct UartBuffer * nextBuff; +}; + +struct UartRxBuff{ + uint32 UartRxBuffSize; + uint8 *pUartRxBuff; + uint8 *pWritePos; + uint8 *pReadPos; + STATUS RxBuffState; + uint32 Space; //remanent space of the buffer +} ; + +typedef enum { + RUN = 0, + BLOCK = 1, +} TCPState; + +//void ICACHE_FLASH_ATTR uart_test_rx(); +STATUS uart_tx_one_char(uint8 uart, uint8 TxChar); +STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar); +void uart1_sendStr_no_wait(const char *str); +struct UartBuffer* Uart_Buf_Init(); + + +#if UART_BUFF_EN +LOCAL void Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len); +void uart_buf_free(struct UartBuffer* pBuff); +void tx_buff_enq(char* pdata, uint16 data_len ); +LOCAL void tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len, uint8 uart_no); +void tx_start_uart_buffer(uint8 uart_no); +uint16 rx_buff_deq(char* pdata, uint16 data_len ); +void Uart_rx_buff_enq(); +#endif +void uart_rx_intr_enable(uint8 uart_no); +void uart_rx_intr_disable(uint8 uart_no); +void uart0_tx_buffer(uint8 *buf, uint16 len); + +//============================================== +#define FUNC_UART0_CTS 4 +#define FUNC_U0CTS 4 +#define FUNC_U1TXD_BK 2 +#define UART_LINE_INV_MASK (0x3f<<19) +void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len); +void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num); +void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask); +void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode); +void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate); +void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh); +void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled +void UART_ResetFifo(uint8 uart_no); +void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask); +void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask); +void UART_SetPrintPort(uint8 uart_no); +bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us); +//============================================== + +void UART_init_console(UartBautRate uart0_br, + uint8 recv_task_priority, + ringbuf_t rxbuffer, + ringbuf_t txBuffer); + +#endif + diff --git a/include/driver/uart_register.h b/include/driver/uart_register.h new file mode 100644 index 0000000..05f6cea --- /dev/null +++ b/include/driver/uart_register.h @@ -0,0 +1,156 @@ +/* + * File : uart_register.h + * Copyright (C) 2013 - 2016, Espressif Systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of version 3 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, see . + */ +/* + * Copyright (c) 2010 - 2011 Espressif System + * + */ + +#ifndef UART_REGISTER_H_ +#define UART_REGISTER_H_ + +#define REG_UART_BASE(i) (0x60000000 + (i)*0xf00) +//version value:32'h062000 + +#define UART_FIFO(i) (REG_UART_BASE(i) + 0x0) +#define UART_RXFIFO_RD_BYTE 0x000000FF +#define UART_RXFIFO_RD_BYTE_S 0 + +#define UART_INT_RAW(i) (REG_UART_BASE(i) + 0x4) +#define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) +#define UART_BRK_DET_INT_RAW (BIT(7)) +#define UART_CTS_CHG_INT_RAW (BIT(6)) +#define UART_DSR_CHG_INT_RAW (BIT(5)) +#define UART_RXFIFO_OVF_INT_RAW (BIT(4)) +#define UART_FRM_ERR_INT_RAW (BIT(3)) +#define UART_PARITY_ERR_INT_RAW (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) +#define UART_RXFIFO_FULL_INT_RAW (BIT(0)) + +#define UART_INT_ST(i) (REG_UART_BASE(i) + 0x8) +#define UART_RXFIFO_TOUT_INT_ST (BIT(8)) +#define UART_BRK_DET_INT_ST (BIT(7)) +#define UART_CTS_CHG_INT_ST (BIT(6)) +#define UART_DSR_CHG_INT_ST (BIT(5)) +#define UART_RXFIFO_OVF_INT_ST (BIT(4)) +#define UART_FRM_ERR_INT_ST (BIT(3)) +#define UART_PARITY_ERR_INT_ST (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) +#define UART_RXFIFO_FULL_INT_ST (BIT(0)) + +#define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC) +#define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) +#define UART_BRK_DET_INT_ENA (BIT(7)) +#define UART_CTS_CHG_INT_ENA (BIT(6)) +#define UART_DSR_CHG_INT_ENA (BIT(5)) +#define UART_RXFIFO_OVF_INT_ENA (BIT(4)) +#define UART_FRM_ERR_INT_ENA (BIT(3)) +#define UART_PARITY_ERR_INT_ENA (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) +#define UART_RXFIFO_FULL_INT_ENA (BIT(0)) + +#define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10) +#define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) +#define UART_BRK_DET_INT_CLR (BIT(7)) +#define UART_CTS_CHG_INT_CLR (BIT(6)) +#define UART_DSR_CHG_INT_CLR (BIT(5)) +#define UART_RXFIFO_OVF_INT_CLR (BIT(4)) +#define UART_FRM_ERR_INT_CLR (BIT(3)) +#define UART_PARITY_ERR_INT_CLR (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) +#define UART_RXFIFO_FULL_INT_CLR (BIT(0)) + +#define UART_CLKDIV(i) (REG_UART_BASE(i) + 0x14) +#define UART_CLKDIV_CNT 0x000FFFFF +#define UART_CLKDIV_S 0 + +#define UART_AUTOBAUD(i) (REG_UART_BASE(i) + 0x18) +#define UART_GLITCH_FILT 0x000000FF +#define UART_GLITCH_FILT_S 8 +#define UART_AUTOBAUD_EN (BIT(0)) + +#define UART_STATUS(i) (REG_UART_BASE(i) + 0x1C) +#define UART_TXD (BIT(31)) +#define UART_RTSN (BIT(30)) +#define UART_DTRN (BIT(29)) +#define UART_TXFIFO_CNT 0x000000FF +#define UART_TXFIFO_CNT_S 16 +#define UART_RXD (BIT(15)) +#define UART_CTSN (BIT(14)) +#define UART_DSRN (BIT(13)) +#define UART_RXFIFO_CNT 0x000000FF +#define UART_RXFIFO_CNT_S 0 + +#define UART_CONF0(i) (REG_UART_BASE(i) + 0x20) +#define UART_DTR_INV (BIT(24)) +#define UART_RTS_INV (BIT(23)) +#define UART_TXD_INV (BIT(22)) +#define UART_DSR_INV (BIT(21)) +#define UART_CTS_INV (BIT(20)) +#define UART_RXD_INV (BIT(19)) +#define UART_TXFIFO_RST (BIT(18)) +#define UART_RXFIFO_RST (BIT(17)) +#define UART_IRDA_EN (BIT(16)) +#define UART_TX_FLOW_EN (BIT(15)) +#define UART_LOOPBACK (BIT(14)) +#define UART_IRDA_RX_INV (BIT(13)) +#define UART_IRDA_TX_INV (BIT(12)) +#define UART_IRDA_WCTL (BIT(11)) +#define UART_IRDA_TX_EN (BIT(10)) +#define UART_IRDA_DPLX (BIT(9)) +#define UART_TXD_BRK (BIT(8)) +#define UART_SW_DTR (BIT(7)) +#define UART_SW_RTS (BIT(6)) +#define UART_STOP_BIT_NUM 0x00000003 +#define UART_STOP_BIT_NUM_S 4 +#define UART_BIT_NUM 0x00000003 +#define UART_BIT_NUM_S 2 +#define UART_PARITY_EN (BIT(1)) +#define UART_PARITY_EN_M 0x00000001 +#define UART_PARITY_EN_S 1 +#define UART_PARITY (BIT(0)) +#define UART_PARITY_M 0x00000001 +#define UART_PARITY_S 0 + +#define UART_CONF1(i) (REG_UART_BASE(i) + 0x24) +#define UART_RX_TOUT_EN (BIT(31)) +#define UART_RX_TOUT_THRHD 0x0000007F +#define UART_RX_TOUT_THRHD_S 24 +#define UART_RX_FLOW_EN (BIT(23)) +#define UART_RX_FLOW_THRHD 0x0000007F +#define UART_RX_FLOW_THRHD_S 16 +#define UART_TXFIFO_EMPTY_THRHD 0x0000007F +#define UART_TXFIFO_EMPTY_THRHD_S 8 +#define UART_RXFIFO_FULL_THRHD 0x0000007F +#define UART_RXFIFO_FULL_THRHD_S 0 + +#define UART_LOWPULSE(i) (REG_UART_BASE(i) + 0x28) +#define UART_LOWPULSE_MIN_CNT 0x000FFFFF +#define UART_LOWPULSE_MIN_CNT_S 0 + +#define UART_HIGHPULSE(i) (REG_UART_BASE(i) + 0x2C) +#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF +#define UART_HIGHPULSE_MIN_CNT_S 0 + +#define UART_PULSE_NUM(i) (REG_UART_BASE(i) + 0x30) +#define UART_PULSE_NUM_CNT 0x0003FF +#define UART_PULSE_NUM_CNT_S 0 + +#define UART_DATE(i) (REG_UART_BASE(i) + 0x78) +#define UART_ID(i) (REG_UART_BASE(i) + 0x7C) + +#endif // UART_REGISTER_H_INCLUDED + diff --git a/include/lwip/app/dhcpserver.h b/include/lwip/app/dhcpserver.h new file mode 100644 index 0000000..a11f137 --- /dev/null +++ b/include/lwip/app/dhcpserver.h @@ -0,0 +1,106 @@ +#ifndef __DHCPS_H__ +#define __DHCPS_H__ + +#define USE_DNS + +typedef struct dhcps_state{ + sint16_t state; +} dhcps_state; + +// ����dhcpclient�Զ����һ��DHCP msg�ṹ�� +typedef struct dhcps_msg { + uint8_t op, htype, hlen, hops; + uint8_t xid[4]; + uint16_t secs, flags; + uint8_t ciaddr[4]; + uint8_t yiaddr[4]; + uint8_t siaddr[4]; + uint8_t giaddr[4]; + uint8_t chaddr[16]; + uint8_t sname[64]; + uint8_t file[128]; + uint8_t options[312]; +}dhcps_msg; + +#ifndef LWIP_OPEN_SRC +struct dhcps_lease { + bool enable; + struct ip_addr start_ip; + struct ip_addr end_ip; +}; + +enum dhcps_offer_option{ + OFFER_START = 0x00, + OFFER_ROUTER = 0x01, + OFFER_END +}; +#endif + +struct dhcps_pool{ + struct ip_addr ip; + uint8 mac[6]; + uint32 lease_timer; +}; + +typedef struct _list_node{ + void *pnode; + struct _list_node *pnext; +}list_node; + +extern uint32 dhcps_lease_time; +#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 +#define DHCPS_MAX_LEASE 0x64 +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPS_SERVER_PORT 67 +#define DHCPS_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_INTERFACE_MTU 26 +#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 +#define DHCP_OPTION_BROADCAST_ADDRESS 28 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +//#define USE_CLASS_B_NET 1 +#define DHCPS_DEBUG 0 +#define MAX_STATION_NUM 8 + +#define DHCPS_STATE_OFFER 1 +#define DHCPS_STATE_DECLINE 2 +#define DHCPS_STATE_ACK 3 +#define DHCPS_STATE_NAK 4 +#define DHCPS_STATE_IDLE 5 +#define DHCPS_STATE_RELEASE 6 + +#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) + +void dhcps_start(struct ip_info *info); +void dhcps_stop(void); + +void dhcps_set_DNS(struct ip_addr *dns_ip) ICACHE_FLASH_ATTR; +struct dhcps_pool *dhcps_get_mapping(uint16_t no) ICACHE_FLASH_ATTR; +void dhcps_set_mapping(struct ip_addr *addr, uint8 *mac, uint32 lease_time) ICACHE_FLASH_ATTR; + +#endif + diff --git a/include/lwip/lwip_napt.h b/include/lwip/lwip_napt.h new file mode 100644 index 0000000..6784ec9 --- /dev/null +++ b/include/lwip/lwip_napt.h @@ -0,0 +1,115 @@ +#ifndef __LWIP_NAPT_H__ +#define __LWIP_NAPT_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if IP_FORWARD +#if IP_NAPT + +/* Default size of the tables used for NAPT */ +#define IP_NAPT_MAX 512 +#define IP_PORTMAP_MAX 32 + +/* Timeouts in sec for the various protocol types */ +#define IP_NAPT_TIMEOUT_MS_TCP (30*60*1000) +#define IP_NAPT_TIMEOUT_MS_TCP_DISCON (20*1000) +#define IP_NAPT_TIMEOUT_MS_UDP (2*1000) +#define IP_NAPT_TIMEOUT_MS_ICMP (2*1000) + +#define IP_NAPT_PORT_RANGE_START 49152 +#define IP_NAPT_PORT_RANGE_END 61439 + +struct napt_table { + u32_t last; + u32_t src; + u32_t dest; + u16_t sport; + u16_t dport; + u16_t mport; + u8_t proto; + u8_t fin1 : 1; + u8_t fin2 : 1; + u8_t finack1 : 1; + u8_t finack2 : 1; + u8_t synack : 1; + u8_t rst : 1; + u16_t next, prev; +}; + +struct portmap_table { + u32_t maddr; + u32_t daddr; + u16_t mport; + u16_t dport; + u8_t proto; + u8 valid; +}; + +extern struct portmap_table *ip_portmap_table; + +/** + * Allocates and initializes the NAPT tables. + * + * @param max_nat max number of enties in the NAPT table (use IP_NAPT_MAX if in doubt) + * @param max_portmap max number of enties in the NAPT table (use IP_PORTMAP_MAX if in doubt) + */ +void ICACHE_FLASH_ATTR +ip_napt_init(uint16_t max_nat, uint8_t max_portmap); + + +/** + * Enable/Disable NAPT for a specified interface. + * + * @param addr ip address of the interface + * @param enable non-zero to enable NAPT, or 0 to disable. + */ +void ICACHE_FLASH_ATTR +ip_napt_enable(u32_t addr, int enable); + + +/** + * Enable/Disable NAPT for a specified interface. + * + * @param netif number of the interface + * @param enable non-zero to enable NAPT, or 0 to disable. + */ +void ICACHE_FLASH_ATTR +ip_napt_enable_no(u8_t number, int enable); + + +/** + * Register port mapping on the external interface to internal interface. + * When the same port mapping is registered again, the old mapping is overwritten. + * In this implementation, only 1 unique port mapping can be defined for each target address/port. + * + * @param proto target protocol + * @param maddr ip address of the external interface + * @param mport mapped port on the external interface, in host byte order. + * @param daddr destination ip address + * @param dport destination port, in host byte order. + */ +u8_t ICACHE_FLASH_ATTR +ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport); + + +/** + * Unregister port mapping on the external interface to internal interface. + * + * @param proto target protocol + * @param maddr ip address of the external interface + */ +u8_t ICACHE_FLASH_ATTR +ip_portmap_remove(u8_t proto, u16_t mport); + +#endif /* IP_NAPT */ +#endif /* IP_FORWARD */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NAPT_H__ */ diff --git a/include/lwip/netif.h b/include/lwip/netif.h new file mode 100644 index 0000000..c6b85e5 --- /dev/null +++ b/include/lwip/netif.h @@ -0,0 +1,323 @@ +/* + * 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 + * + */ +#ifndef __LWIP_NETIF_H__ +#define __LWIP_NETIF_H__ + +#include "lwip/opt.h" + +#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) + +#include "lwip/err.h" + +#include "lwip/ip_addr.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#if LWIP_DHCP +struct dhcp; +#endif +#if LWIP_AUTOIP +struct autoip; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses are expected to be in + * the same byte order as in IP_PCB. */ + +/** must be the maximum of all used hardware address lengths + across all types of interfaces in use */ +#define NETIF_MAX_HWADDR_LEN 6U + +/** Whether the network interface is 'up'. This is + * a software flag used to control whether this network + * interface is enabled and processes traffic. + * It is set by the startup code (for static IP configuration) or + * by dhcp/autoip when an address has been assigned. + */ +#define NETIF_FLAG_UP 0x01U +/** If set, the netif has broadcast capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_BROADCAST 0x02U +/** If set, the netif is one end of a point-to-point connection. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_POINTTOPOINT 0x04U +/** If set, the interface is configured using DHCP. + * Set by the DHCP code when starting or stopping DHCP. */ +#define NETIF_FLAG_DHCP 0x08U +/** If set, the interface has an active link + * (set by the network interface driver). + * Either set by the netif driver in its init function (if the link + * is up at that time) or at a later point once the link comes up + * (if link detection is supported by the hardware). */ +#define NETIF_FLAG_LINK_UP 0x10U +/** If set, the netif is an ethernet device using ARP. + * Set by the netif driver in its init function. + * Used to check input packet types and use of DHCP. */ +#define NETIF_FLAG_ETHARP 0x20U +/** If set, the netif is an ethernet device. It might not use + * ARP or TCP/IP if it is used for PPPoE only. + */ +#define NETIF_FLAG_ETHERNET 0x40U +/** If set, the netif has IGMP capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_IGMP 0x80U + +/** Function prototype for netif init functions. Set up flags and output/linkoutput + * callback functions in this function. + * + * @param netif The netif to initialize + */ +typedef err_t (*netif_init_fn)(struct netif *netif); +/** Function prototype for netif->input functions. This function is saved as 'input' + * callback function in the netif struct. Call it when a packet has been received. + * + * @param p The received packet, copied into a pbuf + * @param inp The netif which received the packet + */ +typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); +/** Function prototype for netif->output functions. Called by lwIP when a packet + * shall be sent. For ethernet netif, set this to 'etharp_output' and set + * 'linkoutput'. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (p->payload points to IP header) + * @param ipaddr The IP address to which the packet shall be sent + */ +typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr); +/** Function prototype for netif->linkoutput functions. Only used for ethernet + * netifs. This function is called by ARP when a packet shall be sent. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (raw ethernet packet) + */ +typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); +/** Function prototype for netif status- or link-callback functions. */ +typedef void (*netif_status_callback_fn)(struct netif *netif); +/** Function prototype for netif igmp_mac_filter functions */ +typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, + ip_addr_t *group, u8_t action); + +/*add DHCP event processing by LiuHan*/ +typedef void (*dhcp_event_fn)(void); + +/** Generic data structure used for all lwIP network interfaces. + * The following fields should be filled in by the initialization + * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ +struct netif { + /** pointer to next in linked list */ + struct netif *next; + + /** IP address configuration in network byte order */ + ip_addr_t ip_addr; + ip_addr_t netmask; + ip_addr_t gw; + + /** This function is called by the network device driver + * to pass a packet up the TCP/IP stack. ÏòIP²ãÊäÈëÊý¾Ý°ü*/ + netif_input_fn input; + /** This function is called by the IP module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. ·¢ËÍIPÊý¾Ý°ü*/ + netif_output_fn output; + /** This function is called by the ARP module when it wants + * to send a packet on the interface. This function outputs + * the pbuf as-is on the link medium. µ×²ãÊý¾Ý°ü·¢ËÍ*/ + netif_linkoutput_fn linkoutput; +#if LWIP_NETIF_STATUS_CALLBACK + /** This function is called when the netif state is set to up or down + */ + netif_status_callback_fn status_callback; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + /** This function is called when the netif link is set to up or down + */ + netif_status_callback_fn link_callback; +#endif /* LWIP_NETIF_LINK_CALLBACK */ + /** This field can be set by the device driver and could point + * to state information for the device. ×ÔÓÉÉèÖÃ×ֶΣ¬±ÈÈçÖ¸Ïòµ×²ãÉ豸Ïà¹ØÐÅÏ¢*/ + void *state; +#if LWIP_DHCP + /** the DHCP client state information for this netif */ + struct dhcp *dhcp; + struct udp_pcb *dhcps_pcb; //dhcps + dhcp_event_fn dhcp_event; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /** the AutoIP client state information for this netif */ + struct autoip *autoip; +#endif +#if LWIP_NETIF_HOSTNAME + /* the hostname for this netif, NULL is a valid value */ + char* hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + /** maximum transfer unit (in bytes) ¸Ã½Ó¿ÚÔÊÐíµÄ×î´óÊý¾Ý°ü³¤¶È£¬¶àÊÇ1500*/ + u16_t mtu; + /** number of bytes used in hwaddr¸Ã½Ó¿ÚÎïÀíµØÖ·³¤¶È */ + u8_t hwaddr_len; + /** link level hardware address of this interface ¸Ã½Ó¿ÚÎïÀíµØÖ·*/ + u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + /** flags (see NETIF_FLAG_ above) ¸Ã½Ó¿Ú״̬¡¢ÊôÐÔ×Ö¶Î*/ + u8_t flags; + /** descriptive abbreviation ¸Ã½Ó¿ÚµÄÃû×Ö*/ + char name[2]; + /** number of this interface ¸Ã½Ó¿ÚµÄ±àºÅ*/ + u8_t num; +#if LWIP_SNMP + /** link type (from "snmp_ifType" enum from snmp.h) */ + u8_t link_type; + /** (estimate) link speed */ + u32_t link_speed; + /** timestamp at last change made (up/down) */ + u32_t ts; + /** counters */ + u32_t ifinoctets; + u32_t ifinucastpkts; + u32_t ifinnucastpkts; + u32_t ifindiscards; + u32_t ifoutoctets; + u32_t ifoutucastpkts; + u32_t ifoutnucastpkts; + u32_t ifoutdiscards; +#endif /* LWIP_SNMP */ +#if LWIP_IGMP + /** This function could be called to add or delete a entry in the multicast + filter table of the ethernet MAC.*/ + netif_igmp_mac_filter_fn igmp_mac_filter; +#endif /* LWIP_IGMP */ +#if LWIP_NETIF_HWADDRHINT + u8_t *addr_hint; +#endif /* LWIP_NETIF_HWADDRHINT */ +#if ENABLE_LOOPBACK + /* List of packets to be queued for ourselves. Ö¸Ïò·¢Ë͸ø×Ô¼ºµÄÊý¾Ý°üµÄpbuf*/ + struct pbuf *loop_first;//µÚÒ»¸ö + struct pbuf *loop_last;//×îºóÒ»¸ö +#if LWIP_LOOPBACK_MAX_PBUFS + u16_t loop_cnt_current; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ +#endif /* ENABLE_LOOPBACK */ +#if IP_NAPT + u8_t napt; +#endif +}; + +#if LWIP_SNMP +#define NETIF_INIT_SNMP(netif, type, speed) \ + /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ + (netif)->link_type = (type); \ + /* your link speed here (units: bits per second) */ \ + (netif)->link_speed = (speed); \ + (netif)->ts = 0; \ + (netif)->ifinoctets = 0; \ + (netif)->ifinucastpkts = 0; \ + (netif)->ifinnucastpkts = 0; \ + (netif)->ifindiscards = 0; \ + (netif)->ifoutoctets = 0; \ + (netif)->ifoutucastpkts = 0; \ + (netif)->ifoutnucastpkts = 0; \ + (netif)->ifoutdiscards = 0 +#else /* LWIP_SNMP */ +#define NETIF_INIT_SNMP(netif, type, speed) +#endif /* LWIP_SNMP */ + + +/** The list of network interfaces. */ +extern struct netif *netif_list; +/** The default network interface. */ +extern struct netif *netif_default; + +void netif_init(void)ICACHE_FLASH_ATTR; + +struct netif *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)ICACHE_FLASH_ATTR; + +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw)ICACHE_FLASH_ATTR; +void netif_remove(struct netif * netif)ICACHE_FLASH_ATTR; + +/* Returns a network interface given its name. The name is of the form + "et0", where the first two letters are the "name" field in the + netif structure, and the digit is in the num field in the same + structure. */ +struct netif *netif_find(char *name)ICACHE_FLASH_ATTR; + +void netif_set_default(struct netif *netif)ICACHE_FLASH_ATTR; + +void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR; +void netif_set_netmask(struct netif *netif, ip_addr_t *netmask)ICACHE_FLASH_ATTR; +void netif_set_gw(struct netif *netif, ip_addr_t *gw)ICACHE_FLASH_ATTR; + +void netif_set_up(struct netif *netif)ICACHE_FLASH_ATTR; +void netif_set_down(struct netif *netif)ICACHE_FLASH_ATTR; +/** Ask if an interface is up */ +#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_STATUS_CALLBACK +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)ICACHE_FLASH_ATTR; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +void netif_set_link_up(struct netif *netif)ICACHE_FLASH_ATTR; +void netif_set_link_down(struct netif *netif)ICACHE_FLASH_ATTR; +/** Ask if a link is up */ +#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_LINK_CALLBACK +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)ICACHE_FLASH_ATTR; +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if LWIP_NETIF_HOSTNAME +#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) +#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) +#endif /* LWIP_NETIF_HOSTNAME */ + +#if LWIP_IGMP +#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) +#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) +#endif /* LWIP_IGMP */ + +#if ENABLE_LOOPBACK +err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip)ICACHE_FLASH_ATTR; +void netif_poll(struct netif *netif)ICACHE_FLASH_ATTR; +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +void netif_poll_all(void)ICACHE_FLASH_ATTR; +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETIF_H__ */ diff --git a/include/lwip/opt.h b/include/lwip/opt.h new file mode 100644 index 0000000..91d501f --- /dev/null +++ b/include/lwip/opt.h @@ -0,0 +1,2054 @@ +/** + * @file + * + * lwIP Options Configuration + */ + +/* + * 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 + * + */ +#ifndef __LWIP_OPT_H__ +#define __LWIP_OPT_H__ + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#include "lwipopts.h" +#include "lwip/debug.h" + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#ifndef SYS_LIGHTWEIGHT_PROT +#define SYS_LIGHTWEIGHT_PROT 0 +#endif + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#ifndef NO_SYS +#define NO_SYS 1 +#endif + +/** + * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 + * Mainly for compatibility to old versions. + */ +#ifndef NO_SYS_NO_TIMERS +#define NO_SYS_NO_TIMERS 1 +#endif + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#ifndef MEMCPY +#define MEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#ifndef SMEMCPY +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#ifndef MEM_LIBC_MALLOC +#define MEM_LIBC_MALLOC 0 +#endif + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#ifndef MEMP_MEM_MALLOC +#define MEMP_MEM_MALLOC 0 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#ifndef MEM_ALIGNMENT +#define MEM_ALIGNMENT 1 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#ifndef MEM_SIZE +#define MEM_SIZE 1600 +#endif + +/** + * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. + * This can be used to individually change the location of each pool. + * Default is one big array for all pools + */ +#ifndef MEMP_SEPARATE_POOLS +#define MEMP_SEPARATE_POOLS 0 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#ifndef MEMP_OVERFLOW_CHECK +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#ifndef MEMP_SANITY_CHECK +#define MEMP_SANITY_CHECK 0 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#ifndef MEM_USE_POOLS +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * inlude path somewhere. + */ +#ifndef MEMP_USE_CUSTOM_POOLS +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 16 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#ifndef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#ifndef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB 5 +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for + * reassembly (whole packets, not fragments!) + */ +#ifndef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 5 +#endif + +/** + * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent + * (fragments, not whole packets!). + * This is only used with IP_FRAG_USES_STATIC_BUF==0 and + * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs + * where the packet is not yet sent when netif->output returns. + */ +#ifndef MEMP_NUM_FRAG_PBUF +#define MEMP_NUM_FRAG_PBUF 15 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#ifndef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 30 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members et the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#ifndef MEMP_NUM_IGMP_GROUP +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + */ +#ifndef MEMP_NUM_SYS_TIMEOUT +#define MEMP_NUM_SYS_TIMEOUT 3 +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 2 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 4 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#endif + +/** + * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. + */ +#ifndef MEMP_NUM_SNMP_NODE +#define MEMP_NUM_SNMP_NODE 50 +#endif + +/** + * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. + * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! + */ +#ifndef MEMP_NUM_SNMP_ROOTNODE +#define MEMP_NUM_SNMP_ROOTNODE 30 +#endif + +/** + * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to + * be changed normally) - 2 of these are used per request (1 for input, + * 1 for output) + */ +#ifndef MEMP_NUM_SNMP_VARBIND +#define MEMP_NUM_SNMP_VARBIND 2 +#endif + +/** + * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used + * (does not have to be changed normally) - 3 of these are used per request + * (1 for the value read and 2 for OIDs - input and output) + */ +#ifndef MEMP_NUM_SNMP_VALUE +#define MEMP_NUM_SNMP_VALUE 3 +#endif + +/** + * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls + * (before freeing the corresponding memory using lwip_freeaddrinfo()). + */ +#ifndef MEMP_NUM_NETDB +#define MEMP_NUM_NETDB 1 +#endif + +/** + * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list + * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. + */ +#ifndef MEMP_NUM_LOCALHOSTLIST +#define MEMP_NUM_LOCALHOSTLIST 1 +#endif + +/** + * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE + * interfaces (only used with PPPOE_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOE_INTERFACES +#define MEMP_NUM_PPPOE_INTERFACES 1 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 16 +#endif + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 10 +#endif + +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#ifndef ARP_QUEUEING +#define ARP_QUEUEING 0 +#endif + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#ifndef ETHARP_TRUST_IP_MAC +#define ETHARP_TRUST_IP_MAC 0 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + */ +#ifndef ETHARP_SUPPORT_VLAN +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP + * might be disabled + */ +#ifndef LWIP_ETHERNET +#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) +#endif + +/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure + * alignment of payload after that header. Since the header is 14 bytes long, + * without this padding e.g. addresses in the IP header will not be aligned + * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. + */ +#ifndef ETH_PAD_SIZE +#define ETH_PAD_SIZE 0 +#endif + +/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table + * entries (using etharp_add_static_entry/etharp_remove_static_entry). + */ +#ifndef ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#endif + + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#ifndef IP_FORWARD +#define IP_FORWARD 1 +#endif + +#ifndef IP_NAPT +#define IP_NAPT 1 +#endif + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#ifndef IP_OPTIONS_ALLOWED +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 0 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#ifndef IP_FRAG +#define IP_FRAG 1 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#ifndef IP_REASS_MAXAGE +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP + * fragmentation. Otherwise pbufs are allocated and reference the original + * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, + * new PBUF_RAM pbufs are used for fragments). + * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! + */ +#ifndef IP_FRAG_USES_STATIC_BUF +#define IP_FRAG_USES_STATIC_BUF 0 +#endif + +/** + * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer + * (requires IP_FRAG_USES_STATIC_BUF==1) + */ +#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) +#define IP_FRAG_MAX_MTU 1500 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#ifndef IP_DEFAULT_TTL +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#ifndef IP_SOF_BROADCAST +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#ifndef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#ifndef LWIP_ICMP +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#ifndef ICMP_TTL +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#ifndef LWIP_BROADCAST_PING +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#ifndef LWIP_MULTICAST_PING +#define LWIP_MULTICAST_PING 0 +#endif + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef LWIP_RAW +#define LWIP_RAW 1 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef RAW_TTL +#define RAW_TTL (IP_DEFAULT_TTL) +#endif + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#ifndef LWIP_DHCP +#define LWIP_DHCP 0 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#ifndef LWIP_AUTOIP +#define LWIP_AUTOIP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP. This can be set + * as low as 1 to get an AutoIP address very quickly, but you should + * be prepared to handle a changing IP address when DHCP overrides + * AutoIP. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif + +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP + * transport. + */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will + * allow. At least one request buffer is required. + * Does not have to be changed unless external MIBs answer request asynchronously + */ +#ifndef SNMP_CONCURRENT_REQUESTS +#define SNMP_CONCURRENT_REQUESTS 1 +#endif + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#ifndef SNMP_TRAP_DESTINATIONS +#define SNMP_TRAP_DESTINATIONS 1 +#endif + +/** + * SNMP_PRIVATE_MIB: + * When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. + */ +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#ifndef SNMP_SAFE_REQUESTS +#define SNMP_SAFE_REQUESTS 1 +#endif + +/** + * The maximum length of strings used. This affects the size of + * MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_OCTET_STRING_LEN +#define SNMP_MAX_OCTET_STRING_LEN 127 +#endif + +/** + * The maximum depth of the SNMP tree. + * With private MIBs enabled, this depends on your MIB! + * This affects the size of MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_TREE_DEPTH +#define SNMP_MAX_TREE_DEPTH 15 +#endif + +/** + * The size of the MEMP_SNMP_VALUE elements, normally calculated from + * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. + */ +#ifndef SNMP_MAX_VALUE_SIZE +#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) +#endif + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 0 +#endif + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#ifndef LWIP_DNS +#define LWIP_DNS 0 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers */ +#ifndef DNS_MAX_SERVERS +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#ifndef DNS_DOES_NAME_CHECK +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** DNS message max. size. Default value is RFC compliant. */ +#ifndef DNS_MSG_SIZE +#define DNS_MSG_SIZE 512 +#endif + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + * + * Instead, you can also use an external function: + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) + * that returns the IP address or INADDR_NONE if not found. + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#ifndef LWIP_UDP +#define LWIP_UDP 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#ifndef LWIP_UDPLITE +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#ifndef UDP_TTL +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#ifndef LWIP_NETBUF_RECVINFO +#define LWIP_NETBUF_RECVINFO 0 +#endif + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#ifndef LWIP_TCP +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#ifndef TCP_TTL +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#ifndef TCP_WND +#define TCP_WND (4 * TCP_MSS) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#ifndef TCP_MAXRTX +#define TCP_MAXRTX 12 +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#ifndef TCP_SYNMAXRTX +#define TCP_SYNMAXRTX 6 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 536 +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#ifndef TCP_CALCULATE_EFF_SEND_MSS +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF 256 +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than + * TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). + */ +#ifndef TCP_SNDLOWAT +#define TCP_SNDLOWAT ((TCP_SND_BUF)/2) +#endif + +/** + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be grater + * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below + * this number, select returns writable (combined with TCP_SNDLOWAT). + */ +#ifndef TCP_SNDQUEUELOWAT +#define TCP_SNDQUEUELOWAT ((TCP_SND_QUEUELEN)/2) +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * TCP_OVERSIZE: The maximum number of bytes that tcp_write may + * allocate ahead of time in an attempt to create shorter pbuf chains + * for transmission. The meaningful range is 0 to TCP_MSS. Some + * suggested values are: + * + * 0: Disable oversized allocation. Each tcp_write() allocates a new + pbuf (old behaviour). + * 1: Allocate size-aligned pbufs with minimal excess. Use this if your + * scatter-gather DMA requires aligned fragments. + * 128: Limit the pbuf/memory overhead to 20%. + * TCP_MSS: Try to create unfragmented TCP packets. + * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. + */ +#ifndef TCP_OVERSIZE +#define TCP_OVERSIZE TCP_MSS +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + */ +#ifndef LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#ifndef TCP_WND_UPDATE_THRESHOLD +#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) +#endif + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. + */ +//#ifndef LWIP_EVENT_API +//#define LWIP_EVENT_API 0 +//#define LWIP_CALLBACK_API 1 +//#else +//#define LWIP_EVENT_API 1 +//#define LWIP_CALLBACK_API 0 +//#endif + + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#ifndef PBUF_LINK_HLEN +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accommodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#ifndef PBUF_POOL_BUFSIZE +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) +#endif + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 0 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquistion) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#ifndef LWIP_NETIF_HWADDRHINT +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#ifndef LWIP_NETIF_LOOPBACK +#define LWIP_NETIF_LOOPBACK 1 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#ifndef LWIP_LOOPBACK_MAX_PBUFS +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#ifndef LWIP_NETIF_TX_SINGLE_PBUF +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c + */ +#ifndef LWIP_HAVE_LOOPIF +#define LWIP_HAVE_LOOPIF 1 +#endif + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c + */ +#ifndef LWIP_HAVE_SLIPIF +#define LWIP_HAVE_SLIPIF 0 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "tcpip_thread" +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_PRIO +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#ifndef SLIPIF_THREAD_NAME +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_STACKSIZE +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_PRIO +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * PPP_THREAD_NAME: The name assigned to the pppInputThread. + */ +#ifndef PPP_THREAD_NAME +#define PPP_THREAD_NAME "pppInputThread" +#endif + +/** + * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_STACKSIZE +#define PPP_THREAD_STACKSIZE 0 +#endif + +/** + * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_PRIO +#define PPP_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#ifndef DEFAULT_THREAD_NAME +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_PRIO +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_RAW_RECVMBOX_SIZE +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_UDP_RECVMBOX_SIZE +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_TCP_RECVMBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#endif + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#ifndef LWIP_NETCONN +#define LWIP_NETCONN 0 +#endif + +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create + * timers running in tcpip_thread from another thread. + */ +#ifndef LWIP_TCPIP_TIMEOUT +#define LWIP_TCPIP_TIMEOUT 1 +#endif + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 0 +#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_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 0 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#ifndef SO_REUSE +#define SO_REUSE 0 +#endif + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#ifndef SO_REUSE_RXTOALL +#define SO_REUSE_RXTOALL 0 +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 1 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 0 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#ifndef LINK_STATS +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#ifndef ETHARP_STATS +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#ifndef IP_STATS +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#ifndef IPFRAG_STATS +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#ifndef ICMP_STATS +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#ifndef IGMP_STATS +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#ifndef UDP_STATS +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#ifndef TCP_STATS +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#ifndef MEM_STATS +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#ifndef MEMP_STATS +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#ifndef SYS_STATS +#define SYS_STATS (NO_SYS == 0) +#endif + +#else + +#define LINK_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 + +#endif /* LWIP_STATS */ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ +/** + * PPP_SUPPORT==1: Enable PPP. + */ +#ifndef PPP_SUPPORT +#define PPP_SUPPORT 0 +#endif + +/** + * PPPOE_SUPPORT==1: Enable PPP Over Ethernet + */ +#ifndef PPPOE_SUPPORT +#define PPPOE_SUPPORT 0 +#endif + +/** + * PPPOS_SUPPORT==1: Enable PPP Over Serial + */ +#ifndef PPPOS_SUPPORT +#define PPPOS_SUPPORT PPP_SUPPORT +#endif + +#if PPP_SUPPORT + +/** + * NUM_PPP: Max PPP sessions. + */ +#ifndef NUM_PPP +#define NUM_PPP 1 +#endif + +/** + * PAP_SUPPORT==1: Support PAP. + */ +#ifndef PAP_SUPPORT +#define PAP_SUPPORT 0 +#endif + +/** + * CHAP_SUPPORT==1: Support CHAP. + */ +#ifndef CHAP_SUPPORT +#define CHAP_SUPPORT 0 +#endif + +/** + * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef MSCHAP_SUPPORT +#define MSCHAP_SUPPORT 0 +#endif + +/** + * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CBCP_SUPPORT +#define CBCP_SUPPORT 0 +#endif + +/** + * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CCP_SUPPORT +#define CCP_SUPPORT 0 +#endif + +/** + * VJ_SUPPORT==1: Support VJ header compression. + */ +#ifndef VJ_SUPPORT +#define VJ_SUPPORT 0 +#endif + +/** + * MD5_SUPPORT==1: Support MD5 (see also CHAP). + */ +#ifndef MD5_SUPPORT +#define MD5_SUPPORT 0 +#endif + +/* + * Timeouts + */ +#ifndef FSM_DEFTIMEOUT +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef FSM_DEFMAXTERMREQS +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXCONFREQS +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXNAKLOOPS +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif + +#ifndef UPAP_DEFTIMEOUT +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef UPAP_DEFREQTIME +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif + +#ifndef CHAP_DEFTIMEOUT +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef CHAP_DEFTRANSMITS +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ +#endif + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#ifndef LCP_ECHOINTERVAL +#define LCP_ECHOINTERVAL 0 +#endif + +/* Number of unanswered echo requests before failure. */ +#ifndef LCP_MAXECHOFAILS +#define LCP_MAXECHOFAILS 3 +#endif + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#ifndef PPP_MAXIDLEFLAG +#define PPP_MAXIDLEFLAG 100 +#endif + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#ifndef PPP_MAXMTU +/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#ifndef PPP_DEFMRU +#define PPP_DEFMRU 296 /* Try for this */ +#endif +#define PPP_MINMRU 128 /* No MRUs below this */ + +#ifndef MAXNAMELEN +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#endif +#ifndef MAXSECRETLEN +#define MAXSECRETLEN 256 /* max length of password or secret */ +#endif + +#endif /* PPP_SUPPORT */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#ifndef LWIP_CHECKSUM_ON_COPY +#define LWIP_CHECKSUM_ON_COPY 0 +#endif + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +#ifndef LWIP_DBG_MIN_LEVEL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#ifndef LWIP_DBG_TYPES_ON +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#ifndef NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#ifndef PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#ifndef ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#ifndef IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#ifndef INET_DEBUG +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#ifndef IP_DEBUG +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#ifndef RAW_DEBUG +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#ifndef MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#ifndef MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#ifndef SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#ifndef TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#ifndef TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#ifndef UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * PPP_DEBUG: Enable debugging for PPP. + */ +#ifndef PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#ifndef SLIP_DEBUG +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#ifndef DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#ifndef AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. + */ +#ifndef SNMP_MSG_DEBUG +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#ifndef SNMP_MIB_DEBUG +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#ifndef DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +/** + * NAPT_DEBUG: Enable debugging for NAPT. + */ +#ifndef NAPT_DEBUG +#define NAPT_DEBUG LWIP_DBG_OFF +#endif + +#endif /* __LWIP_OPT_H__ */ diff --git a/include/lwipopts.h b/include/lwipopts.h new file mode 100644 index 0000000..459d0be --- /dev/null +++ b/include/lwipopts.h @@ -0,0 +1,2097 @@ +/** + * @file + * + * lwIP Options Configuration + */ + +/* + * 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 + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#ifndef SYS_LIGHTWEIGHT_PROT +#define SYS_LIGHTWEIGHT_PROT 0 +#endif + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#ifndef NO_SYS +#define NO_SYS 1 +#endif + +/** + * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 + * Mainly for compatibility to old versions. + */ +#ifndef NO_SYS_NO_TIMERS +#define NO_SYS_NO_TIMERS 0 +#endif + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#ifndef MEMCPY +#define MEMCPY(dst,src,len) os_memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#ifndef SMEMCPY +#define SMEMCPY(dst,src,len) os_memcpy(dst,src,len) +#endif + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#ifndef MEM_LIBC_MALLOC +#define MEM_LIBC_MALLOC 1 +#endif + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#ifndef MEMP_MEM_MALLOC +#define MEMP_MEM_MALLOC 1 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#ifndef MEM_ALIGNMENT +#define MEM_ALIGNMENT 4 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#ifndef MEM_SIZE +#define MEM_SIZE 16000 +#endif + +/** + * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. + * This can be used to individually change the location of each pool. + * Default is one big array for all pools + */ +#ifndef MEMP_SEPARATE_POOLS +#define MEMP_SEPARATE_POOLS 1 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#ifndef MEMP_OVERFLOW_CHECK +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#ifndef MEMP_SANITY_CHECK +#define MEMP_SANITY_CHECK 1 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#ifndef MEM_USE_POOLS +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * inlude path somewhere. + */ +#ifndef MEMP_USE_CUSTOM_POOLS +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 10 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#ifndef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#ifndef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB (*(volatile uint32*)0x600011FC) +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 2 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for + * reassembly (whole packets, not fragments!) + */ +#ifndef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 0 +#endif + +/** + * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent + * (fragments, not whole packets!). + * This is only used with IP_FRAG_USES_STATIC_BUF==0 and + * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs + * where the packet is not yet sent when netif->output returns. + */ +#ifndef MEMP_NUM_FRAG_PBUF +#define MEMP_NUM_FRAG_PBUF 0 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#ifndef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 10 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members et the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#ifndef MEMP_NUM_IGMP_GROUP +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + */ +#ifndef MEMP_NUM_SYS_TIMEOUT +#define MEMP_NUM_SYS_TIMEOUT 8 +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 0 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 0 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 4 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 4 +#endif + +/** + * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. + */ +#ifndef MEMP_NUM_SNMP_NODE +#define MEMP_NUM_SNMP_NODE 0 +#endif + +/** + * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. + * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! + */ +#ifndef MEMP_NUM_SNMP_ROOTNODE +#define MEMP_NUM_SNMP_ROOTNODE 0 +#endif + +/** + * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to + * be changed normally) - 2 of these are used per request (1 for input, + * 1 for output) + */ +#ifndef MEMP_NUM_SNMP_VARBIND +#define MEMP_NUM_SNMP_VARBIND 0 +#endif + +/** + * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used + * (does not have to be changed normally) - 3 of these are used per request + * (1 for the value read and 2 for OIDs - input and output) + */ +#ifndef MEMP_NUM_SNMP_VALUE +#define MEMP_NUM_SNMP_VALUE 0 +#endif + +/** + * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls + * (before freeing the corresponding memory using lwip_freeaddrinfo()). + */ +#ifndef MEMP_NUM_NETDB +#define MEMP_NUM_NETDB 0 +#endif + +/** + * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list + * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. + */ +#ifndef MEMP_NUM_LOCALHOSTLIST +#define MEMP_NUM_LOCALHOSTLIST 0 +#endif + +/** + * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE + * interfaces (only used with PPPOE_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOE_INTERFACES +#define MEMP_NUM_PPPOE_INTERFACES 0 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 10 +#endif + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 10 +#endif + +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#ifndef ARP_QUEUEING +#define ARP_QUEUEING 1 +#endif + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#ifndef ETHARP_TRUST_IP_MAC +#define ETHARP_TRUST_IP_MAC 1 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + */ +#ifndef ETHARP_SUPPORT_VLAN +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP + * might be disabled + */ +#ifndef LWIP_ETHERNET +#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) +#endif + +/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure + * alignment of payload after that header. Since the header is 14 bytes long, + * without this padding e.g. addresses in the IP header will not be aligned + * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. + */ +#ifndef ETH_PAD_SIZE +#define ETH_PAD_SIZE 0 +#endif + +/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table + * entries (using etharp_add_static_entry/etharp_remove_static_entry). + */ +#ifndef ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#endif + + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#ifndef IP_FORWARD +#define IP_FORWARD 1 +#endif + +/** + * IP_NAPT==1: Enables the ability to do Network Address Port Translation (NAPT) + * on forwarded packets. This only makes sense with IP_FORWARD==1. + */ +#ifndef IP_NAPT +#define IP_NAPT 1 +#endif + +/** + * IP_NAPT_DYNAMIC==1: Saves the memory for the NAPT tables if not required. + * If NAPT is used, ip_napt_init() has to be called explicitly once. + */ +#ifndef IP_NAPT_DYNAMIC +#define IP_NAPT_DYNAMIC 0 +#endif + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#ifndef IP_OPTIONS_ALLOWED +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 0 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#ifndef IP_FRAG +#define IP_FRAG 0 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#ifndef IP_REASS_MAXAGE +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP + * fragmentation. Otherwise pbufs are allocated and reference the original + * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, + * new PBUF_RAM pbufs are used for fragments). + * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! + */ +#ifndef IP_FRAG_USES_STATIC_BUF +#define IP_FRAG_USES_STATIC_BUF 1 +#endif + +/** + * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer + * (requires IP_FRAG_USES_STATIC_BUF==1) + */ +#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) +#define IP_FRAG_MAX_MTU 1500 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#ifndef IP_DEFAULT_TTL +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#ifndef IP_SOF_BROADCAST +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#ifndef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#ifndef LWIP_ICMP +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#ifndef ICMP_TTL +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#ifndef LWIP_BROADCAST_PING +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#ifndef LWIP_MULTICAST_PING +#define LWIP_MULTICAST_PING 0 +#endif + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef LWIP_RAW +#define LWIP_RAW 1 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef RAW_TTL +#define RAW_TTL (IP_DEFAULT_TTL) +#endif + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#ifndef LWIP_DHCP +#define LWIP_DHCP 1 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/** + * DHCP_MAXRTX: Maximum number of retries of current request. + */ +#ifndef DHCP_MAXRTX +#define DHCP_MAXRTX (*(volatile uint32*)0x600011E0) +#endif + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#ifndef LWIP_AUTOIP +#define LWIP_AUTOIP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP. This can be set + * as low as 1 to get an AutoIP address very quickly, but you should + * be prepared to handle a changing IP address when DHCP overrides + * AutoIP. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif + +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP + * transport. + */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will + * allow. At least one request buffer is required. + */ +#ifndef SNMP_CONCURRENT_REQUESTS +#define SNMP_CONCURRENT_REQUESTS 0 +#endif + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#ifndef SNMP_TRAP_DESTINATIONS +#define SNMP_TRAP_DESTINATIONS 0 +#endif + +/** + * SNMP_PRIVATE_MIB: + */ +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#ifndef SNMP_SAFE_REQUESTS +#define SNMP_SAFE_REQUESTS 0 +#endif + +/** + * The maximum length of strings used. This affects the size of + * MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_OCTET_STRING_LEN +#define SNMP_MAX_OCTET_STRING_LEN 127 +#endif + +/** + * The maximum depth of the SNMP tree. + * With private MIBs enabled, this depends on your MIB! + * This affects the size of MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_TREE_DEPTH +#define SNMP_MAX_TREE_DEPTH 15 +#endif + +/** + * The size of the MEMP_SNMP_VALUE elements, normally calculated from + * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. + */ +#ifndef SNMP_MAX_VALUE_SIZE +#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) +#endif + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 1 +#endif +/* + ---------------------------------- + ---------- MDNS options ---------- + ---------------------------------- +*/ +/** + * LWIP_MDNS==1: Turn on MDNS module. + */ +#ifndef LWIP_MDNS +#define LWIP_MDNS 1 +#endif +/* +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#ifndef LWIP_DNS +#define LWIP_DNS 1 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers */ +#ifndef DNS_MAX_SERVERS +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#ifndef DNS_DOES_NAME_CHECK +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** DNS message max. size. Default value is RFC compliant. */ +#ifndef DNS_MSG_SIZE +#define DNS_MSG_SIZE 512 +#endif + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + * + * Instead, you can also use an external function: + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) + * that returns the IP address or INADDR_NONE if not found. + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#ifndef LWIP_UDP +#define LWIP_UDP 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#ifndef LWIP_UDPLITE +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#ifndef UDP_TTL +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#ifndef LWIP_NETBUF_RECVINFO +#define LWIP_NETBUF_RECVINFO 0 +#endif + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#ifndef LWIP_TCP +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#ifndef TCP_TTL +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#ifndef TCP_WND +#define TCP_WND (*(volatile uint32*)0x600011F0) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#ifndef TCP_MAXRTX +#define TCP_MAXRTX (*(volatile uint32*)0x600011E8) +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#ifndef TCP_SYNMAXRTX +#define TCP_SYNMAXRTX (*(volatile uint32*)0x600011E4) +#endif + +/** + * TCP_MAXRTO: Maximum retransmission timeout of data segments. + */ +#ifndef TCP_MAXRTO +#define TCP_MAXRTO 10 +#endif + +/** + * TCP_MINRTO: Minimum retransmission timeout of data segments. + */ +#ifndef TCP_MINRTO +#define TCP_MINRTO 2 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ 1 +#endif + +#if 1 +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 536 +#endif +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#ifndef TCP_CALCULATE_EFF_SEND_MSS +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF (2 * TCP_MSS) +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than + * TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). + */ +#ifndef TCP_SNDLOWAT +#define TCP_SNDLOWAT ((TCP_SND_BUF)/2) +#endif + +/** + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be grater + * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below + * this number, select returns writable (combined with TCP_SNDLOWAT). + */ +#ifndef TCP_SNDQUEUELOWAT +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * TCP_OVERSIZE: The maximum number of bytes that tcp_write may + * allocate ahead of time in an attempt to create shorter pbuf chains + * for transmission. The meaningful range is 0 to TCP_MSS. Some + * suggested values are: + * + * 0: Disable oversized allocation. Each tcp_write() allocates a new + pbuf (old behaviour). + * 1: Allocate size-aligned pbufs with minimal excess. Use this if your + * scatter-gather DMA requires aligned fragments. + * 128: Limit the pbuf/memory overhead to 20%. + * TCP_MSS: Try to create unfragmented TCP packets. + * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. + */ +#ifndef TCP_OVERSIZE +#define TCP_OVERSIZE TCP_MSS +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + */ +#ifndef LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#ifndef TCP_WND_UPDATE_THRESHOLD +#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) +#endif + +/** + * 2 * TCP_MSL defines duration of socket TIME-WAIT state in ms. + */ +#define TCP_MSL 2500UL + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. + */ +#ifndef LWIP_EVENT_API +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#else +#define LWIP_EVENT_API 1 +#define LWIP_CALLBACK_API 0 +#endif + + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#ifndef PBUF_LINK_HLEN +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accommodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#ifndef PBUF_POOL_BUFSIZE +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) +#endif + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 1 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquistion) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#ifndef LWIP_NETIF_HWADDRHINT +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#ifndef LWIP_NETIF_LOOPBACK +#define LWIP_NETIF_LOOPBACK 0 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#ifndef LWIP_LOOPBACK_MAX_PBUFS +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#ifndef LWIP_NETIF_TX_SINGLE_PBUF +#define LWIP_NETIF_TX_SINGLE_PBUF 1 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c + */ +#ifndef LWIP_HAVE_LOOPIF +#define LWIP_HAVE_LOOPIF 0 +#endif + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c + */ +#ifndef LWIP_HAVE_SLIPIF +#define LWIP_HAVE_SLIPIF 1 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "tcpip_thread" +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_PRIO +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#ifndef SLIPIF_THREAD_NAME +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_STACKSIZE +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_PRIO +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * PPP_THREAD_NAME: The name assigned to the pppInputThread. + */ +#ifndef PPP_THREAD_NAME +#define PPP_THREAD_NAME "pppInputThread" +#endif + +/** + * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_STACKSIZE +#define PPP_THREAD_STACKSIZE 0 +#endif + +/** + * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_PRIO +#define PPP_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#ifndef DEFAULT_THREAD_NAME +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_PRIO +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_RAW_RECVMBOX_SIZE +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_UDP_RECVMBOX_SIZE +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_TCP_RECVMBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#endif + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#ifndef LWIP_NETCONN +#define LWIP_NETCONN 0 +#endif + +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create + * timers running in tcpip_thread from another thread. + */ +#ifndef LWIP_TCPIP_TIMEOUT +#define LWIP_TCPIP_TIMEOUT 1 +#endif + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 0 +#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 0 +#endif + +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 1 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 0 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#ifndef SO_REUSE +#define SO_REUSE 1 +#endif + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#ifndef SO_REUSE_RXTOALL +#define SO_REUSE_RXTOALL 0 +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 0 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 1 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#ifndef LINK_STATS +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#ifndef ETHARP_STATS +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#ifndef IP_STATS +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#ifndef IPFRAG_STATS +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#ifndef ICMP_STATS +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#ifndef IGMP_STATS +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#ifndef UDP_STATS +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#ifndef TCP_STATS +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#ifndef MEM_STATS +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#ifndef MEMP_STATS +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#ifndef SYS_STATS +#define SYS_STATS (NO_SYS == 0) +#endif + +#else +#define ETHARP_STATS 0 +#define LINK_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 + +#endif /* LWIP_STATS */ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ +/** + * PPP_SUPPORT==1: Enable PPP. + */ +#ifndef PPP_SUPPORT +#define PPP_SUPPORT 0 +#endif + +/** + * PPPOE_SUPPORT==1: Enable PPP Over Ethernet + */ +#ifndef PPPOE_SUPPORT +#define PPPOE_SUPPORT 0 +#endif + +/** + * PPPOS_SUPPORT==1: Enable PPP Over Serial + */ +#ifndef PPPOS_SUPPORT +#define PPPOS_SUPPORT PPP_SUPPORT +#endif + +#if PPP_SUPPORT + +/** + * NUM_PPP: Max PPP sessions. + */ +#ifndef NUM_PPP +#define NUM_PPP 1 +#endif + +/** + * PAP_SUPPORT==1: Support PAP. + */ +#ifndef PAP_SUPPORT +#define PAP_SUPPORT 0 +#endif + +/** + * CHAP_SUPPORT==1: Support CHAP. + */ +#ifndef CHAP_SUPPORT +#define CHAP_SUPPORT 0 +#endif + +/** + * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef MSCHAP_SUPPORT +#define MSCHAP_SUPPORT 0 +#endif + +/** + * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CBCP_SUPPORT +#define CBCP_SUPPORT 0 +#endif + +/** + * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CCP_SUPPORT +#define CCP_SUPPORT 0 +#endif + +/** + * VJ_SUPPORT==1: Support VJ header compression. + */ +#ifndef VJ_SUPPORT +#define VJ_SUPPORT 0 +#endif + +/** + * MD5_SUPPORT==1: Support MD5 (see also CHAP). + */ +#ifndef MD5_SUPPORT +#define MD5_SUPPORT 0 +#endif + +/* + * Timeouts + */ +#ifndef FSM_DEFTIMEOUT +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef FSM_DEFMAXTERMREQS +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXCONFREQS +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXNAKLOOPS +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif + +#ifndef UPAP_DEFTIMEOUT +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef UPAP_DEFREQTIME +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif + +#ifndef CHAP_DEFTIMEOUT +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef CHAP_DEFTRANSMITS +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ +#endif + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#ifndef LCP_ECHOINTERVAL +#define LCP_ECHOINTERVAL 0 +#endif + +/* Number of unanswered echo requests before failure. */ +#ifndef LCP_MAXECHOFAILS +#define LCP_MAXECHOFAILS 3 +#endif + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#ifndef PPP_MAXIDLEFLAG +#define PPP_MAXIDLEFLAG 100 +#endif + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#ifndef PPP_MAXMTU +/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#ifndef PPP_DEFMRU +#define PPP_DEFMRU 296 /* Try for this */ +#endif +#define PPP_MINMRU 128 /* No MRUs below this */ + +#ifndef MAXNAMELEN +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#endif +#ifndef MAXSECRETLEN +#define MAXSECRETLEN 256 /* max length of password or secret */ +#endif + +#endif /* PPP_SUPPORT */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#ifndef LWIP_CHECKSUM_ON_COPY +#define LWIP_CHECKSUM_ON_COPY 0 +#endif + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +//#define LWIP_DEBUG 1 +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +#ifndef LWIP_DBG_MIN_LEVEL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#ifndef LWIP_DBG_TYPES_ON +#define LWIP_DBG_TYPES_ON LWIP_DBG_OFF +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#ifndef NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#ifndef PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#ifndef ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#ifndef IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#ifndef INET_DEBUG +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#ifndef IP_DEBUG +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#ifndef RAW_DEBUG +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#ifndef MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#ifndef MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#ifndef SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#ifndef TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#ifndef TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#ifndef UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * PPP_DEBUG: Enable debugging for PPP. + */ +#ifndef PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#ifndef SLIP_DEBUG +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#ifndef DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#ifndef AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. + */ +#ifndef SNMP_MSG_DEBUG +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#ifndef SNMP_MIB_DEBUG +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#ifndef DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +/** + * NAPT_DEBUG: Enable debugging for NAPT. + */ +#ifndef NAPT_DEBUG +#define NAPT_DEBUG LWIP_DBG_OFF +#endif + +#endif /* __LWIP_OPT_H__ */ diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000..bb97dcd --- /dev/null +++ b/include/string.h @@ -0,0 +1 @@ +//Nothing here. diff --git a/liblwip_open_napt.a b/liblwip_open_napt.a new file mode 100644 index 0000000000000000000000000000000000000000..3ca4da8556a39788a307d107c82481a4c74e475d GIT binary patch literal 323816 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 z

+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 KYpe*=-hTo?yGRTG literal 0 HcmV?d00001 diff --git a/user/acl.c b/user/acl.c new file mode 100644 index 0000000..d4bcd49 --- /dev/null +++ b/user/acl.c @@ -0,0 +1,310 @@ +#include "c_types.h" +#include "mem.h" +#include "ets_sys.h" +#include "osapi.h" +#include "os_type.h" +#include "lwip/ip.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "netif/etharp.h" + +#include "user_interface.h" +#include "string.h" + +#include "acl.h" + +acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES]; +uint8_t acl_freep[MAX_NO_ACLS]; +uint32_t acl_allow_count; +uint32_t acl_deny_count; +static packet_deny_cb my_deny_cb; + +void ICACHE_FLASH_ATTR +acl_init() +{ + int i; + acl_allow_count = acl_deny_count = 0; + my_deny_cb = NULL; + for(i=0; i< MAX_NO_ACLS; i++) + { + acl_freep[i] = 0; + acl_clear_stats(i); + } +} + +bool ICACHE_FLASH_ATTR +acl_is_empty(uint8_t acl_no) +{ + if (acl_no >= MAX_NO_ACLS) + { + return true; + } + return acl_freep[acl_no] == 0; +} + +void ICACHE_FLASH_ATTR +acl_clear(uint8_t acl_no) +{ + if (acl_no >= MAX_NO_ACLS) + { + return; + } + acl_freep[acl_no] = 0; + acl_clear_stats(acl_no); +} + +void ICACHE_FLASH_ATTR +acl_clear_stats(uint8_t acl_no) +{ + int i; + + if (acl_no >= MAX_NO_ACLS) + { + return; + } + my_deny_cb = NULL; + for(i=0; i< MAX_ACL_ENTRIES; i++) + acl[acl_no][i].hit_count = 0; +} + +bool ICACHE_FLASH_ATTR +acl_add(uint8_t acl_no, + uint32_t src, + uint32_t s_mask, + uint32_t dest, + uint32_t d_mask, + uint8_t proto, + uint16_t s_port, + uint16_t d_port, + uint8_t allow) +{ + acl_entry *my_entry; + + if (acl_no >= MAX_NO_ACLS || acl_freep[acl_no] >= MAX_ACL_ENTRIES) + { + return false; + } + + my_entry = &acl[acl_no][acl_freep[acl_no]]; + my_entry->src = src & s_mask; + my_entry->s_mask = s_mask; + my_entry->dest = dest & d_mask; + my_entry->d_mask = d_mask; + my_entry->proto = proto; + my_entry->s_port = s_port; + my_entry->d_port = d_port; + my_entry->allow = allow; + my_entry->hit_count = 0; + + acl_freep[acl_no]++; + return true; +} + +uint8_t ICACHE_FLASH_ATTR +acl_check_packet(uint8_t acl_no, struct pbuf *p) +{ + struct eth_hdr *mac_h; + struct ip_hdr *ip_h; + uint8_t proto; + struct udp_hdr *udp_h; + struct tcp_hdr *tcp_h; + uint16_t src_port, dest_port; + uint8_t *packet; + int i; + acl_entry *my_entry; + uint8_t allow; + + if (acl_no >= MAX_NO_ACLS) + { + return ACL_DENY; + } + + if (p->len < sizeof(struct eth_hdr)) + { + return ACL_DENY; + } + + mac_h = (struct eth_hdr *)p->payload; + + // Allow ARP + if (ntohs(mac_h->type) == ETHTYPE_ARP) + { + acl_allow_count++; + return ACL_ALLOW; + } + + // Drop anything else if not IPv4 + if (ntohs(mac_h->type) != ETHTYPE_IP) + { + acl_deny_count++; + return ACL_DENY; + } + + if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)) + { + acl_deny_count++; + return ACL_DENY; + } + + allow = ACL_DENY; + packet = (uint8_t*)p->payload; + ip_h = (struct ip_hdr *)&packet[sizeof(struct eth_hdr)]; + proto = IPH_PROTO(ip_h); + + switch (proto) { + case IP_PROTO_UDP: + { + if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct udp_hdr)) + { + return; + } + udp_h = (struct udp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)]; + src_port = ntohs(udp_h->src); + dest_port = ntohs(udp_h->dest); + } break; + + case IP_PROTO_TCP: + { + if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct tcp_hdr)) + { + return; + } + tcp_h = (struct tcp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)]; + src_port = ntohs(tcp_h->src); + dest_port = ntohs(tcp_h->dest); + } break; + + case IP_PROTO_ICMP: + { + src_port = dest_port = 0; + } break; + + // Drop anything that is not UDP, TCP, or ICMP + default: + { + acl_deny_count++; + return ACL_DENY; + } break; + } + + // os_printf("Src: %d.%d.%d.%d Dst: %d.%d.%d.%d Proto: %s SP:%d DP:%d\n", + // IP2STR(&ip_h->src), IP2STR(&ip_h->dest), + // proto==IP_PROTO_TCP?"TCP":proto==IP_PROTO_UDP?"UDP":"IP4", src_port, dest_port); + + for(i=0; iproto == 0 || proto == my_entry->proto) && + (my_entry->src == 0 || my_entry->src == (ip_h->src.addr&my_entry->s_mask)) && + (my_entry->dest == 0 || my_entry->dest == (ip_h->dest.addr&my_entry->d_mask)) && + (my_entry->s_port == 0 || my_entry->s_port == src_port) && + (my_entry->d_port == 0 || my_entry->d_port == dest_port)) + { + allow = my_entry->allow; + my_entry->hit_count++; + goto done; + } + } + +done: + if (!(allow & ACL_ALLOW) && my_deny_cb != NULL) + { + allow = my_deny_cb(proto, ip_h->src.addr, src_port, + ip_h->dest.addr, dest_port, allow); + } + if (allow & ACL_ALLOW) + { + acl_allow_count++; + } + else + { + acl_deny_count++; + } + + // os_printf(" allow: %d\r\n", allow); + return allow; +} + +void +acl_set_deny_cb(packet_deny_cb cb) +{ + my_deny_cb = cb; +} + +void ICACHE_FLASH_ATTR +addr2str(uint8_t *buf, uint32_t addr, uint32_t mask) +{ + uint8_t clidr; + + if (addr == 0) + { + os_sprintf(buf, "any"); + return; + } + + mask = ntohl(mask); + for (clidr = 0; mask; mask <<= 1,clidr++); + if (clidr < 32) + { + os_sprintf(buf, "%d.%d.%d.%d/%d", IP2STR((ip_addr_t*)&addr), clidr); + } + else + { + os_sprintf(buf, "%d.%d.%d.%d", IP2STR((ip_addr_t*)&addr)); + } +} + +void ICACHE_FLASH_ATTR +port2str(uint8_t *buf, uint16_t port) +{ + if (port == 0) + { + os_sprintf(buf, "any"); + } + else + { + os_sprintf(buf, "%d", port); + } +} + +void ICACHE_FLASH_ATTR +acl_show(uint8_t acl_no, uint8_t *buf) +{ + int i; + acl_entry *my_entry; + uint8_t line[80], addr1[21], addr2[21], port1[6], port2[6]; + + buf[0] = 0; + + if (acl_no >= MAX_NO_ACLS) + { + return; + } + + for(i = 0; i < acl_freep[acl_no]; i++) + { + my_entry = &acl[acl_no][i]; + addr2str(addr1, my_entry->src, my_entry->s_mask); + port2str(port1, my_entry->s_port); + addr2str(addr2, my_entry->dest, my_entry->d_mask); + port2str(port2, my_entry->d_port); + if (my_entry->proto != 0) + { + os_sprintf(line, "%s %s:%s %s:%s %s%s (%d hits)\r\n", + my_entry->proto==IP_PROTO_TCP?"TCP":"UDP", + addr1, port1, addr2, port2, + (my_entry->allow & ACL_ALLOW)?"allow":"deny", + (my_entry->allow & ACL_MONITOR)?"_monitor":"", + my_entry->hit_count); + } + else + { + os_sprintf(line, "IP %s %s %s%s (%d hits)\r\n", + addr1, addr2, + (my_entry->allow & ACL_ALLOW)?"allow":"deny", + (my_entry->allow & ACL_MONITOR)?"_monitor":"", + my_entry->hit_count); + } + os_memcpy(&buf[os_strlen(buf)], line, os_strlen(line)+1); + } +} diff --git a/user/acl.h b/user/acl.h new file mode 100644 index 0000000..1793caf --- /dev/null +++ b/user/acl.h @@ -0,0 +1,51 @@ +#ifndef _ACL_H_ +#define _ACL_H_ + +#include "lwip/ip.h" +#include "lwip/pbuf.h" + +#define MAX_NO_ACLS 4 +#define MAX_ACL_ENTRIES 16 + +#define ACL_DENY 0x0 +#define ACL_ALLOW 0x1 +#define ACL_MONITOR 0x2 + +typedef struct _acl_entry +{ + uint32_t src; + uint32_t s_mask; + uint32_t dest; + uint32_t d_mask; + uint16_t s_port; + uint16_t d_port; + uint8_t proto; + uint8_t allow; + uint32_t hit_count; +} acl_entry; + +extern acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES]; +extern uint8_t acl_freep[MAX_NO_ACLS]; +extern uint32_t acl_allow_count; +extern uint32_t acl_deny_count; + +typedef uint8_t (*packet_deny_cb)(uint8_t proto, uint32_t saddr, uint16_t s_port, uint32_t daddr, uint16_t d_port, uint8_t allow); + +void acl_init(); +bool acl_is_empty(uint8_t acl_no); +void acl_clear(uint8_t acl_no); +void acl_clear_stats(uint8_t acl_no); +bool acl_add(uint8_t acl_no, + uint32_t src, + uint32_t s_mask, + uint32_t dest, + uint32_t d_mask, + uint8_t proto, + uint16_t s_port, + uint16_t d_port, + uint8_t allow); +uint8_t acl_check_packet(uint8_t acl_no, struct pbuf *p); +void acl_set_deny_cb(packet_deny_cb cb); +void acl_show(uint8_t acl_no, uint8_t *buf); + +#endif /* _ACL_H_ */ diff --git a/user/config_flash.c b/user/config_flash.c new file mode 100644 index 0000000..6e2c1e2 --- /dev/null +++ b/user/config_flash.c @@ -0,0 +1,153 @@ +#include "user_interface.h" +#include "lwip/ip.h" +#include "config_flash.h" + + +/* From the document 99A-SDK-Espressif IOT Flash RW Operation_v0.2 * + * -------------------------------------------------------------------------* + * Flash is erased sector by sector, which means it has to erase 4Kbytes one + * time at least. When you want to change some data in flash, you have to + * erase the whole sector, and then write it back with the new data. + *--------------------------------------------------------------------------*/ +void +config_load_default(sysconfig_p config) +{ + uint8_t mac[6]; + + wifi_get_macaddr(STATION_IF, mac); + + os_memset(config, 0, sizeof(sysconfig_t)); + os_printf("Loading default configuration\r\n"); + config->magic_number = MAGIC_NUMBER; + config->length = sizeof(sysconfig_t); + os_sprintf(config->ssid,"%s", WIFI_SSID); + os_sprintf(config->password,"%s", WIFI_PASSWORD); + config->auto_connect = 0; + os_memset(config->bssid, 0, 6); + os_sprintf(config->sta_hostname, "ESP_%02x%02x%02x", mac[3], mac[4], mac[5]); + os_sprintf(config->ap_ssid,"%s", WIFI_AP_SSID); + + config->first_run = 1; + config->ap_watchdog = -1; + config->client_watchdog = -1; + + IP4_ADDR(&config->network_addr, 192, 168, 4, 1); + config->dns_addr.addr = 0; // use DHCP + config->my_addr.addr = 0; // use DHCP + config->my_netmask.addr = 0; // use DHCP + config->my_gw.addr = 0; // use DHCP +#ifdef PHY_MODE + config->phy_mode = 3; // mode n +#endif + config->clock_speed = 80; + config->status_led = STATUS_LED_GPIO; + + wifi_get_macaddr(STATION_IF, config->STA_MAC_address); + + config->dhcps_entries = 0; +#ifdef ACLS + acl_init(); // initializes the ACLs, written in config during save +#endif + + config->current_mac_address = 0; + // Interval to change mac address in seconds + // Default: 28800 (8 hours) + config->mac_change_interval = 600; + + // list of mac addresses + // from https://docs.google.com/spreadsheets/d/1su5u-vPrQwkTixR6YnOTWSi_Ls9lV-_XNJHaWIJspv4/edit#gid=0 + ets_str2macaddr(config->mac_list[0], "4E:53:50:4F:4F:40"); + ets_str2macaddr(config->mac_list[1], "4E:53:50:4F:4F:41"); + ets_str2macaddr(config->mac_list[2], "4E:53:50:4F:4F:42"); + ets_str2macaddr(config->mac_list[3], "4E:53:50:4F:4F:43"); + ets_str2macaddr(config->mac_list[4], "4E:53:50:4F:4F:44"); + ets_str2macaddr(config->mac_list[5], "4E:53:50:4F:4F:45"); + ets_str2macaddr(config->mac_list[6], "4E:53:50:4F:4F:46"); + ets_str2macaddr(config->mac_list[7], "4E:53:50:4F:4F:47"); + ets_str2macaddr(config->mac_list[8], "4E:53:50:4F:4F:48"); + ets_str2macaddr(config->mac_list[9], "4E:53:50:4F:4F:49"); + ets_str2macaddr(config->mac_list[10], "4E:53:50:4F:4F:4A"); + ets_str2macaddr(config->mac_list[11], "4E:53:50:4F:4F:4B"); + ets_str2macaddr(config->mac_list[12], "4E:53:50:4F:4F:4C"); + ets_str2macaddr(config->mac_list[13], "4E:53:50:4F:4F:4D"); + ets_str2macaddr(config->mac_list[14], "4E:53:50:4F:4F:4E"); + ets_str2macaddr(config->mac_list[15], "4E:53:50:4F:4F:4F"); +} + +int +config_load(sysconfig_p config) +{ + if (config == NULL) + { + return -1; + } + uint16_t base_address = FLASH_BLOCK_NO; + + spi_flash_read(base_address* SPI_FLASH_SEC_SIZE, &config->magic_number, 4); + + if((config->magic_number != MAGIC_NUMBER)) + { + os_printf("\r\nNo config found, saving default in flash\r\n"); + config_load_default(config); + config_save(config); + return -1; + } + + os_printf("\r\nConfig found and loaded\r\n"); + spi_flash_read(base_address * SPI_FLASH_SEC_SIZE, + (uint32 *) config, + sizeof(sysconfig_t)); + if (config->length != sizeof(sysconfig_t)) + { + os_printf("Length Mismatch, probably old version of config, loading defaults\r\n"); + config_load_default(config); + config_save(config); + return -1; + } +#ifdef ACLS + os_memcpy(&acl, &(config->acl), sizeof(acl)); + os_memcpy(&acl_freep, &(config->acl_freep), sizeof(acl_freep)); +#endif + return 0; +} + +void +config_save(sysconfig_p config) +{ + uint16_t base_address = FLASH_BLOCK_NO; +#ifdef ACLS + os_memcpy(&(config->acl), &acl, sizeof(acl)); + os_memcpy(&(config->acl_freep), &acl_freep, sizeof(acl_freep)); +#endif + os_printf("Saving configuration\r\n"); + spi_flash_erase_sector(base_address); + spi_flash_write(base_address * SPI_FLASH_SEC_SIZE, + (uint32 *)config, + sizeof(sysconfig_t)); +} + +void +blob_save(uint8_t blob_no, uint32_t *data, uint16_t len) +{ + uint16_t base_address = FLASH_BLOCK_NO + 1 + blob_no; + spi_flash_erase_sector(base_address); + spi_flash_write(base_address * SPI_FLASH_SEC_SIZE, data, len); +} + +void +blob_load(uint8_t blob_no, uint32_t *data, uint16_t len) +{ + uint16_t base_address = FLASH_BLOCK_NO + 1 + blob_no; + spi_flash_read(base_address * SPI_FLASH_SEC_SIZE, data, len); +} + +void +blob_zero(uint8_t blob_no, uint16_t len) +{ + int i; + uint8_t z[len]; + os_memset(z, 0,len); + uint16_t base_address = FLASH_BLOCK_NO + 1 + blob_no; + spi_flash_erase_sector(base_address); + spi_flash_write(base_address * SPI_FLASH_SEC_SIZE, (uint32_t *)z, len); +} diff --git a/user/config_flash.h b/user/config_flash.h new file mode 100644 index 0000000..bd920aa --- /dev/null +++ b/user/config_flash.h @@ -0,0 +1,81 @@ +#ifndef _CONFIG_FLASH_H_ +#define _CONFIG_FLASH_H_ + +#include "c_types.h" +#include "mem.h" +#include "ets_sys.h" +#include "osapi.h" +#include "gpio.h" +#include "os_type.h" +#include "spi_flash.h" +#include "lwip/app/dhcpserver.h" + +#include "user_config.h" +#include "acl.h" + +#define FLASH_BLOCK_NO 0xc + +#define MAGIC_NUMBER 0x112005fc + +#define MAX_MAC_LIST_LENGTH 15 + +typedef struct +{ + // To check if the structure is initialized or not in flash + uint32_t magic_number; + + // Length of the structure, since this is a evolving library, + // the variant may change hence used for verification + uint16_t length; + + /* Below variables are specific to my code */ + uint8_t ssid[32]; // SSID of the AP to connect to + uint8_t password[64]; // Password of the network + uint8_t auto_connect; // Should we auto connect + uint8_t bssid[6]; // Optional: BSSID the AP + uint8_t sta_hostname[32]; // Name of the station + uint8_t ap_ssid[32]; // SSID of the own AP + uint8_t first_run; // Has ESPerPass been configured yet? + uint8_t current_mac_address; // Holds currently broadcasted HomePass mac address index + int32_t mac_change_interval; // Interval to rotate HomePass mac address (in seconds) + + // Seconds without ap traffic will cause reset (-1 off, default) + int32_t ap_watchdog; + // Seconds without client traffic will cause reset (-1 off, default) + int32_t client_watchdog; + + ip_addr_t network_addr; // Address of the internal network + ip_addr_t dns_addr; // Optional: address of the dns server + + ip_addr_t my_addr; // Optional (if not DHCP): IP address of the uplink side + ip_addr_t my_netmask; // Optional (if not DHCP): IP netmask of the uplink side + ip_addr_t my_gw; // Optional (if not DHCP): Gateway of the uplink side +#ifdef PHY_MODE + uint16_t phy_mode; // WiFi PHY mode +#endif + uint16_t clock_speed; // Freq of the CPU + uint16_t status_led; // GPIO pin os the status LED (>16 disabled) + + uint8_t STA_MAC_address[6]; // MAC address of the STA + + uint16_t dhcps_entries; // number of allocated entries in the following table + struct dhcps_pool dhcps_p[MAX_DHCP]; // DHCP entries +#ifdef ACLS + acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES]; // ACL entries + uint8_t acl_freep[MAX_NO_ACLS]; // ACL free pointers +#endif + + // HomePass mac list + // Allow 20 slots + uint8_t mac_list[19][6]; + +} sysconfig_t, *sysconfig_p; + +int config_load(sysconfig_p config); +void config_save(sysconfig_p config); + +void blob_save(uint8_t blob_no, uint32_t *data, uint16_t len); +void blob_load(uint8_t blob_no, uint32_t *data, uint16_t len); +void blob_zero(uint8_t blob_no, uint16_t len); + +#endif diff --git a/user/ringbuf.c b/user/ringbuf.c new file mode 100644 index 0000000..7668b5e --- /dev/null +++ b/user/ringbuf.c @@ -0,0 +1,250 @@ +/* + * ringbuf.c - C ring buffer (FIFO) implementation. + * + * Written in 2011 by Drew Hess . + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "ringbuf.h" + +#include +#include +#include +#include +#include +#include + +#include "osapi.h" +#include "mem.h" + +#define assert(x) + +/* + * The code is written for clarity, not cleverness or performance, and + * contains many assert()s to enforce invariant assumptions and catch + * bugs. Feel free to optimize the code and to remove asserts for use + * in your own projects, once you're comfortable that it functions as + * intended. + */ + +struct ringbuf_t +{ + uint8_t *buf; + uint8_t *head, *tail; + size_t size; +}; + +ringbuf_t +ringbuf_new(size_t capacity) +{ + ringbuf_t rb = (ringbuf_t)os_malloc(sizeof(struct ringbuf_t)); + if (rb) { + + /* One byte is used for detecting the full condition. */ + rb->size = capacity + 1; + rb->buf = (uint8_t *)os_malloc(rb->size); + if (rb->buf) + ringbuf_reset(rb); + else { + os_free(rb); + return 0; + } + } + return rb; +} + +size_t +ringbuf_buffer_size(const struct ringbuf_t *rb) +{ + return rb->size; +} + +void +ringbuf_reset(ringbuf_t rb) +{ + rb->head = rb->tail = rb->buf; +} + +void +ringbuf_free(ringbuf_t *rb) +{ + assert(rb && *rb); + os_free((*rb)->buf); + os_free(*rb); + *rb = 0; +} + +size_t +ringbuf_capacity(const struct ringbuf_t *rb) +{ + return ringbuf_buffer_size(rb) - 1; +} + +/* + * Return a pointer to one-past-the-end of the ring buffer's + * contiguous buffer. You shouldn't normally need to use this function + * unless you're writing a new ringbuf_* function. + */ +static const uint8_t * +ringbuf_end(const struct ringbuf_t *rb) +{ + return rb->buf + ringbuf_buffer_size(rb); +} + +size_t +ringbuf_bytes_free(const struct ringbuf_t *rb) +{ + if (rb->head >= rb->tail) + return ringbuf_capacity(rb) - (rb->head - rb->tail); + else + return rb->tail - rb->head - 1; +} + +size_t +ringbuf_bytes_used(const struct ringbuf_t *rb) +{ + return ringbuf_capacity(rb) - ringbuf_bytes_free(rb); +} + +int +ringbuf_is_full(const struct ringbuf_t *rb) +{ + return ringbuf_bytes_free(rb) == 0; +} + +int +ringbuf_is_empty(const struct ringbuf_t *rb) +{ + return ringbuf_bytes_free(rb) == ringbuf_capacity(rb); +} + +const void * +ringbuf_tail(const struct ringbuf_t *rb) +{ + return rb->tail; +} + +const void * +ringbuf_head(const struct ringbuf_t *rb) +{ + return rb->head; +} + +/* + * Given a ring buffer rb and a pointer to a location within its + * contiguous buffer, return the a pointer to the next logical + * location in the ring buffer. + */ +static uint8_t * +ringbuf_nextp(ringbuf_t rb, const uint8_t *p) +{ + /* + * The assert guarantees the expression (++p - rb->buf) is + * non-negative; therefore, the modulus operation is safe and + * portable. + */ + assert((p >= rb->buf) && (p < ringbuf_end(rb))); + return rb->buf + ((++p - rb->buf) % ringbuf_buffer_size(rb)); +} + +void * +ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count) +{ + const uint8_t *u8src = src; + const uint8_t *bufend = ringbuf_end(dst); + int overflow = count > ringbuf_bytes_free(dst); + size_t nread = 0; + + while (nread != count) { + /* don't copy beyond the end of the buffer */ + assert(bufend > dst->head); + size_t n = MIN(bufend - dst->head, count - nread); + os_memcpy(dst->head, u8src + nread, n); + dst->head += n; + nread += n; + + /* wrap? */ + if (dst->head == bufend) + dst->head = dst->buf; + } + + if (overflow) { + dst->tail = ringbuf_nextp(dst, dst->head); + assert(ringbuf_is_full(dst)); + } + + return dst->head; +} + +void * +ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count) +{ + size_t bytes_used = ringbuf_bytes_used(src); + if (count > bytes_used) + return 0; + + uint8_t *u8dst = dst; + const uint8_t *bufend = ringbuf_end(src); + size_t nwritten = 0; + while (nwritten != count) { + assert(bufend > src->tail); + size_t n = MIN(bufend - src->tail, count - nwritten); + os_memcpy(u8dst + nwritten, src->tail, n); + src->tail += n; + nwritten += n; + + /* wrap ? */ + if (src->tail == bufend) + src->tail = src->buf; + } + + assert(count + ringbuf_bytes_used(src) == bytes_used); + return src->tail; +} + +void * +ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count) +{ + size_t src_bytes_used = ringbuf_bytes_used(src); + if (count > src_bytes_used) + return 0; + int overflow = count > ringbuf_bytes_free(dst); + + const uint8_t *src_bufend = ringbuf_end(src); + const uint8_t *dst_bufend = ringbuf_end(dst); + size_t ncopied = 0; + while (ncopied != count) { + assert(src_bufend > src->tail); + size_t nsrc = MIN(src_bufend - src->tail, count - ncopied); + assert(dst_bufend > dst->head); + size_t n = MIN(dst_bufend - dst->head, nsrc); + os_memcpy(dst->head, src->tail, n); + src->tail += n; + dst->head += n; + ncopied += n; + + /* wrap ? */ + if (src->tail == src_bufend) + src->tail = src->buf; + if (dst->head == dst_bufend) + dst->head = dst->buf; + } + + assert(count + ringbuf_bytes_used(src) == src_bytes_used); + + if (overflow) { + dst->tail = ringbuf_nextp(dst, dst->head); + assert(ringbuf_is_full(dst)); + } + + return dst->head; +} + diff --git a/user/ringbuf.h b/user/ringbuf.h new file mode 100644 index 0000000..c032b9e --- /dev/null +++ b/user/ringbuf.h @@ -0,0 +1,167 @@ +#ifndef INCLUDED_RINGBUF_H +#define INCLUDED_RINGBUF_H + +/* + * ringbuf.h - C ring buffer (FIFO) interface. + * + * Written in 2011 by Drew Hess . + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +/* + * A byte-addressable ring buffer FIFO implementation. + * + * The ring buffer's head pointer points to the starting location + * where data should be written when copying data *into* the buffer + * (e.g., with ringbuf_read). The ring buffer's tail pointer points to + * the starting location where data should be read when copying data + * *from* the buffer (e.g., with ringbuf_write). + */ + +#include +#include + +typedef struct ringbuf_t *ringbuf_t; + +/* + * Create a new ring buffer with the given capacity (usable + * bytes). Note that the actual internal buffer size may be one or + * more bytes larger than the usable capacity, for bookkeeping. + * + * Returns the new ring buffer object, or 0 if there's not enough + * memory to fulfill the request for the given capacity. + */ +ringbuf_t +ringbuf_new(size_t capacity); + +/* + * The size of the internal buffer, in bytes. One or more bytes may be + * unusable in order to distinguish the "buffer full" state from the + * "buffer empty" state. + * + * For the usable capacity of the ring buffer, use the + * ringbuf_capacity function. + */ +size_t +ringbuf_buffer_size(const struct ringbuf_t *rb); + +/* + * Deallocate a ring buffer, and, as a side effect, set the pointer to + * 0. + */ +void +ringbuf_free(ringbuf_t *rb); + +/* + * Reset a ring buffer to its initial state (empty). + */ +void +ringbuf_reset(ringbuf_t rb); + +/* + * The usable capacity of the ring buffer, in bytes. Note that this + * value may be less than the ring buffer's internal buffer size, as + * returned by ringbuf_buffer_size. + */ +size_t +ringbuf_capacity(const struct ringbuf_t *rb); + +/* + * The number of free/available bytes in the ring buffer. This value + * is never larger than the ring buffer's usable capacity. + */ +size_t +ringbuf_bytes_free(const struct ringbuf_t *rb); + +/* + * The number of bytes currently being used in the ring buffer. This + * value is never larger than the ring buffer's usable capacity. + */ +size_t +ringbuf_bytes_used(const struct ringbuf_t *rb); + +int +ringbuf_is_full(const struct ringbuf_t *rb); + +int +ringbuf_is_empty(const struct ringbuf_t *rb); + +/* + * Const access to the head and tail pointers of the ring buffer. + */ +const void * +ringbuf_tail(const struct ringbuf_t *rb); + +const void * +ringbuf_head(const struct ringbuf_t *rb); + +/* + * Copy n bytes from a contiguous memory area src into the ring buffer + * dst. Returns the ring buffer's new head pointer. + * + * It is possible to copy more data from src than is available in the + * buffer; i.e., it's possible to overflow the ring buffer using this + * function. When an overflow occurs, the state of the ring buffer is + * guaranteed to be consistent, including the head and tail pointers; + * old data will simply be overwritten in FIFO fashion, as + * needed. However, note that, if calling the function results in an + * overflow, the value of the ring buffer's tail pointer may be + * different than it was before the function was called. + */ +void * +ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count); + +/* + * Copy n bytes from the ring buffer src, starting from its tail + * pointer, into a contiguous memory area dst. Returns the value of + * src's tail pointer after the copy is finished. + * + * Note that this copy is destructive with respect to the ring buffer: + * the n bytes copied from the ring buffer are no longer available in + * the ring buffer after the copy is complete, and the ring buffer + * will have n more free bytes than it did before the function was + * called. + * + * This function will *not* allow the ring buffer to underflow. If + * count is greater than the number of bytes used in the ring buffer, + * no bytes are copied, and the function will return 0. + */ +void * +ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count); + +/* + * Copy count bytes from ring buffer src, starting from its tail + * pointer, into ring buffer dst. Returns dst's new head pointer after + * the copy is finished. + * + * Note that this copy is destructive with respect to the ring buffer + * src: any bytes copied from src into dst are no longer available in + * src after the copy is complete, and src will have 'count' more free + * bytes than it did before the function was called. + * + * It is possible to copy more data from src than is available in dst; + * i.e., it's possible to overflow dst using this function. When an + * overflow occurs, the state of dst is guaranteed to be consistent, + * including the head and tail pointers; old data will simply be + * overwritten in FIFO fashion, as needed. However, note that, if + * calling the function results in an overflow, the value dst's tail + * pointer may be different than it was before the function was + * called. + * + * It is *not* possible to underflow src; if count is greater than the + * number of bytes used in src, no bytes are copied, and the function + * returns 0. + */ +void * +ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count); + +#endif /* INCLUDED_RINGBUF_H */ + diff --git a/user/sys_time.c b/user/sys_time.c new file mode 100644 index 0000000..6748566 --- /dev/null +++ b/user/sys_time.c @@ -0,0 +1,36 @@ +#include "c_types.h" +#include "osapi.h" + +typedef union _timer { + uint32_t time_s[2]; + uint64_t time_l; +} long_time_t; + +static long_time_t time; +static uint32_t old; + +uint64_t ICACHE_FLASH_ATTR +get_long_systime() +{ + uint32_t now = system_get_time(); + if (now < old) + { + time.time_s[1]++; + } + old = now; + time.time_s[0] = now; + return time.time_l; +} + +uint64_t ICACHE_FLASH_ATTR +get_low_systime() +{ + get_long_systime(); + return time.time_s[0]; +} + +void init_long_systime() +{ + old = system_get_time(); + time.time_l = (uint64_t)old; +} diff --git a/user/sys_time.h b/user/sys_time.h new file mode 100644 index 0000000..43c3538 --- /dev/null +++ b/user/sys_time.h @@ -0,0 +1,13 @@ +#include "c_types.h" + +// returns time until boot in us +uint64_t ICACHE_FLASH_ATTR +get_long_systime(); + +// returns lower half of time until boot in us +uint64_t ICACHE_FLASH_ATTR +get_low_systime(); + +// initializes the timer +void +init_long_systime(); diff --git a/user/user_config.h b/user/user_config.h new file mode 100644 index 0000000..f4c5cc8 --- /dev/null +++ b/user/user_config.h @@ -0,0 +1,38 @@ +#ifndef _USER_CONFIG_ +#define _USER_CONFIG_ + +#define ESPERPASS_VERSION "V0.0.1" + +#define WIFI_SSID "ssid" +#define WIFI_PASSWORD "password" + +#define WIFI_AP_SSID "attwifi" + +#define MAX_CLIENTS 8 +#define MAX_DHCP 8 + +// +// Size of the console buffers +// +#define MAX_CON_SEND_SIZE 1024 +#define MAX_CON_CMD_SIZE 80 + +// +// Define this if you have a status LED connected to a GPIO pin +// +#define STATUS_LED_GPIO 2 + +// +// Define this to support the setting of the WiFi PHY mode +// +#define PHY_MODE 1 + +// +// Define this if you want to have ACLs for the SoftAP. +// +#define ACLS 1 + +// Internal +typedef enum {SIG_DO_NOTHING=0, SIG_START_SERVER=1, SIG_SEND_DATA, SIG_UART0, SIG_CONSOLE_RX, SIG_CONSOLE_TX, SIG_CONSOLE_TX_RAW, SIG_GPIO_INT} USER_SIGNALS; + +#endif diff --git a/user/user_main.c b/user/user_main.c new file mode 100644 index 0000000..a8b37b5 --- /dev/null +++ b/user/user_main.c @@ -0,0 +1,1494 @@ +#include "c_types.h" +#include "mem.h" +#include "ets_sys.h" +#include "osapi.h" +#include "gpio.h" +#include "os_type.h" +#include "lwip/ip.h" +#include "lwip/netif.h" +#include "lwip/dns.h" +#include "lwip/lwip_napt.h" +#include "lwip/app/dhcpserver.h" +#include "lwip/app/espconn.h" +#include "lwip/app/espconn_tcp.h" + +#include "user_interface.h" +#include "string.h" +#include "driver/uart.h" + +#include "ringbuf.h" +#include "user_config.h" +#include "config_flash.h" +#include "sys_time.h" + +#include "easygpio.h" + +#ifdef ACLS +#include "acl.h" +#endif + +/* System Task, for signals refer to user_config.h */ +#define user_procTaskPrio 0 +#define user_procTaskQueueLen 1 +os_event_t user_procTaskQueue[user_procTaskQueueLen]; +static void user_procTask(os_event_t *events); + +static os_timer_t ptimer; + +int32_t ap_watchdog_cnt; +int32_t client_watchdog_cnt; +int32_t mac_cnt; + +/* Some stats */ +uint64_t Bytes_in, Bytes_out, Bytes_in_last, Bytes_out_last; +uint32_t Packets_in, Packets_out, Packets_in_last, Packets_out_last; +uint64_t t_old; + +/* Hold the system wide configuration */ +sysconfig_t config; + +static ringbuf_t console_rx_buffer, console_tx_buffer; + +static ip_addr_t my_ip; +static ip_addr_t dns_ip; +bool connected; +uint8_t my_channel; +bool do_ip_config; + +static netif_input_fn orig_input_ap, orig_input_sta; +static netif_linkoutput_fn orig_output_ap, orig_output_sta; + +uint8_t remote_console_disconnect; +struct espconn *currentconn; + +void ICACHE_FLASH_ATTR user_set_softap_wifi_config(void); +void ICACHE_FLASH_ATTR user_set_softap_ip_config(void); +void ICACHE_FLASH_ATTR user_set_station_config(void); + +void +ICACHE_FLASH_ATTR to_console(char *str) +{ + ringbuf_memcpy_into(console_tx_buffer, str, os_strlen(str)); +} + +err_t ICACHE_FLASH_ATTR +my_input_ap(struct pbuf *p, struct netif *inp) +{ + // os_printf("Got packet from STA\r\n"); + + if (config.status_led <= 16) + { + easygpio_outputSet (config.status_led, 1); + } + + client_watchdog_cnt = config.client_watchdog; + +#ifdef ACLS + // Check ACLs - store result + uint8_t acl_check = ACL_ALLOW; + if (!acl_is_empty(0)) + { + acl_check = acl_check_packet(0, p); + } +#endif + +#ifdef ACLS + // If not allowed, drop packet + if (!(acl_check&ACL_ALLOW)) + { + pbuf_free(p); + return; + } +#endif + + Bytes_in += p->tot_len; + Packets_in++; + + orig_input_ap (p, inp); +} + +err_t ICACHE_FLASH_ATTR +my_output_ap(struct netif *outp, struct pbuf *p) +{ + // os_printf("Send packet to STA\r\n"); + + if (config.status_led <= 16) + { + easygpio_outputSet (config.status_led, 0); + } + +#ifdef ACLS + // Check ACLs - store result + uint8_t acl_check = ACL_ALLOW; + if (!acl_is_empty(1)) + { + acl_check = acl_check_packet(1, p); + } +#endif + +#ifdef ACLS + // If not allowed, drop packet + if (!(acl_check&ACL_ALLOW)) + { + pbuf_free(p); + return; + } +#endif + + Bytes_out += p->tot_len; + Packets_out++; + + orig_output_ap (outp, p); +} + +err_t ICACHE_FLASH_ATTR +my_input_sta(struct pbuf *p, struct netif *inp) +{ + ap_watchdog_cnt = config.ap_watchdog; +#ifdef ACLS + if (!acl_is_empty(2) && !(acl_check_packet(2, p) & ACL_ALLOW)) + { + pbuf_free(p); + return; + } +#endif + orig_input_sta (p, inp); +} + +err_t ICACHE_FLASH_ATTR +my_output_sta(struct netif *outp, struct pbuf *p) +{ +#ifdef ACLS + if (!acl_is_empty(3) && !(acl_check_packet(3, p) & ACL_ALLOW)) + { + pbuf_free(p); + return; + } +#endif + orig_output_sta (outp, p); +} + +static void ICACHE_FLASH_ATTR +patch_netif(ip_addr_t netif_ip, + netif_input_fn ifn, + netif_input_fn *orig_ifn, + netif_linkoutput_fn ofn, + netif_linkoutput_fn *orig_ofn, + bool nat) +{ + struct netif *nif; + + for (nif = netif_list; + nif != NULL && nif->ip_addr.addr != netif_ip.addr; + nif = nif->next); + + if (nif == NULL) + { + return; + } + + nif->napt = nat?1:0; + if (ifn != NULL && nif->input != ifn) + { + *orig_ifn = nif->input; + nif->input = ifn; + } + if (ofn != NULL && nif->linkoutput != ofn) + { + *orig_ofn = nif->linkoutput; + nif->linkoutput = ofn; + } +} + +int ICACHE_FLASH_ATTR +parse_str_into_tokens(char *str, char **tokens, int max_tokens) +{ + char *p, *q, *end; + int token_count = 0; + bool in_token = false; + + // preprocessing + for (p = q = str; *p != 0; p++) + { + if (*(p) == '%' && *(p+1) != 0 && *(p+2) != 0) + { + // quoted hex + uint8_t a; + p++; + if (*p <= '9') + a = *p - '0'; + else + a = toupper(*p) - 'A' + 10; + a <<= 4; + p++; + if (*p <= '9') + a += *p - '0'; + else + a += toupper(*p) - 'A' + 10; + *q++ = a; + } + else if (*p == '\\' && *(p+1) != 0) + { + // next char is quoted - just copy it, skip this one + *q++ = *++p; + } + else if (*p == 8) + { + // backspace - delete previous char + if (q != str) + { + q--; + } + } + else if (*p <= ' ') + { + // mark this as whitespace + *q++ = 0; + } + else + { + *q++ = *p; + } + } + + end = q; + *q = 0; + + // cut into tokens + for (p = str; p != end; p++) + { + if (*p == 0) + { + if (in_token) + { + in_token = false; + } + } + else + { + if (!in_token) + { + tokens[token_count++] = p; + if (token_count == max_tokens) + { + return token_count; + } + in_token = true; + } + } + } + return token_count; +} + +void +console_send_response(struct espconn *pespconn, uint8_t do_cmd) +{ + char payload[MAX_CON_SEND_SIZE+4]; + uint16_t len = ringbuf_bytes_used(console_tx_buffer); + + ringbuf_memcpy_from(payload, console_tx_buffer, len); + + if (do_cmd) + { + os_memcpy(&payload[len], "CMD>", 4); + len += 4; + } + + if (pespconn != NULL) + { + espconn_sent(pespconn, payload, len); + } + else + { + UART_Send(0, &payload, len); + } +} + + +#ifdef ACLS +void ICACHE_FLASH_ATTR +parse_IP_addr(uint8_t *str, uint32_t *addr, uint32_t *mask) +{ + int i; + uint32_t net; + if (strcmp(str, "any") == 0) + { + *addr = 0; + *mask = 0; + return; + } + + for(i=0; str[i]!=0 && str[i]!='/'; i++); + + *mask = 0xffffffff; + if (str[i]!=0) + { + str[i]=0; + *mask <<= (32 - atoi(&str[i+1])); + } + *mask = htonl(*mask); + *addr = ipaddr_addr(str); +} + +struct espconn *deny_cb_conn = 0; +uint8_t acl_debug = 0; + +uint8_t +acl_deny_cb(uint8_t proto, + uint32_t saddr, + uint16_t s_port, + uint32_t daddr, + uint16_t d_port, + uint8_t allow) +{ + char response[128]; + + if (!acl_debug) + { + return allow; + } + + os_sprintf(response, + "\rdeny: %s Src: %d.%d.%d.%d:%d Dst: %d.%d.%d.%d:%d\r\n", + proto==IP_PROTO_TCP?"TCP":proto==IP_PROTO_UDP?"UDP":"IP4", + IP2STR((ip_addr_t *)&saddr), + s_port, + IP2STR((ip_addr_t *)&daddr), + d_port); + + if (acl_debug) + { + to_console(response); + system_os_post(0, SIG_CONSOLE_TX, (ETSParam) deny_cb_conn); + } + return allow; +} +#endif /* ACLS */ + +// Use this from ROM instead +int ets_str2macaddr(uint8 *mac, char *str_mac); +#define parse_mac ets_str2macaddr +/*bool parse_mac(uint8_t *mac, uint8_t *inp) +{ +int i; + + if (os_strlen(inp) != 17) return false; + for (i=0; i<17; i++) { + if (inp[i] == ':') continue; + inp[i] = toupper(inp[i]); + inp[i] = inp[i] <= '9'? inp[i]-'0' : (inp[i]-'A')+10; + if (inp[i] >= 16) return false; + } + + for (i=0; i<17; i+=3) { + *mac++ = inp[i]*16+inp[i+1]; + } + return true; +} +*/ +static char INVALID_NUMARGS[] = "Invalid number of arguments\r\n"; +static char INVALID_ARG[] = "Invalid argument\r\n"; + +void ICACHE_FLASH_ATTR +console_handle_command(struct espconn *pespconn) +{ + #define MAX_CMD_TOKENS 9 + + char cmd_line[MAX_CON_CMD_SIZE+1]; + char response[256]; + char *tokens[MAX_CMD_TOKENS]; + + int bytes_count, nTokens; + + bytes_count = ringbuf_bytes_used(console_rx_buffer); + ringbuf_memcpy_from(cmd_line, console_rx_buffer, bytes_count); + + cmd_line[bytes_count] = 0; + response[0] = 0; + + nTokens = parse_str_into_tokens(cmd_line, tokens, MAX_CMD_TOKENS); + + if (nTokens == 0) + { + char c = '\n'; + ringbuf_memcpy_into(console_tx_buffer, &c, 1); + goto command_handled_2; + } + + if (strcmp(tokens[0], "help") == 0) + { + os_sprintf(response, "show [config|stats]\r\n"); + to_console(response); + + os_sprintf(response, "set [ssid|password|auto_connect|ap_ssid] \r\nset [sta_mac|sta_hostname] \r\nset [dns|ip|netmask|gw] \r\n"); + to_console(response); + os_sprintf(response, "set [speed|status_led|config_port] \r\nsave [config|dhcp]\r\nconnect | disconnect| reset [factory] | quit\r\n"); + to_console(response); + os_sprintf(response, "set [client_watchdog|ap_watchdog] \r\n"); + to_console(response); +#ifdef PHY_MODE + os_sprintf(response, "set phy_mode [1|2|3]\r\n"); + to_console(response); +#endif + +#ifdef ACLS + os_sprintf(response, "acl [from_sta|to_sta|from_ap|to_ap] clear\r\nacl [from_sta|to_sta|from_ap|to_ap] [IP|TCP|UDP] [] [] [allow|deny|allow_monitor|deny_monitor]\r\n"); + to_console(response); +#endif + goto command_handled_2; + } + + if (strcmp(tokens[0], "mac_list") == 0) + { + // List stored HomePass mac addresses + int16_t i; + + to_console("HomePass mac list:\r\n"); + for (i = 0; i < MAX_MAC_LIST_LENGTH; i++) + { + os_sprintf(response, "%02x:%02x:%02x:%02x:%02x:%02x\r\n", + config.mac_list[i][0], config.mac_list[i][1], + config.mac_list[i][2], config.mac_list[i][3], + config.mac_list[i][4], config.mac_list[i][5]); + to_console(response); + } + os_sprintf(response, "\r\n"); + to_console(response); + + goto command_handled_2; + } + + if (strcmp(tokens[0], "show") == 0) + { + int16_t i; + ip_addr_t i_ip; + + if (nTokens == 1 || (nTokens == 2 && strcmp(tokens[1], "config") == 0)) + { + os_sprintf(response, + "Version %s (build: %s)\r\n", + ESPERPASS_VERSION, __TIMESTAMP__); + to_console(response); + + os_sprintf(response, "STA: SSID:%s PW:%s%s\r\n", + config.ssid, + (char*)config.password, + config.auto_connect?"":" [AutoConnect:0]"); + to_console(response); + if (*(int*)config.bssid != 0) + { + os_sprintf(response, "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\r\n", + config.bssid[0], config.bssid[1], config.bssid[2], + config.bssid[3], config.bssid[4], config.bssid[5]); + to_console(response); + } + + os_sprintf(response, "AP: SSID:%s IP:%d.%d.%d.%d/24", + config.ap_ssid, + IP2STR(&config.network_addr)); + to_console(response); + + // if static DNS, add it + os_sprintf(response, + config.dns_addr.addr?" DNS: %d.%d.%d.%d\r\n":"\r\n", + IP2STR(&config.dns_addr)); + to_console(response); + + // if static IP, add it + os_sprintf(response, + config.my_addr.addr?"Static IP: %d.%d.%d.%d Netmask: %d.%d.%d.%d Gateway: %d.%d.%d.%d\r\n":"", + IP2STR(&config.my_addr), IP2STR(&config.my_netmask), + IP2STR(&config.my_gw)); + to_console(response); + + os_sprintf(response, + "STA MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\nAP MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n", + config.STA_MAC_address[0], config.STA_MAC_address[1], + config.STA_MAC_address[2], config.STA_MAC_address[3], + config.STA_MAC_address[4], config.STA_MAC_address[5], + config.mac_list[config.current_mac_address][0], + config.mac_list[config.current_mac_address][1], + config.mac_list[config.current_mac_address][2], + config.mac_list[config.current_mac_address][3], + config.mac_list[config.current_mac_address][4], + config.mac_list[config.current_mac_address][5]); + to_console(response); + os_sprintf(response, "STA hostname: %s\r\n", config.sta_hostname); + to_console(response); + + os_sprintf(response, "Clock speed: %d\r\n", config.clock_speed); + to_console(response); + + goto command_handled_2; + } + + if (nTokens == 2 && strcmp(tokens[1], "stats") == 0) + { + uint32_t time = (uint32_t)(get_long_systime()/1000000); + int16_t i; + enum phy_mode phy; + struct dhcps_pool *p; + os_sprintf(response, "System uptime: %d:%02d:%02d\r\n", + time/3600, (time%3600)/60, time%60); + to_console(response); + os_sprintf(response, + "%d KiB in (%d packets)\r\n%d KiB out (%d packets)\r\n", + (uint32_t)(Bytes_in/1024), Packets_in, + (uint32_t)(Bytes_out/1024), Packets_out); + to_console(response); +#ifdef PHY_MODE + phy = wifi_get_phy_mode(); + os_sprintf(response, "Phy mode: %c\r\n", + phy == PHY_MODE_11B?'b':phy == PHY_MODE_11G?'g':'n'); + to_console(response); +#endif + os_sprintf(response, "Free mem: %d\r\n", system_get_free_heap_size()); + to_console(response); + if (connected) + { + os_sprintf(response, "External IP-address: " IPSTR "\r\n", IP2STR(&my_ip)); + } + else + { + os_sprintf(response, "Not connected to AP\r\n"); + } + to_console(response); + + os_sprintf(response, + "%d Station%s connected to SoftAP\r\n", + wifi_softap_get_station_num(), + wifi_softap_get_station_num()==1?"":"s"); + + to_console(response); + for (i = 0; p = dhcps_get_mapping(i); i++) + { + os_sprintf(response, + "Station: %02x:%02x:%02x:%02x:%02x:%02x - " IPSTR "\r\n", + p->mac[0], p->mac[1], p->mac[2], p->mac[3], p->mac[4], + p->mac[5], IP2STR(&p->ip)); + to_console(response); + } + + if (config.ap_watchdog >= 0 || config.client_watchdog >= 0) + { + os_sprintf(response, "AP watchdog: %d Client watchdog: %d\r\n", + ap_watchdog_cnt, client_watchdog_cnt); + to_console(response); + } + goto command_handled_2; + } +#ifdef ACLS + if (nTokens == 2 && strcmp(tokens[1], "acl") == 0) + { + char *txt[] = {"From STA:\r\n", + "To STA:\r\n", "From AP:\r\n", "To AP:\r\n"}; + for (i = 0; i 1) + { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + + user_set_station_config(); + os_sprintf(response, "Trying to connect to ssid %s, password: %s\r\n", config.ssid, config.password); + + wifi_station_disconnect(); + wifi_station_connect(); + + goto command_handled; + } + + if (strcmp(tokens[0], "disconnect") == 0) + { + if (nTokens > 1) + { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + + os_sprintf(response, "Disconnect from ssid\r\n"); + + wifi_station_disconnect(); + + goto command_handled; + } + + if (strcmp(tokens[0], "save") == 0) + { + if (nTokens == 1 || (nTokens == 2 && strcmp(tokens[1], "config") == 0)) + { + config.first_run = 0; + config_save(&config); + os_sprintf(response, "Config saved\r\n"); + goto command_handled; + } + + if (nTokens == 2 && strcmp(tokens[1], "dhcp") == 0) + { + int16_t i; + struct dhcps_pool *p; + + for (i = 0; i 16) + { + os_sprintf(response, "Status led disabled\r\n"); + goto command_handled; + } + if (config.status_led == 1) + { + // Disable output if serial pin is used as status LED + system_set_os_print(0); + } + easygpio_pinMode(config.status_led, EASYGPIO_NOPULL, EASYGPIO_OUTPUT); + easygpio_outputSet (config.status_led, 0); + os_sprintf(response, "Status led set to GPIO %d\r\n", + config.status_led); + goto command_handled; + } + +#ifdef PHY_MODE + if (strcmp(tokens[1], "phy_mode") == 0) + { + uint16_t mode = atoi(tokens[2]); + bool succ = wifi_set_phy_mode(mode); + if (succ) + { + config.phy_mode = mode; + } + os_sprintf(response, "Phy mode setting %s\r\n", + succ?"successful":"failed"); + goto command_handled; + } +#endif + if (strcmp(tokens[1], "network") == 0) + { + config.network_addr.addr = ipaddr_addr(tokens[2]); + ip4_addr4(&config.network_addr) = 0; + os_sprintf(response, "Network set to %d.%d.%d.%d/24\r\n", + IP2STR(&config.network_addr)); + goto command_handled; + } + + if (strcmp(tokens[1], "dns") == 0) + { + if (os_strcmp(tokens[2], "dhcp") == 0) + { + config.dns_addr.addr = 0; + os_sprintf(response, "DNS from DHCP\r\n"); + } + else + { + config.dns_addr.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "DNS set to %d.%d.%d.%d\r\n", + IP2STR(&config.dns_addr)); + if (config.dns_addr.addr) + { + dns_ip.addr = config.dns_addr.addr; + dhcps_set_DNS(&dns_ip); + } + } + goto command_handled; + } + + if (strcmp(tokens[1], "ip") == 0) + { + if (os_strcmp(tokens[2], "dhcp") == 0) + { + config.my_addr.addr = 0; + os_sprintf(response, "IP from DHCP\r\n"); + } + else + { + config.my_addr.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "IP address set to %d.%d.%d.%d\r\n", + IP2STR(&config.my_addr)); + } + goto command_handled; + } + + if (strcmp(tokens[1],"netmask") == 0) + { + config.my_netmask.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "IP netmask set to %d.%d.%d.%d\r\n", + IP2STR(&config.my_netmask)); + goto command_handled; + } + + if (strcmp(tokens[1],"gw") == 0) + { + config.my_gw.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "Gateway set to %d.%d.%d.%d\r\n", + IP2STR(&config.my_gw)); + goto command_handled; + } + + if (strcmp(tokens[1],"sta_mac") == 0) + { + if (!parse_mac(config.STA_MAC_address, tokens[2])) + { + os_sprintf(response, INVALID_ARG); + } + else + { + os_sprintf(response, "STA MAC set\r\n"); + } + goto command_handled; + } + + if (strcmp(tokens[1],"bssid") == 0) + { + if (!parse_mac(config.bssid, tokens[2])) + { + os_sprintf(response, INVALID_ARG); + } + else + { + os_sprintf(response, "bssid set\r\n"); + } + goto command_handled; + } + } + } + + /* Control comes here only if the tokens[0] command is not handled */ + os_sprintf(response, "\r\nInvalid Command\r\n"); + +command_handled: + to_console(response); + +command_handled_2: + system_os_post(0, SIG_CONSOLE_TX, (ETSParam) pespconn); + + return; +} + +bool toggle; +// Timer cb function +void ICACHE_FLASH_ATTR +timer_func(void *arg) +{ + uint32_t Vcurr; + uint64_t t_new; + uint32_t t_diff; + + toggle = !toggle; + + // Check if watchdogs + if (toggle) + { + // Rotate HomePass mac address if necessary + if (config.auto_connect == 1) + { + if (mac_cnt >= config.mac_change_interval) + { + mac_cnt = 0; + // os_printf("Rotating mac address...\r\n"); + // os_printf("config.current_mac_address = %d\r\n", config.current_mac_address); + + // os_printf("OLD MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n", + // config.mac_list[config.current_mac_address][0], + // config.mac_list[config.current_mac_address][1], + // config.mac_list[config.current_mac_address][2], + // config.mac_list[config.current_mac_address][3], + // config.mac_list[config.current_mac_address][4], + // config.mac_list[config.current_mac_address][5]); + + if (config.current_mac_address >= (MAX_MAC_LIST_LENGTH - 1)) + { + config.current_mac_address = 0; + } + else + { + config.current_mac_address++; + } + + // os_printf("NEW MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n\r\n", + // config.mac_list[config.current_mac_address][0], + // config.mac_list[config.current_mac_address][1], + // config.mac_list[config.current_mac_address][2], + // config.mac_list[config.current_mac_address][3], + // config.mac_list[config.current_mac_address][4], + // config.mac_list[config.current_mac_address][5]); + + // Save current mac address config to flash + config_save(&config); + + // Start using new mac address + // wifi_set_macaddr(SOFTAP_IF, config.mac_list[config.current_mac_address]); + system_restart(); + } + else + { + mac_cnt++; + } + } + + if (ap_watchdog_cnt >= 0) + { + if (ap_watchdog_cnt == 0) + { + os_printf("AP watchdog reset\r\n"); + system_restart(); + } + ap_watchdog_cnt--; + } + + if (client_watchdog_cnt >= 0) + { + if (client_watchdog_cnt == 0) + { + os_printf("Client watchdog reset\r\n"); + system_restart(); + } + client_watchdog_cnt--; + } + } + + if (config.status_led <= 16) + { + easygpio_outputSet (config.status_led, toggle && connected); + } + + // Do we still have to configure the AP netif? + if (do_ip_config) + { + user_set_softap_ip_config(); + do_ip_config = false; + } + + t_new = get_long_systime(); + + os_timer_arm(&ptimer, toggle?900:100, 0); +} + +//Priority 0 Task +static void ICACHE_FLASH_ATTR +user_procTask(os_event_t *events) +{ + //os_printf("Sig: %d\r\n", events->sig); + + switch(events->sig) + { + case SIG_START_SERVER: + { + // Anything else to do here, when the repeater has received its IP? + } break; + + case SIG_CONSOLE_TX: + case SIG_CONSOLE_TX_RAW: + { + struct espconn *pespconn = (struct espconn *) events->par; + console_send_response(pespconn, events->sig == SIG_CONSOLE_TX); + + if (pespconn != 0 && remote_console_disconnect) + { + espconn_disconnect(pespconn); + } + remote_console_disconnect = 0; + } break; + + case SIG_CONSOLE_RX: + { + struct espconn *pespconn = (struct espconn *) events->par; + console_handle_command(pespconn); + } break; + + case SIG_DO_NOTHING: + default: + { + // Intentionally ignoring other signals + os_printf("Spurious Signal received\r\n"); + } break; + } +} + +/* Callback called when the connection state of the module with an Access Point changes */ +void +wifi_handle_event_cb(System_Event_t *evt) +{ + uint16_t i; + uint8_t mac_str[20]; + + //os_printf("wifi_handle_event_cb: "); + switch (evt->event) + { + case EVENT_STAMODE_CONNECTED: + { + os_printf("connect to ssid %s, channel %d\r\n", + evt->event_info.connected.ssid, + evt->event_info.connected.channel); + my_channel = evt->event_info.connected.channel; + } break; + + case EVENT_STAMODE_DISCONNECTED: + { + os_printf("disconnect from ssid %s, reason %d\r\n", + evt->event_info.disconnected.ssid, + evt->event_info.disconnected.reason); + connected = false; + } break; + + case EVENT_STAMODE_AUTHMODE_CHANGE: + { + // os_printf("mode: %d -> %d\r\n", + // evt->event_info.auth_change.old_mode, + // evt->event_info.auth_change.new_mode); + } break; + + case EVENT_STAMODE_GOT_IP: + { + if (config.dns_addr.addr == 0) + { + dns_ip = dns_getserver(0); + } + dhcps_set_DNS(&dns_ip); + + os_printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR ",dns:" IPSTR "\n", + IP2STR(&evt->event_info.got_ip.ip), + IP2STR(&evt->event_info.got_ip.mask), + IP2STR(&evt->event_info.got_ip.gw), + IP2STR(&dns_ip)); + + my_ip = evt->event_info.got_ip.ip; + connected = true; + + patch_netif(my_ip, my_input_sta, &orig_input_sta, my_output_sta, &orig_output_sta, false); + + // Post a Server Start message as the IP has been acquired to Task with priority 0 + system_os_post(user_procTaskPrio, SIG_START_SERVER, 0 ); + } break; + + case EVENT_SOFTAPMODE_STACONNECTED: + { + os_sprintf(mac_str, MACSTR, MAC2STR(evt->event_info.sta_connected.mac)); + os_printf("station: %s join, AID = %d\r\n", + mac_str, evt->event_info.sta_connected.aid); + ip_addr_t ap_ip = config.network_addr; + ip4_addr4(&ap_ip) = 1; + patch_netif(ap_ip, my_input_ap, &orig_input_ap, my_output_ap, + &orig_output_ap, true); + } break; + + case EVENT_SOFTAPMODE_STADISCONNECTED: + { + os_sprintf(mac_str, MACSTR, + MAC2STR(evt->event_info.sta_disconnected.mac)); + os_printf("station: %s leave, AID = %d\r\n", mac_str, + evt->event_info.sta_disconnected.aid); + } break; + + default: + { + // Do nothing + } break; + } +} + +void ICACHE_FLASH_ATTR +user_set_softap_wifi_config(void) +{ + struct softap_config apConfig; + + wifi_softap_get_config(&apConfig); // Get config first. + + os_memset(apConfig.ssid, 0, 32); + os_sprintf(apConfig.ssid, "%s", config.ap_ssid); + apConfig.authmode = AUTH_OPEN; + apConfig.ssid_len = 0;// or its actual length + + // how many stations can connect to ESP8266 softAP at most. + apConfig.max_connection = MAX_CLIENTS; + + // Set ESP8266 softap config + wifi_softap_set_config(&apConfig); +} + +void ICACHE_FLASH_ATTR +user_set_softap_ip_config(void) +{ + struct ip_info info; + struct dhcps_lease dhcp_lease; + struct netif *nif; + int i; + + // Configure the internal network + + // Find the netif of the AP (that with num != 0) + for (nif = netif_list; nif != NULL && nif->num == 0; nif = nif->next); + if (nif == NULL) + { + return; + } + + // If is not 1, set it to 1. + // Kind of a hack, but the Espressif-internals expect it like this (hardcoded 1). + nif->num = 1; + + wifi_softap_dhcps_stop(); + + info.ip = config.network_addr; + ip4_addr4(&info.ip) = 1; + info.gw = info.ip; + IP4_ADDR(&info.netmask, 255, 255, 255, 0); + + wifi_set_ip_info(nif->num, &info); + + dhcp_lease.start_ip = config.network_addr; + ip4_addr4(&dhcp_lease.start_ip) = 2; + dhcp_lease.end_ip = config.network_addr; + ip4_addr4(&dhcp_lease.end_ip) = 128; + wifi_softap_set_dhcps_lease(&dhcp_lease); + + wifi_softap_dhcps_start(); + + // Change the DNS server again + dhcps_set_DNS(&dns_ip); + + // Enter any saved dhcp enties if they are in this network + for (i = 0; i prompt and follow these instructions:\r\n"); + os_printf("Note that the console does not support the backspace key.\r\n"); + os_printf("If you make a mistake, hit return and try the command again.\r\n\r\n"); + os_printf("1. Set your Internet WiFi ssid: set ssid \r\n"); + os_printf("2. Set your Internet WiFi password: set password \r\n"); + os_printf("3. Save the settings: save\r\n"); + os_printf("4. Restart the device: reset\r\n"); + os_printf("\r\n"); + + // Disable any further verbose system output + system_set_os_print(0); + } + else + { + // Now start the STA-Mode + user_set_station_config(); + } + + system_update_cpu_freq(config.clock_speed); + + // Start the timer + os_timer_setfn(&ptimer, timer_func, 0); + os_timer_arm(&ptimer, 500, 0); + + //Start task + system_os_task(user_procTask, user_procTaskPrio, user_procTaskQueue, + user_procTaskQueueLen); +}