diff --git a/Bootloader/.gitignore b/Bootloader/.gitignore new file mode 100644 index 0000000..bdb41b7 --- /dev/null +++ b/Bootloader/.gitignore @@ -0,0 +1,3 @@ +*.o +*.hex +*.elf \ No newline at end of file diff --git a/Bootloader/Makefile b/Bootloader/Makefile new file mode 100644 index 0000000..72cf373 --- /dev/null +++ b/Bootloader/Makefile @@ -0,0 +1,66 @@ +PROJECT = MyOtaBootloader +INCLUDES = ../libraries/MySensors + +MCU = atmega328p +CLK = 16000000L + +ISP_PORT = com5 +ISP_SPEED = 115200 +ISP_PROTOCOL = stk500v2 +ISP_MCU = m328p +# HFUSE = D8 - 4096 byte boot +ISP_HFUSE = D8 +# LFUSE = 4E - Low power resonator (16MHz), fast start, clkdiv/8 +ISP_LFUSE = FF +# EFUSE = 06 - 1.8V brownout +ISP_EFUSE = 06 +ISP_ARGS = -c$(ISP_PROTOCOL) -P$(ISP_PORT) -b$(ISP_SPEED) -p$(ISP_MCU) + +ifeq ($(OS),Windows_NT) + BINPATH = C:/Program Files (x86)/Arduino/hardware/tools/avr/bin/ + JAVAPATH = C:/Program Files/Java/jdk1.7.0_40/bin/ + JAVAC = $(JAVAPATH)javac.exe + JAVA = $(JAVAPATH)java.exe +else + UNAME_S := $(shell uname -s) + UNAME_P := $(shell uname -p) + UNAME_M := $(shell uname -m) + ifeq ($(UNAME_S),Linux) + ifeq ($(UNAME_P),x86_64) + BINPATH = ../arduino/bin-linux64/bin/ + else ifneq ($(filter %86,$(UNAME_P)),) + BINPATH = ../arduino/bin-linux32/bin/ + else ifneq ($(filter arm%,$(UNAME_M)),) + BINPATH = /usr/bin/ + endif + endif +endif + +CFLAGS = -c -g -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -Wall -mmcu=$(MCU) -DF_CPU=$(CLK) -std=gnu99 +LDFLAGS = -Os -Wl,--section-start=.text=0x7000 -nostartfiles -mmcu=$(MCU) + +all: clean out + +clean: + - rm *.o + - rm *.elf + - rm *.hex + +$(PROJECT).o: $(PROJECT).c + "$(BINPATH)avr-gcc" $(CFLAGS) -I$(INCLUDES) $< -o $@ + +$(PROJECT).elf: $(PROJECT).o + "$(BINPATH)avr-gcc" $(LDFLAGS) -o $@ $< -lm + +$(PROJECT).hex: $(PROJECT).elf + "$(BINPATH)avr-objcopy" -O ihex -R .eeprom $< $@ + +out: $(PROJECT).hex + "$(BINPATH)avr-size" $(PROJECT).elf + +load: clean out isp + +isp: $(PROJECT).hex + "$(BINPATH)avrdude" $(ISP_ARGS) -e -u -Ulock:w:0x3f:m -qq -Uefuse:w:0x$(ISP_EFUSE):m -Uhfuse:w:0x$(ISP_HFUSE):m -Ulfuse:w:0x$(ISP_LFUSE):m -Ulock:w:0x0f:m + "$(BINPATH)avrdude" $(ISP_ARGS) -V -q -s -Uflash:w:$(PROJECT).hex + "$(BINPATH)avrdude" $(ISP_ARGS) diff --git a/Bootloader/MyOtaBootloader.c b/Bootloader/MyOtaBootloader.c new file mode 100644 index 0000000..a601075 --- /dev/null +++ b/Bootloader/MyOtaBootloader.c @@ -0,0 +1,207 @@ +#include "MyOtaBootloader.h" + +int main(void) __attribute__ ((naked)) __attribute__ ((section (".init9"))); + +volatile char dummy; + +EMPTY_INTERRUPT(WDT_vect); + +static uint16_t calcCRCrom (const void* ptr, uint16_t len) { + uint16_t crc = ~0; + for (uint16_t i = 0; i < len; ++i) + crc = _crc16_update(crc, pgm_read_byte((uint16_t) ptr + i)); + return crc; +} + +static uint8_t validFirmware () { + return calcCRCrom(0, fc.blocks * FIRMWARE_BLOCK_SIZE) == fc.crc; +} + +static void reboot() { + wdt_enable(WDTO_15MS); + for (;;); +} + +static void startup() { + if (validFirmware()) { + wdt_disable(); + clock_prescale_set(orgClockDiv); + ((void(*)()) 0)(); + } else + reboot(); +} + +static void boot_program_page(uint32_t page, uint8_t *buf) { + uint8_t sreg = SREG; + cli(); + eeprom_busy_wait(); + boot_page_erase(page); + boot_spm_busy_wait(); + for (uint16_t i = 0; i < SPM_PAGESIZE; i += 2) { + uint16_t w = *buf++; + w += (*buf++) << 8; + boot_page_fill(page + i, w); + } + boot_page_write(page); + boot_spm_busy_wait(); + boot_rww_enable(); + SREG = sreg; +} + +static boolean sendWrite(MyMessage message) { + return write(nc.parentNodeId, message.array, HEADER_SIZE + mGetLength(message), (message.destination == BROADCAST_ADDRESS)); +} + +static uint8_t sendAndWait(uint8_t reqType, uint8_t resType) { + msg.type = reqType; + for (uint8_t i = 0; i < 10; i++) { + sendWrite(msg); + for (uint16_t j = 0; j < 20; j++) { + wdt_reset(); + for (uint16_t j = 0; j < 100; j++) { + wdt_reset(); + uint8_t pipe; + boolean avail = available(&pipe); + if (avail && pipe<=6) { + read(rmsg.array,pipe); + if(!(mGetVersion(rmsg) == PROTOCOL_VERSION)) + continue; + if (rmsg.destination == nc.nodeId) { + if (mGetCommand(rmsg) == C_INTERNAL) { + if (rmsg.type == I_PING_ACK) { + if (rmsg.data[0] < nc.distance - 1) { + nc.distance = rmsg.data[0] + 1; + nc.parentNodeId = rmsg.sender; + eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId); + eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance); + } + } + } + if ((mGetCommand(rmsg) == mGetCommand(msg)) && (rmsg.type == resType)) + return 1; + } + } + delaym(1); + } + } + } + return 0; +} + +int main () { + asm volatile ("clr __zero_reg__"); + // switch to 4 MHz + orgClockDiv = clock_prescale_get(); + clock_prescale_set(F_CPU_DIV); + MCUSR = 0; + // enable watchdog to avoid deadlock + wdt_enable(WDTO_8S); + +#ifdef LED_DEBUG + // enable LEDs for debugging and blink once as visual "bootloader started" sign + led_init(); + blink(LED_MBOTH, 250); +#endif +#ifdef UART_DEBUG + // enable UART for debugging and send start message + uart_init(); + uart_puts("Go\n"); +#endif + + wdt_reset(); + // initialize RF module + begin(); + wdt_reset(); + // Read settings from EEPROM + eeprom_read_block((void*)&nc, (void*)EEPROM_NODE_ID_ADDRESS, sizeof(struct NodeConfig)); + wdt_reset(); + + msg.sender = nc.nodeId; + msg.last = nc.nodeId; + address(nc.nodeId); + + msg.sensor = NODE_SENSOR_ID; + mSetLength(msg, 0); + mSetPayloadType(msg, P_STRING); + mSetAck(msg,false); + mSetVersion(msg, PROTOCOL_VERSION); + + nc.distance = 255; + mSetCommand(msg, C_INTERNAL); + msg.destination = BROADCAST_ADDRESS; + if (!sendAndWait(I_PING, I_PING_ACK)) +// starting existing firmware if no ping response (if firmware is valid) +// reboot(); + startup(); + + msg.destination = GATEWAY_ADDRESS; + + if (nc.nodeId == AUTO) { + openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId)); + if (!sendAndWait(I_ID_REQUEST, I_ID_RESPONSE)) + reboot(); + if (mGetPayloadType(rmsg) == P_BYTE) + nc.nodeId = rmsg.data[0]; + else if (mGetPayloadType(rmsg) == P_STRING) + nc.nodeId = atoi(rmsg.data); + if (nc.nodeId == AUTO) + reboot(); + eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, nc.nodeId); + msg.sender = nc.nodeId; + msg.last = nc.nodeId; + address(nc.nodeId); + } + + // Read settings from EEPROM + eeprom_read_block((void*)&fc, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS, sizeof(struct FirmwareConfig)); + + mSetPayloadType(msg,P_CUSTOM); + + FirmwareConfigRequest *firmwareConfigRequest = (FirmwareConfigRequest *)msg.data; + mSetLength(msg, sizeof(FirmwareConfigRequest)); + mSetCommand(msg, C_STREAM); + firmwareConfigRequest->type = fc.type; + firmwareConfigRequest->version = fc.version; + if (!sendAndWait(ST_FIRMWARE_CONFIG_REQUEST, ST_FIRMWARE_CONFIG_RESPONSE)) +// starting existing firmware if no firmware config response (if firmware is valid) +// reboot(); + startup(); + FirmwareConfigResponse *firmwareConfigResponse = (FirmwareConfigResponse *)rmsg.data; + if (firmwareConfigResponse->version == fc.version) + if (firmwareConfigResponse->blocks == fc.blocks) + if (firmwareConfigResponse->crc == fc.crc) + if (validFirmware()) + startup(); + fc.type = firmwareConfigResponse->type; + fc.version = firmwareConfigResponse->version; + fc.blocks = firmwareConfigResponse->blocks; + fc.crc = firmwareConfigResponse->crc; + + FirmwareRequest *firmwareRequest = (FirmwareRequest *)msg.data; + mSetLength(msg, sizeof(FirmwareRequest)); + firmwareRequest->type = fc.type; + firmwareRequest->version = fc.version; + for (uint16_t block = 0; block < fc.blocks; block++) { + firmwareRequest->block = block; + if (!sendAndWait(ST_FIRMWARE_REQUEST, ST_FIRMWARE_RESPONSE)) + reboot(); + FirmwareResponse *firmwareResponse = (FirmwareResponse *)rmsg.data; + uint8_t offset = (block * FIRMWARE_BLOCK_SIZE) % SPM_PAGESIZE; + memcpy(progBuf + offset, firmwareResponse->data, FIRMWARE_BLOCK_SIZE); + if (offset == SPM_PAGESIZE - FIRMWARE_BLOCK_SIZE) + boot_program_page((block * FIRMWARE_BLOCK_SIZE) - offset, progBuf); + } + + wdt_reset(); + + if (validFirmware()) { + eeprom_write_block((void*)&fc, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS, sizeof(struct FirmwareConfig)); +#ifdef UART_DEBUG + uart_puts("fw ok\n"); + } else { + uart_puts("fw nok\n"); +#endif + } + + reboot(); +} diff --git a/Bootloader/MyOtaBootloader.h b/Bootloader/MyOtaBootloader.h new file mode 100644 index 0000000..d906370 --- /dev/null +++ b/Bootloader/MyOtaBootloader.h @@ -0,0 +1,67 @@ +#ifndef MyOtaBootloader_H +#define MyOtaBootloader_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "MyMessage.h" +#include "MySensor.h" +#include "MyOtaBootloaderRF24.h" + +#define FIRMWARE_BLOCK_SIZE 16 + +struct FirmwareConfig +{ + uint16_t type; + uint16_t version; + uint16_t blocks; + uint16_t crc; +}; + +typedef struct +{ + uint16_t type; + uint16_t version; +} FirmwareConfigRequest; + +typedef struct +{ + uint16_t type; + uint16_t version; + uint16_t blocks; + uint16_t crc; +} FirmwareConfigResponse; + +typedef struct +{ + uint16_t type; + uint16_t version; + uint16_t block; +} FirmwareRequest; + +typedef struct +{ + uint16_t type; + uint16_t version; + uint16_t block; + uint8_t data[FIRMWARE_BLOCK_SIZE]; +} FirmwareResponse; + +static struct NodeConfig nc; +static struct FirmwareConfig fc; +static MyMessage msg; +static MyMessage rmsg; + +static clock_div_t orgClockDiv = 0; + +static uint8_t progBuf[SPM_PAGESIZE]; + +#endif // MyOtaBootloader_H diff --git a/Bootloader/MyOtaBootloaderHW.h b/Bootloader/MyOtaBootloaderHW.h new file mode 100644 index 0000000..2eec57b --- /dev/null +++ b/Bootloader/MyOtaBootloaderHW.h @@ -0,0 +1,154 @@ +#ifndef MyOtaBootloaderHW_H +#define MyOtaBootloaderHW_H + +#include +#include + +//#define LED_DEBUG +//#define UART_DEBUG + +// hardware +// ******** + +#define F_CPU_DIV clock_div_4 +#define F_CPU_REAL F_CPU / (1 << F_CPU_DIV) +#define UART_BAUD 9600UL +#define DELAY_M 125 * (1 << F_CPU_DIV) + +// boolean definition +// ****************** + +typedef uint8_t bool; +typedef uint8_t boolean; +#define false 0x0 +#define true 0x1 +#define LOW 0x0 +#define HIGH 0x1 + +// delay +// ***** + +static void delayu() { + asm("nop"); +} + +static void delaym(uint16_t t) { + uint16_t d, a; + for (d = 0; d < t; d++) + for (a = 0; a < DELAY_M; a++) + asm("nop"); +} + +// LED debug +// ********* + +#ifdef LED_DEBUG +#define LED_DDR DDRD +#define LED_PORT PORTD +#define LED_RED 6 // Arduino Pin 6 <-> Bit 6 of port D +#define LED_GREEN 7 // Arduino Pin 7 <-> Bit 7 of port D +#define LED_MRED (1 << LED_RED) +#define LED_MGREEN (1 << LED_GREEN) +#define LED_MBOTH (LED_MRED | LED_MGREEN) + +static void led_init() { + LED_DDR |= LED_MBOTH; + LED_PORT &= ~LED_MBOTH; +} + +static void blink(uint8_t mask, uint16_t time) { + LED_PORT |= mask; + if (time > 0) + { + delaym(time); + LED_PORT &= ~mask; + delaym(time); + } +} +#endif + +// UART debug +// ********** + +#ifdef UART_DEBUG +static void uart_init() +{ + UCSR0A = _BV(U2X0); //Double speed mode USART0 + UCSR0B = _BV(RXEN0) | _BV(TXEN0); + UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); + UBRR0L = (uint8_t)( (F_CPU_REAL + UART_BAUD * 4L) / (UART_BAUD * 8L) - 1 ); +} + +static void uart_putc(char ch) { + while (!(UCSR0A & _BV(UDRE0))); + UDR0 = ch; +} + +static void uart_puts(char *s) +{ + while (*s) + uart_putc(*s++); +} + +static void uart_puti(uint8_t i) +{ + char s[5]; + itoa( i, s, 10 ); + uart_puts( s ); +} +#endif + +// SPI communication +// ***************** + +#define SPI_DDR DDRB +#define SPI_PORT PORTB +#define SPI_PIN PINB +#define SPI_SCLK 5 // Arduino Pin 13 <-> Bit 5 of port B +#define SPI_MISO 4 // Arduino Pin 12 <-> Bit 4 of port B +#define SPI_MOSI 3 // Arduino Pin 11 <-> Bit 3 of port B +#define SPI_CSN 2 // Arduino Pin 10 <-> Bit 2 of port B +#define SPI_CE 1 // Arduino Pin 9 <-> Bit 1 of port B + +#define csnlow() SPI_PORT &= ~(1<> SPI_MISO) & 0x01); // capture current MISO bit + delayu(); + SPI_PORT &= ~(1 << SPI_SCLK); + delayu(); + } + return value; +} + +static uint8_t spiTrans(uint8_t cmd){ + uint8_t status; + csnlow(); + status = SPItransfer( cmd ); + csnhigh(); + return status; +} + +#endif // MyOtaBootloaderHW_H diff --git a/Bootloader/MyOtaBootloaderRF24.h b/Bootloader/MyOtaBootloaderRF24.h new file mode 100644 index 0000000..fa2495c --- /dev/null +++ b/Bootloader/MyOtaBootloaderRF24.h @@ -0,0 +1,253 @@ +#ifndef MyOtaBootloaderRF24_H +#define MyOtaBootloaderRF24_H + +#include "MyOtaBootloaderHW.h" +#include "../libraries/MySensors/utility/nRF24L01.h" + +#include + +// hardware-agnostic interface to transceiver +// ****************************************** +// static void begin() +// static void address(uint8_t addr) +// static boolean write(uint8_t next, uint8_t* packet, uint8_t length, boolean multicast) +// static bool available(uint8_t* pipe_num) +// static void read(uint8_t* buf, uint8_t pipe) + +typedef enum { RF24_PA_MIN = 0,RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR } rf24_pa_dbm_e ; +typedef enum { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS } rf24_datarate_e; + +uint64_t pipe0_reading_address; /**< Last address set on pipe 0 for reading. */ + +static uint8_t read_register(uint8_t reg) +{ + csnlow(); + SPItransfer( R_REGISTER | ( REGISTER_MASK & reg ) ); + uint8_t result = SPItransfer(0xff); + csnhigh(); + return result; +} + +static uint8_t write_registers(uint8_t reg, const uint8_t* buf, uint8_t len) +{ + uint8_t status; + csnlow(); + status = SPItransfer( W_REGISTER | ( REGISTER_MASK & reg ) ); + while ( len-- ) + SPItransfer(*buf++); + csnhigh(); + return status; +} + +static uint8_t write_register(uint8_t reg, uint8_t value) +{ + uint8_t status; + csnlow(); + status = SPItransfer( W_REGISTER | ( REGISTER_MASK & reg ) ); + SPItransfer(value); + csnhigh(); + return status; +} + +static uint8_t read_payload(uint8_t* buf, uint8_t data_len) +{ +#ifdef UART_DEBUG + uart_puts("-> "); +#endif + uint8_t status; + uint8_t* current = buf; + csnlow(); + status = SPItransfer( R_RX_PAYLOAD ); + while ( data_len-- ) { + *current = SPItransfer(0xFF); +#ifdef UART_DEBUG + uart_puti(*current); + uart_putc(','); +#endif + current++; + } + csnhigh(); +#ifdef UART_DEBUG + uart_putc('\n'); +#endif + return status; +} + +#define get_status() spiTrans(NOP) + +static void powerUp(void) +{ + if (!(read_register(CONFIG) & _BV(PWR_UP))){ + write_register(CONFIG,read_register(CONFIG) | _BV(PWR_UP)); + delaym(5); + } +} + +#define convert_64_bit_to_byte_array(value, data) ((*(uint64_t *)(data)) = (uint64_t)(value)) + +static void startListening(void) +{ + powerUp(); + write_register(CONFIG, read_register(CONFIG) | _BV(PRIM_RX)); + write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); + if (pipe0_reading_address){ + uint8_t addressa[8]; + convert_64_bit_to_byte_array(pipe0_reading_address, addressa); + write_registers(RX_ADDR_P0, addressa, 5); + } + spiTrans(FLUSH_RX); + spiTrans(FLUSH_TX); + cehigh(); +} + +static void stopListening(void) +{ + celow(); + spiTrans(FLUSH_TX); + spiTrans(FLUSH_RX); + write_register(CONFIG, read_register(CONFIG) & ~_BV(PRIM_RX)); +} + +static void write_payload(const uint8_t* buf, uint8_t data_len, const uint8_t writeType) +{ +#ifdef UART_DEBUG + uart_puts("<- "); +#endif + const uint8_t* current = buf; + csnlow(); + SPItransfer(writeType); + while ( data_len-- ) { +#ifdef UART_DEBUG + uart_puti(*current); + uart_putc(','); +#endif + SPItransfer(*current++); + } + csnhigh(); +#ifdef UART_DEBUG + uart_putc('\n'); +#endif +} + +static bool writem( const uint8_t* buf, uint8_t len, const bool multicast ) +{ + write_payload( buf, len, multicast ? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD) ; + cehigh(); + celow(); + while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) { } + uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); + if( status & _BV(MAX_RT)){ + spiTrans(FLUSH_TX); + return 0; + } + return 1; +} + +static uint8_t getDynamicPayloadSize(void) +{ + uint8_t result = 0; + csnlow(); + SPItransfer( R_RX_PL_WID ); + result = SPItransfer(0xff); + csnhigh(); + if(result > 32) { + spiTrans(FLUSH_RX); + return 0; + } + return result; +} + +static bool available(uint8_t* pipe_num) +{ + if (!(read_register(FIFO_STATUS) & _BV(RX_EMPTY) )){ + if (pipe_num) { + uint8_t status = get_status(); + *pipe_num = ( status >> RX_P_NO ) & 0b111; + } + return 1; + } + return 0; +} + +static void writeAckPayload(uint8_t pipe, const uint8_t* buf, uint8_t len) +{ + const uint8_t* current = buf; + uint8_t data_len = len; + csnlow(); + SPItransfer(W_ACK_PAYLOAD | ( pipe & 0b111 ) ); + while ( data_len-- ) + SPItransfer(*current++); + csnhigh(); +} + +static void read( uint8_t* buf, uint8_t pipe ){ + read_payload(buf, getDynamicPayloadSize()); + write_register(STATUS,_BV(RX_DR) | _BV(MAX_RT) | _BV(TX_DS)); + writeAckPayload(pipe,&pipe, 1 ); +} + +static void openWritingPipe(uint64_t value) +{ + uint8_t valuea[8]; + convert_64_bit_to_byte_array(value, valuea); + write_registers(RX_ADDR_P0, valuea, 5); + write_registers(TX_ADDR, valuea, 5); +} + +static void openReadingPipe(uint8_t child, uint64_t address) +{ + if (child == 0) + pipe0_reading_address = address; + uint8_t addressa[8]; + convert_64_bit_to_byte_array(address, addressa); + if ( child < 2 ) + write_registers(RX_ADDR_P0 + child, addressa, 5); + write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(ERX_P0 + child)); +} + +static boolean write(uint8_t next, uint8_t* packet, uint8_t length, boolean multicast) { + powerUp(); + stopListening(); + openWritingPipe(TO_ADDR(next)); + bool ok = writem(packet, length, multicast); + startListening(); + return ok; +} + +static void address(uint8_t addr) +{ + if (addr != BROADCAST_ADDRESS) { + openReadingPipe(WRITE_PIPE, TO_ADDR(addr)); + openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(addr)); + } +} + +static void begin(void) +{ + pipe0_reading_address = 0; + + SPIinit(); + delaym( 10 ) ; + + write_register(SETUP_RETR, 5 << ARD | 15 << ARC); + write_register(EN_AA, 0b00111111 & ~_BV(BROADCAST_PIPE)) ; + write_register(RF_CH, RF24_CHANNEL); + write_register(RF_SETUP, (read_register(RF_SETUP) & 0b11010000) | ((RF24_PA_LEVEL << 1) + 1) | ((RF24_DATARATE & 0b00000010 ) << 4) | ((RF24_DATARATE & 0b00000001 ) << 3)); + write_register(CONFIG, read_register(CONFIG) | _BV(CRCO) | _BV(EN_CRC)) ; + write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); + + csnlow(); + SPItransfer(ACTIVATE); + SPItransfer(0x73); + csnhigh(); + write_register(FEATURE, read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) ); + write_register(DYNPD, read_register(DYNPD) | _BV(DPL_P5) | _BV(DPL_P4) | _BV(DPL_P3) | _BV(DPL_P2) | _BV(DPL_P1) | _BV(DPL_P0)); + + spiTrans(FLUSH_RX); + spiTrans(FLUSH_TX); + + powerUp(); //Power up by default when begin() is called + write_register(CONFIG, read_register(CONFIG) & ~_BV(PRIM_RX)); + openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS)); +} +#endif // MyOtaBootloaderRF24_H diff --git a/EthernetGateway/EthernetGateway.ino b/EthernetGateway/EthernetGateway.ino index 1144227..ddafef1 100644 --- a/EthernetGateway/EthernetGateway.ino +++ b/EthernetGateway/EthernetGateway.ino @@ -48,7 +48,6 @@ #include -#include #include #include #include diff --git a/NodeJsController/BlinkGreen.hex b/NodeJsController/BlinkGreen.hex new file mode 100644 index 0000000..00c3de6 --- /dev/null +++ b/NodeJsController/BlinkGreen.hex @@ -0,0 +1,71 @@ +:100000000C9461000C947E000C947E000C947E0095 +:100010000C947E000C947E000C947E000C947E0068 +:100020000C947E000C947E000C947E000C947E0058 +:100030000C947E000C947E000C947E000C947E0048 +:100040000C949A000C947E000C947E000C947E001C +:100050000C947E000C947E000C947E000C947E0028 +:100060000C947E000C947E00000000002400270009 +:100070002A0000000000250028002B0000000000DE +:1000800023002600290004040404040404040202DA +:100090000202020203030303030301020408102007 +:1000A0004080010204081020010204081020000012 +:1000B0000007000201000003040600000000000029 +:1000C000000011241FBECFEFD8E0DEBFCDBF11E08E +:1000D000A0E0B1E0E4E5F4E002C005900D92A030AC +:1000E000B107D9F711E0A0E0B1E001C01D92A9303D +:1000F000B107E1F70E9418020C9428020C9400004A +:1001000087E061E00E94C4016AEF70E080E090E067 +:100110000E941D0187E060E00E94C4016AEF70E068 +:1001200080E090E00E941D01089587E061E00E9458 +:10013000850108951F920F920FB60F9211242F93ED +:100140003F938F939F93AF93BF93809104019091BE +:100150000501A0910601B0910701309108010196B7 +:10016000A11DB11D232F2D5F2D3720F02D57019696 +:10017000A11DB11D209308018093040190930501F6 +:10018000A0930601B09307018091000190910101B5 +:10019000A0910201B09103010196A11DB11D8093B0 +:1001A000000190930101A0930201B0930301BF915C +:1001B000AF919F918F913F912F910F900FBE0F9014 +:1001C0001F901895789484B5826084BD84B5816051 +:1001D00084BD85B5826085BD85B5816085BDEEE64F +:1001E000F0E0808181608083E1E8F0E0108280812E +:1001F00082608083808181608083E0E8F0E080819C +:1002000081608083E1EBF0E0808184608083E0EBBB +:10021000F0E0808181608083EAE7F0E080818460A3 +:1002200080838081826080838081816080838081FF +:10023000806880831092C1000895EF92FF920F931F +:100240001F93CF93DF937B018C013FB7F89480918C +:10025000000190910101A0910201B091030126B526 +:10026000A89B05C02F3F19F00196A11DB11D3FBFEE +:10027000BA2FA92F982F8827820F911DA11DB11D7C +:1002800052E0880F991FAA1FBB1F5A95D1F7EC01A6 +:1002900030C00E9427023FB7F894809100019091EE +:1002A0000101A0910201B091030126B5A89B05C0F0 +:1002B0002F3F19F00196A11DB11D3FBFBA2FA92FE5 +:1002C000982F8827820F911DA11DB11D32E0880F44 +:1002D000991FAA1FBB1F3A95D1F78C1B9D0B885EF7 +:1002E0009340B8F20894E108F10801091109C851D6 +:1002F000DC4FE114F1040105110559F6DF91CF91AE +:100300001F910F91FF90EF900895CF93DF93482FA7 +:1003100050E0CA0186569F4FFC0134914A575F4F07 +:10032000FA018491882369F190E0880F991FFC01FC +:10033000E859FF4FA591B491FC01EE58FF4FC591CC +:10034000D491662351F42FB7F8948C91932F909504 +:1003500089238C93888189230BC0623061F42FB785 +:10036000F8948C91932F909589238C938881832B7B +:1003700088832FBF06C09FB7F8948C91832B8C93F2 +:100380009FBFDF91CF910895482F50E0CA01825559 +:100390009F4FFC012491CA0186569F4FFC01949106 +:1003A0004A575F4FFA013491332309F440C02223A6 +:1003B00051F1233071F0243028F42130A1F02230A3 +:1003C00011F514C02630B1F02730C1F02430D9F433 +:1003D00004C0809180008F7703C0809180008F7D62 +:1003E0008093800010C084B58F7702C084B58F7D64 +:1003F00084BD09C08091B0008F7703C08091B000A8 +:100400008F7D8093B000E32FF0E0EE0FFF1FEE58DA +:10041000FF4FA591B4912FB7F894662321F48C91E6 +:100420009095892302C08C91892B8C932FBF0895BE +:10043000CF93DF930E94E2000E949500C0E0D0E0DD +:100440000E9480002097E1F30E940000F9CF0895F8 +:04045000F894FFCF4E +:00000001FF diff --git a/NodeJsController/BlinkRed.hex b/NodeJsController/BlinkRed.hex new file mode 100644 index 0000000..3f2c259 --- /dev/null +++ b/NodeJsController/BlinkRed.hex @@ -0,0 +1,71 @@ +:100000000C9461000C947E000C947E000C947E0095 +:100010000C947E000C947E000C947E000C947E0068 +:100020000C947E000C947E000C947E000C947E0058 +:100030000C947E000C947E000C947E000C947E0048 +:100040000C949A000C947E000C947E000C947E001C +:100050000C947E000C947E000C947E000C947E0028 +:100060000C947E000C947E00000000002400270009 +:100070002A0000000000250028002B0000000000DE +:1000800023002600290004040404040404040202DA +:100090000202020203030303030301020408102007 +:1000A0004080010204081020010204081020000012 +:1000B0000007000201000003040600000000000029 +:1000C000000011241FBECFEFD8E0DEBFCDBF11E08E +:1000D000A0E0B1E0E4E5F4E002C005900D92A030AC +:1000E000B107D9F711E0A0E0B1E001C01D92A9303D +:1000F000B107E1F70E9418020C9428020C9400004A +:1001000086E061E00E94C4016AEF70E080E090E068 +:100110000E941D0186E060E00E94C4016AEF70E069 +:1001200080E090E00E941D01089586E061E00E9459 +:10013000850108951F920F920FB60F9211242F93ED +:100140003F938F939F93AF93BF93809104019091BE +:100150000501A0910601B0910701309108010196B7 +:10016000A11DB11D232F2D5F2D3720F02D57019696 +:10017000A11DB11D209308018093040190930501F6 +:10018000A0930601B09307018091000190910101B5 +:10019000A0910201B09103010196A11DB11D8093B0 +:1001A000000190930101A0930201B0930301BF915C +:1001B000AF919F918F913F912F910F900FBE0F9014 +:1001C0001F901895789484B5826084BD84B5816051 +:1001D00084BD85B5826085BD85B5816085BDEEE64F +:1001E000F0E0808181608083E1E8F0E0108280812E +:1001F00082608083808181608083E0E8F0E080819C +:1002000081608083E1EBF0E0808184608083E0EBBB +:10021000F0E0808181608083EAE7F0E080818460A3 +:1002200080838081826080838081816080838081FF +:10023000806880831092C1000895EF92FF920F931F +:100240001F93CF93DF937B018C013FB7F89480918C +:10025000000190910101A0910201B091030126B526 +:10026000A89B05C02F3F19F00196A11DB11D3FBFEE +:10027000BA2FA92F982F8827820F911DA11DB11D7C +:1002800052E0880F991FAA1FBB1F5A95D1F7EC01A6 +:1002900030C00E9427023FB7F894809100019091EE +:1002A0000101A0910201B091030126B5A89B05C0F0 +:1002B0002F3F19F00196A11DB11D3FBFBA2FA92FE5 +:1002C000982F8827820F911DA11DB11D32E0880F44 +:1002D000991FAA1FBB1F3A95D1F78C1B9D0B885EF7 +:1002E0009340B8F20894E108F10801091109C851D6 +:1002F000DC4FE114F1040105110559F6DF91CF91AE +:100300001F910F91FF90EF900895CF93DF93482FA7 +:1003100050E0CA0186569F4FFC0134914A575F4F07 +:10032000FA018491882369F190E0880F991FFC01FC +:10033000E859FF4FA591B491FC01EE58FF4FC591CC +:10034000D491662351F42FB7F8948C91932F909504 +:1003500089238C93888189230BC0623061F42FB785 +:10036000F8948C91932F909589238C938881832B7B +:1003700088832FBF06C09FB7F8948C91832B8C93F2 +:100380009FBFDF91CF910895482F50E0CA01825559 +:100390009F4FFC012491CA0186569F4FFC01949106 +:1003A0004A575F4FFA013491332309F440C02223A6 +:1003B00051F1233071F0243028F42130A1F02230A3 +:1003C00011F514C02630B1F02730C1F02430D9F433 +:1003D00004C0809180008F7703C0809180008F7D62 +:1003E0008093800010C084B58F7702C084B58F7D64 +:1003F00084BD09C08091B0008F7703C08091B000A8 +:100400008F7D8093B000E32FF0E0EE0FFF1FEE58DA +:10041000FF4FA591B4912FB7F894662321F48C91E6 +:100420009095892302C08C91892B8C932FBF0895BE +:10043000CF93DF930E94E2000E949500C0E0D0E0DD +:100440000E9480002097E1F30E940000F9CF0895F8 +:04045000F894FFCF4E +:00000001FF diff --git a/NodeJsController/DallasTemperatureSensor.cpp.hex b/NodeJsController/DallasTemperatureSensor.cpp.hex new file mode 100644 index 0000000..a714a35 --- /dev/null +++ b/NodeJsController/DallasTemperatureSensor.cpp.hex @@ -0,0 +1,1222 @@ +:100000000C94AE020C94311F0C945E1F0C94D6021B +:100010000C94D6020C94D6020C9455140C94D6026F +:100020000C94D6020C94D6020C94D6020C94D602F0 +:100030000C94D6020C94D6020C94D6020C94D602E0 +:100040000C948B1F0C94D6020C9461220C94E42225 +:100050000C94D6020C94D6020C94D6020C94D602C0 +:100060000C94D6020C94D602303B303B25643B25E1 +:10007000643B0072643D636C6561720A0069643DB3 +:1000800025640A0066756C6C0A006E6577207061E5 +:1000900072656E743D25642C20643D25640A0076EB +:1000A000657273696F6E206D69736D61746368004A +:1000B000726561643A2025642D25642D25642073C2 +:1000C0003D25642C633D25642C743D25642C70749F +:1000D0003D25642C6C3D25643A25730A0073656EDA +:1000E000643A2025642D25642D25642D2564207314 +:1000F0003D25642C633D25642C743D25642C70746F +:100100003D25642C6C3D25642C73743D25733A2584 +:10011000730A00726571206E6F64652069640A005D +:10012000636865636B2077697265730A00257320C5 +:10013000737461727465642C2069642025640A00FC +:100140000001020304050A0B0C0D0E0F111213140B +:100150001516A702AD02B302BB02C402CE02D7023B +:10016000DE02E602ED02F402FC02504120506F77FD +:10017000657209203D2025530D0A00435243204C4F +:10018000656E67746809203D2025530D0A004D6F88 +:1001900064656C0909203D2025530D0A00446174F3 +:1001A00061205261746509203D2025530D0A0044E9 +:1001B000594E50442F4645415455524500434F4EE9 +:1001C0004649470052465F53455455500052465FDA +:1001D000434800454E5F52584144445200454E5FEB +:1001E00041410052585F50575F50302D36005458EF +:1001F0005F414444520052585F414444525F503280 +:100200002D350052585F414444525F50302D31002B +:100210000D0A00253032780020307800255309255A +:1002200063203D000D0A002030782530327800250B +:1002300053092563203D004F4253455256455F54B4 +:10024000583D253032783A20504F4C535F434E543E +:100250003D2578204152435F434E543D25780D0A99 +:10026000005354415455530909203D20307825301E +:1002700032782052585F44523D25782054585F44CC +:10028000533D2578204D41585F52543D25782052EA +:10029000585F505F4E4F3D25782054585F46554C6F +:1002A0004C3D25780D0A00314D42505300324D42ED +:1002B0005053003235304B425053006E5246323468 +:1002C0004C3031006E524632344C30312B00446990 +:1002D0007361626C65640038206269747300313642 +:1002E00020626974730050415F4D494E0050415F78 +:1002F0004C4F570050415F484947480050415F4DBF +:10030000415800005EBCE2613FDD83C29C7E20A3B9 +:10031000FD1F419DC3217FFCA2401E5F01E3BD3E46 +:100320006082DC237D9FC1421CFEA0E1BF5D038093 +:10033000DE3C62BEE0025CDF81633D7C22C09E1D2C +:1003400043A1FF4618FAA427799BC584DA3866E5ED +:10035000BB5907DB856739BAE406581947A5FB780E +:1003600026C49A653BD987045AB8E6A7F91B45C647 +:10037000987A24F8A6441A99C7257B3A6486D85BF4 +:1003800005E7B98CD2306EEDB3510F4E10F2AC2FA1 +:100390007193CD114FADF3702ECC92D38D6F31B2DE +:1003A000EC0E50AFF1134DCE90722C6D33D18F0CFB +:1003B00052B0EE326C8ED0530DEFB1F0AE4C1291C4 +:1003C000CF2D73CA947628ABF517490856B4EA695D +:1003D00037D58B5709EBB536688AD495CB2977F496 +:1003E000AA4816E9B7550B88D6346A2B7597C94ABF +:1003F00014F6A8742AC896154BA9F7B6E80A54D77C +:10040000896B3500000000240027002A000000004E +:1004100000250028002B00000000002300260029F2 +:10042000000404040404040404020202020202039D +:1004300003030303030102040810204080010204A7 +:10044000081020010204081020000000070002012B +:100450000000030406000000000000000000407AD5 +:1004600010F35A00A0724E18090010A5D4E800003D +:10047000E87648170000E40B54020000CA9A3B00DB +:100480000000E1F505000080969800000040420F52 +:10049000000000A08601000000102700000000E816 +:1004A00003000000006400000000000A00000000DB +:1004B000000100000000002C76D888DC674F08237C +:1004C000DFC1DFAE59E1B1B796E5E3E453C63AE6E2 +:1004D00051997696E8E6C28426EB898C9B62ED40C2 +:1004E0007C6FFCEFBC9C9F40F2BAA56FA5F4900511 +:1004F0005A2AF75C936B6CF9676DC11BFCE0E40D45 +:1005000047FEF520E6B500D0ED902E030094357738 +:10051000050080841E080000204E0A000000C80C60 +:10052000333333330F986E12831141EF8D211489C9 +:100530003BE65516CFFEE6DB18D1844B381BF77C23 +:100540001D901DA4BBE424203284725E228100C968 +:10055000F124ECA1E53D27003F09972211241FBE9D +:10056000CFEFD8E0DEBFCDBF11E0A0E0B1E0E4EE18 +:10057000FBE402C005900D92A036B107D9F713E055 +:10058000A0E6B1E001C01D92A930B107E1F715E086 +:10059000CCE5D5E004C02297FE010E94A125C83514 +:1005A000D107C9F70E940A230C94F0250C9400008F +:1005B000EF92FF920F931F93F22FF02E47FD02C090 +:1005C000E4E001C0E4E1242F332727FD309537FF15 +:1005D00003C0309521953F4F4F2D512F0F2FEE2EF9 +:1005E0000E9455068F2D912F1F910F91FF90EF9034 +:1005F0000895FC0188279927E89421912032E9F396 +:10060000293010F02E30C8F32B3241F02D3239F45E +:10061000689404C00E94DA03820F911D2191205337 +:100620002A30C0F31EF4909581959F4F08951F9333 +:10063000FC0199278827BC01E89411911032E9F355 +:10064000193010F01E30C8F31B3251F01D3249F43E +:10065000689406C00E94C503610F711D811D911D24 +:10066000119110531A30B0F33EF490958095709527 +:1006700061957F4F8F4F9F4F1F910895FB01DC01C4 +:1006800001900D920020E1F70895FB01DC0141503B +:10069000504048F001900D920020C9F701C01D9212 +:1006A00041505040E0F70895A0E0B0E0EAE5F3E003 +:1006B0000C94C3257C01EB018A01690109C0CE01BC +:1006C0002196F6010995F70181937F0101501040B1 +:1006D00001151105A1F7CDB7DEB7E8E00C94DF25D1 +:1006E000FB019F01E8944230C4F04532B4F44A3033 +:1006F00029F497FB1EF4909581959F4F642F7727DF +:100700000E94A525805D8A330CF0895D8193CB0121 +:100710000097A1F716F45DE251931082C9010C9481 +:10072000A508FA01CF93FF93EF93223044F12532CD +:1007300034F5C22FE894CA3049F497FB3EF4909503 +:100740008095709561957F4F8F4F9F4F2C2F33274A +:1007500044275527FF93EF930E947D25EF91FF914A +:10076000605D6A330CF0695D6193B901CA01605044 +:1007700070408040904051F716F4CDE2C193108252 +:100780008F919F91CF910C94A508592F482F372F07 +:10079000262F660F771F881F991F660F771F881FE8 +:1007A000991F620F731F841F951F660F771F881F85 +:1007B000991F08957AE0979F902D879F802D910D26 +:1007C00011240895FA01CF93FF93EF932230CCF0D8 +:1007D0002532BCF4C22F2C2F332744275527FF93F3 +:1007E000EF930E947D25EF91FF91605D6A330CF0DD +:1007F000695D6193B901CA016050704080409040CA +:1008000051F710828F919F91CF910C94A508FB0115 +:100810009F01423074F0453264F4642F77270E94C0 +:10082000A525805D8A330CF0895D8193CB0100970B +:10083000A1F71082C9010C94A508AEE0B0E0E3E294 +:10084000F4E00C94C7250D891E898F89988D97FF38 +:1008500002C080E090E801979E838D831A8309830C +:100860008EE08C839E01255E3F4FCE010196698DFF +:100870007A8DA9010E9478044D815E8157FD0AC0DE +:100880002F813885421753070CF49A01020F131F6A +:10089000F80110822E96E4E00C94E325AEE0B0E07F +:1008A000E4E5F4E00C94C7258C0177FF02C060E01A +:1008B00070E8615070407E836D831A8309838EE0F7 +:1008C0008C83CE010196BA01A9010E9478042D8182 +:1008D0003E8137FD09C0EF81F8852E173F070CF4E4 +:1008E000F901E00FF11F10822E96E4E00C94E3254D +:1008F000ABE0B0E0EEE7F4E00C94B9253C012B014D +:100900005A01FC0117821682838181FD03C06FEFBB +:100910007FEFC6C19AE0892E1E010894211C311C6C +:10092000F3012381F20123FD859123FF81912F01A2 +:10093000882309F4B2C1853239F423FD859123FF60 +:1009400081912F01853229F490E0B3010E94B5080E +:10095000E7CF982FFF24EE249924FFE1FF15D0F074 +:100960009B3269F09C3228F4903259F0933291F422 +:100970000EC09D3249F0903369F441E024C052E04A +:10098000F52A84E0F82A28C098E0F92A25C0E0E199 +:10099000FE2A22C0F7FC29C0892F80538A3070F4C8 +:1009A000F6FE05C0989C902C1124980E15C0E89C6A +:1009B000E02C1124E80EF0E2FF2A0EC09E3229F44A +:1009C000F6FC6BC140E4F42A07C09C3619F450E8E9 +:1009D000F52A02C0983649F4F20123FD959123FFD0 +:1009E00091912F01992309F0B8CF892F8554833035 +:1009F00018F08052833038F444E050E0A40EB51E65 +:100A00005FE359830FC0933631F0933779F0933514 +:100A100009F056C020C0F5018081898342E050E092 +:100A2000A40EB51E610101E010E012C0F501C08006 +:100A3000D180F6FC03C06FEF7FEF02C0692D70E03C +:100A400042E050E0A40EB51EC6010E949A088C0137 +:100A50005FE7F52214C0F501C080D180F6FC03C029 +:100A60006FEF7FEF02C0692D70E042E050E0A40E0E +:100A7000B51EC6010E948F088C0150E8F52AF3FECE +:100A800007C01AC080E290E0B3010E94B508EA9462 +:100A90008E2D90E008171907A8F30EC0F601F7FC99 +:100AA0008591F7FE81916F0190E0B3010E94B50836 +:100AB000E110EA94015010400115110579F7EAC0E0 +:100AC000943611F0993669F5F7FE08C0F5012081DA +:100AD00031814281538184E090E00AC0F501808138 +:100AE00091819C01442737FD4095542F82E090E08E +:100AF000A80EB91E9FE6F92257FF09C050954095F0 +:100B0000309521953F4F4F4F5F4FE0E8FE2ACA01D5 +:100B1000B901A1012AE030E00E94E108D82ED218E4 +:100B200040C0953729F41F2D1F7E2AE030E01DC0FC +:100B30001F2D197F9F3661F0903720F4983509F00A +:100B4000ACC00FC0903739F0983709F0A6C004C088 +:100B500028E030E00AC0106114FD146020E130E0AC +:100B600004C014FD166020E132E017FF08C0F50153 +:100B7000608171818281938144E050E008C0F50179 +:100B800080819181BC0180E090E042E050E0A40EC1 +:100B9000B51EA1010E94E108D82ED2188FE7F82EC9 +:100BA000F122F6FE0BC05EEFF522D91438F4F4FE04 +:100BB00007C0F2FC05C08FEEF82202C01D2D01C057 +:100BC000192DF4FE0DC0FE01ED0DF11D8081803365 +:100BD00019F499EEF92208C01F5FF2FE05C003C0A8 +:100BE0008F2D867809F01F5F0F2DF3FC14C0F0FEE7 +:100BF0000FC01E1510F09D2C0BC09D2C9E0C911A41 +:100C00001E2D06C080E290E0B3010E94B5081F5F70 +:100C10001E15C0F304C01E1510F4E11A01C0EE2425 +:100C200004FF0FC080E390E0B3010E94B50802FF0B +:100C30001DC001FD03C088E790E00EC088E590E08C +:100C40000BC0802F867891F001FF02C08BE201C0BB +:100C500080E2F7FC8DE290E0B3010E94B50806C087 +:100C600080E390E0B3010E94B5089A94D914C0F3D0 +:100C7000DA94F101ED0DF11D808190E0B3010E9445 +:100C8000B508DD20A9F706C080E290E0B3010E941C +:100C9000B508EA94EE20C1F743CEF301668177816F +:100CA000CB012B96E2E10C94D525A9E0B0E0EBE571 +:100CB000F6E00C94BD256A01122FA02EBE2C2BE36A +:100CC000201718F42CE3922E02C0902E9394AE01BC +:100CD0004F5F5F4F27E0092D0E94B707BC01898154 +:100CE000E82EFF24C70189709070019711F4ADE2DE +:100CF00009C0B1FE02C0ABE205C0B0FC02C0A0E07A +:100D000001C0A0E2E3FE3BC0AA2311F423E001C02E +:100D100024E0211710F020E002C0121B212FEB2C41 +:100D2000B4FE02C0322F0AC0F601322F80E202C0A8 +:100D3000819331503323E1F7C20ED11CAA2319F05D +:100D4000F601A1936F01F6013196E2FE05C09EE423 +:100D5000D6019C9381E404C09EE6D6019C9381E673 +:100D600011968C9391833296DF01832F90E202C01B +:100D70009D9381508823E1F7E30FF11D40C0E2FE0F +:100D800042C0AA2311F423E001C024E0211710F08F +:100D900020E002C0121B212FEB2CB4FE02C0922FC8 +:100DA0000AC0F601922F80E202C0819391509923EC +:100DB000E1F7C20ED11CAA2319F0F601A1936F012D +:100DC000F6013196E2FE08C089E4D6018C938EE4E8 +:100DD00011968C9386E407C089E6D6018C938EE643 +:100DE00011968C9386E681833296DF01892F20E26B +:100DF00002C02D9381508823E1F7E90FF11D108285 +:100E00002EEF3FEFAFC0161617061CF041E050E082 +:100E100003C0AB014F5F5F4FAA2019F480E090E060 +:100E200003C08A2D90E0019620E030E0AA2311F063 +:100E300021E030E0240F351F280F391F812F90E06B +:100E40002817390714F020E002C0121B212F4B2D68 +:100E500050E0CA0180719070B4FC0DC0B3FC0BC0AF +:100E6000F601322F40E202C0419331503323E1F7C3 +:100E7000C20ED11C01C0322FAA2319F0F601A19392 +:100E80006F01892B11F0132F0AC0F601132F80E395 +:100E900002C0819311501123E1F7C30ED11C092D1B +:100EA000060FBA8090E1892E912C8E209F20E4FEBF +:100EB00004C0F1E3BF1609F40150101614F001E06C +:100EC00003C0093008F008E09B0177FF02C020E072 +:100ED00030E0CB010196821B930BFE013196E80FA7 +:100EE000F91F8EE2F82E3B01601A71088A2D90E0FE +:100EF00044275527481B590B8FEF2F3F380719F40C +:100F0000D601FD926D01621773072CF0621673060D +:100F100014F4808101C080E32150304031962417C1 +:100F2000350724F0D6018D936D01E6CF26173707DC +:100F300049F4B5E3BB1528F0BB1621F481149104E4 +:100F400009F481E3F6018193D601812F90E202C07A +:100F50009C93815011968823D9F7E10FF11D1082DF +:100F600020E030E0C9012996EEE00C94D925283024 +:100F700008F027E03327DA01990F311D87FD9160D2 +:100F800000966105710539F432602E5F3D9330E3C0 +:100F90002A95E1F708959F3F30F08038710561058B +:100FA00009F03C5F3C5F3D93913008F08068911DF3 +:100FB000DF93CF931F930F93FF92EF92192F987F98 +:100FC0009695E92F96959695E90FFF27E954FB4FE3 +:100FD00099273327EE24FF24A701E7010590089401 +:100FE000079428F4360FE71EF81E491F511D660F9F +:100FF000771F881F991F0694A1F70590079428F47E +:10100000E70EF81E491F561FC11D770F881F991F35 +:10101000661F0694A1F70590079428F4F80E491F5F +:10102000561FC71FD11D880F991F661F771F069473 +:10103000A1F70590079420F4490F561FC71FD81F2A +:10104000990F661F771F881F0694A9F78491109542 +:10105000177041F0D695C79557954795F794E79443 +:101060001A95C1F7EDE5F4E0689415901591359166 +:101070006591959105907FE27395E118F10A430B14 +:10108000560BC90BD009C0F7E10CF11E431F561FC8 +:10109000C91FD01D7EF4703311F48A95E6CFE89411 +:1010A000015030F0080F0AF40027021708F4202F2F +:1010B0002395022F7A3328F079E37D932A95E9F777 +:1010C00010C07D932A9589F6069497956795379574 +:1010D00017951794E118F10A430B560BC90BD00969 +:1010E00098F023957E9173957A3308F070E37C93A2 +:1010F0002013B8F77E9170617D9330F0839571E392 +:101100007D9370E32A95E1F71124EF90FF900F9102 +:101110001F91CF91DF91992787FD90950895FC014C +:101120000590615070400110D8F7809590958E0F12 +:101130009F1F0895FC016150704001900110D8F785 +:10114000809590958E0F9F1F0895DC01FC01672FFD +:1011500071917723E1F7329704C07C916D9370838E +:101160006291AE17BF07C8F308950F931F93CF93F3 +:10117000DF938C01EB018B8181FF1BC082FF0DC0CF +:101180002E813F818C819D812817390764F4E88185 +:10119000F9810193F983E88306C0E885F985802FFA +:1011A0000995892B31F48E819F8101969F838E83CF +:1011B00002C00FEF1FEFC801DF91CF911F910F9178 +:1011C0000895FA01AA27283051F1203181F1E894DD +:1011D0006F936E7F6E5F7F4F8F4F9F4FAF4FB1E02A +:1011E0003ED0B4E03CD0670F781F891F9A1FA11D25 +:1011F000680F791F8A1F911DA11D6A0F711D811D26 +:10120000911DA11D20D009F468943F912AE0269FEA +:1012100011243019305D3193DEF6CF010895462F49 +:101220004770405D4193B3E00FD0C9F7F6CF462F2A +:101230004F70405D4A3318F0495D31FD4052419393 +:1012400002D0A9F7EACFB4E0A69597958795779550 +:101250006795BA95C9F700976105710508959B01D7 +:10126000AC010A2E06945795479537952795BA9560 +:10127000C9F7620F731F841F951FA01D08950F9358 +:101280001F9300E611E0C80163E00E94C61D8EE6D0 +:1012900091E0B8010E941D1980E891E069E04AE000 +:1012A0000E94F71389E392E060E040E00E94410A67 +:1012B0001F910F910895CF92DF92EF92FF920F93BB +:1012C0001F93CF93DF9380E891E00E94870D8EE615 +:1012D00091E00E94121A87EFC82E81E0D82EC0E05C +:1012E000D0E056C080E891E00E94290B882331F0BD +:1012F0008EE691E06C2F0E94351B05C08EE691E0D2 +:101300006C2F0E945C1B20E030E040E251E40E9420 +:101310001A250E943724882777FD8095982F0E94F0 +:101320006A2420E030E040E251E40E94CF237B01B8 +:101330008C01F6016081718182819381A8019701FE +:101340000E94CB238823F9F0C801B70120E030E0E8 +:101350004EEF52EC0E94CB238823A9F089E392E060 +:101360006C2F0E94460AB801A70121E00E94550A8D +:10137000BC0180E891E040E00E942F12F601E0827B +:10138000F18202831383219684E090E0C80ED91E77 +:101390008091370290913802C817D90724F4C031E0 +:1013A000D10509F09FCF609140017091410180917A +:1013B0004201909143010E94262080E891E00E9422 +:1013C000870D609144017091450180E891E00E9491 +:1013D0008E0CDF91CF911F910F91FF90EF90DF90D6 +:1013E000CF900895AF92BF92CF92EF92FF920F935A +:1013F000CF93DF938EE691E00E946B1B80E891E033 +:1014000060E070E04FEF20E00FEFE3E0EE2EF12C14 +:101410005CE4C52E32E0A32EB12C0E94C11280E8FC +:1014200091E060E071E043E151E020E00E94BF11F3 +:101430008EE691E00E942B198093370210923802B9 +:10144000C0E0D0E008C080E891E06C2F46E020E0EA +:101450000E940D1221968091370290913802C81790 +:10146000D9071CF4C031D10571F7DF91CF910F91ED +:10147000FF90EF90CF90BF90AF900895FC01148241 +:101480000895FC011482668345830895FC016683F8 +:101490000895FC01808187708860808381818F70CE +:1014A000806181836783CF010895CF92DF92EF92AD +:1014B000FF920F931F937C01F7E0CF2ED12CC80E23 +:1014C000D91ECB01BA0142E086010E94D802F60182 +:1014D00001900020E9F73197EC19FD09EE0FEE0FAE +:1014E000EE0FD7018C918770E82BEC9311968C91BD +:1014F00011978F7011968C93C7011F910F91FF90D8 +:10150000EF90DF90CF900895CF93DF93EC01DB0154 +:101510000D900020E9F71197A61B4A2F50E09A0181 +:10152000B3E0220F331FBA95E1F788818770822BD1 +:10153000888389818F708983A93110F049E150E057 +:10154000CE0107960E944503CE01DF91CF91089509 +:10155000FC01818182958F7090E0009731F00197B6 +:1015600011F080E0089587810895CF0107960E94C9 +:10157000F9020895FC01818182958F7090E00097B7 +:1015800061F0059729F020E030E040E050E00EC027 +:10159000278130854185528509C0CF0107960E9479 +:1015A0001703AC01CB01DA019C01AD01B901CA01FD +:1015B0000895CF93DF93FC01EB01818182958F70B9 +:1015C00031F43796CB01BF010E943E0336C061154E +:1015D000710599F18330B9F0843028F4813041F0FD +:1015E000823059F508C08430A9F0853031F51CC02F +:1015F000878190E002C087819085BE014AE050E07B +:101600000E9470031AC0878190854AE050E00E94D2 +:10161000070413C06781708581859285AE012AE039 +:1016200030E00E94910309C06781708581859285B1 +:10163000AE012AE030E00E94E203CE01DF91CF91BB +:1016400008959C01F999FECF32BD21BDF89A80B56D +:101650000895FC0181890895EF92FF920F931F93E3 +:10166000DF93CF93CDB7DEB7CC52D1400FB6F8940D +:10167000DEBF0FBECDBFC95CDE4FE880F980C75327 +:10168000D140CB5CDE4FA881B981C553D14054967F +:101690008C91882389F1EDB7FEB73A970FB6F8948D +:1016A000FEBF0FBEEDBF31968E010F5F1F4FADB76E +:1016B000BEB712961C930E9311978BE291E0938321 +:1016C000828388E690E09583848383E090E097832B +:1016D000868389E090E0918780870E941D04EDB7A2 +:1016E000FEB73A960FB6F894FEBF0FBEEDBF88E680 +:1016F00092E0B8010E946223FE01E75CFE4FCB5CE2 +:10170000DE4FA881B981C553D14054968C919E017A +:101710002F5F3F4F882359F0C9016CE370E0A701A8 +:101720009F010E944E048AE08CAF1DAE07C0C90124 +:101730006BE271E0A7019F010E944E0488E692E0EF +:10174000BE016F5F7F4F0E94622388E692E00E9495 +:10175000EF21C45DDE4F0FB6F894DEBF0FBECDBFE4 +:10176000CF91DF911F910F91FF90EF900895CF934C +:10177000DF93EB010CC08AE592E069E070E040E0A5 +:1017800050E020E030E00E940714C054DF41809117 +:10179000480190914901892B89F08FE1C034D80725 +:1017A00054F7B3C08AE592E068E070E040E050E0B2 +:1017B00020E030E00E940714C05ADF4080914801C9 +:1017C00090914901892B81F087E0C03DD80764F0F2 +:1017D0008AE592E067E070E040E050E020E030E031 +:1017E0000E940714C05DD740809148019091490143 +:1017F000892B81F083E0C83ED80764F08AE592E047 +:1018000066E070E040E050E020E030E00E94071425 +:10181000C85ED3408091480190914901892B81F0A5 +:1018200081E0C43FD80764F08AE592E065E070E0AB +:1018300040E050E020E030E00E940714C45FD14057 +:101840008091480190914901892B79F0CA3FD105D7 +:1018500064F08AE592E064E070E040E050E020E06F +:1018600030E00E940714CA5FD040809148019091F7 +:101870004901892B79F0CD37D10564F08AE592E0F2 +:1018800063E070E040E050E020E030E00E940714A8 +:10189000C857D0408091480190914901892B71F03F +:1018A000C034D1055CF08AE592E062E070E040E08F +:1018B00050E020E030E00E940714EC97809148014E +:1018C00090914901892B71F0C032D1055CF08AE515 +:1018D00092E061E070E040E050E020E030E00E9403 +:1018E00007146E978091480190914901892B99F0D6 +:1018F00060978CF08AE592E060E070E040E050E0B4 +:1019000020E030E00E94071406C08FE0C03AD807FC +:101910000CF454CF47CFDF91CF910895EF92FF920F +:101920000F931F938C017B0188E692E00E94EF21C8 +:10193000C8010E942C1881E090E0909349018093A7 +:101940004801C801B7010E94B70B1F910F91FF908A +:10195000EF9008955F926F927F928F929F92AF92D5 +:10196000BF92CF92DF92EF92FF920F931F93CF938C +:10197000DF937C01562EEA01822E8881982E969460 +:1019800096949694D7011E969C919B83887F826043 +:101990008883DE2CCF2CC7010E941118C7010E943A +:1019A000411830E040E050E060E070E080E090E01E +:1019B000052DF1E03D3F08F4F0E0E1E0423E08F49F +:1019C000E0E031EEA32EAF0EE060F1E0593A08F40A +:1019D000F0E028EAB22EBE0EE1E0B8EABB1608F04D +:1019E000E0E0FE2BA1E0693A08F4A0E0BF2FB85573 +:1019F000E1E0B83A08F0E0E0AE2BF1E0772309F43B +:101A0000F0E0E1E0882309F4E0E08D2D9C2D1CEF4F +:101A100095014B2F5A2F6F2F7E2F0E945216892D22 +:101A200090E04A9714F040E202C0492D495F8D2DA5 +:101A30009C2DBE01282D0E940516682E8D2D9C2DF3 +:101A40000E945C18BA80AB809C808E8019817D805A +:101A50000881662029F497E1C92E91E0D92E04C0AF +:101A60008CE1C82E81E0D82EB701695A7F4FCE0194 +:101A70000E94D90AEDB7FEB77A970FB6F894FEBF69 +:101A80000FBEEDBF3196ADB7BEB71296FC92EE9287 +:101A900011972DED30E033832283B4821582A68224 +:101AA0001782508611869286138684861586212F8A +:101AB00030E02770307037872687708A118A129538 +:101AC0001F70128B138A069506950695048B158A4E +:101AD000D78AC68A918F808F0E942C0BEDB7FEB7F4 +:101AE0007A960FB6F894FEBF0FBEEDBF862DDF913C +:101AF000CF911F910F91FF90EF90DF90CF90BF900B +:101B0000AF909F908F907F906F905F9008954F92CD +:101B10005F926F927F928F929F92AF92BF92CF927D +:101B2000DF92EF92FF920F931F93DF93CF930F9269 +:101B3000CDB7DEB74C01582E492C8E010F5F1F4FD9 +:101B4000B8010E94F217882309F4D5C28981873031 +:101B500008F0D1C2C4010E940215482F65E1662E2B +:101B6000712C680C791CC401B3010E94F815C401E2 +:101B70006981A80121E00E949414D40155960C912A +:101B800006950695069510E0F401E00FF11F148EFE +:101B9000F401E788D08CC18CB38CF688A28CB40198 +:101BA000695A7F4FC3010E94D90A2DB73EB726510B +:101BB00030400FB6F8943EBF0FBE2DBFEDB7FEB755 +:101BC0003196ADB7BEB712969C928E92119720EBCC +:101BD00030E033832283E4821582D6821782C08666 +:101BE0001186B28613862F2D30E02770307035872E +:101BF0002487A6861786F2945FE0F522F08A118A80 +:101C0000138B028B958B848B0E942C0BF40185899E +:101C100087702DB73EB72A5E3F4F0FB6F8943EBF90 +:101C20000FBE2DBF8230B1F000D000D0ADB7BEB72F +:101C300012969C928E9211978FE990E014969C9345 +:101C40008E9313970E942C0B80E00F900F900F90B3 +:101C50000F9052C2F4012689022F0770128DE78877 +:101C6000F08C318D9289992379F1033069F5173021 +:101C700059F50E94D31F7370807090700E942620C7 +:101C8000D4011E968C911E9757968C935797599610 +:101C9000EC9259978FEF5B968C935B9788E05A96FE +:101CA0008C935A9756968C915697807F8360569660 +:101CB0008C935697C30150966C910E94490AAC01CF +:101CC000C4016E2D21E0F5C1F4018685381709F0B5 +:101CD000DBC123FF21C0D401D696759681E2019025 +:101CE0000D928150E1F7D401D7968C91D797877FD9 +:101CF000D7968C93D7971E968C911E97D8968C93D7 +:101D0000D89757968C915797DA968C93B4016A5C62 +:101D10007F4FC4010E945011F4018289882319F178 +:101D20008785F81601F12E2D30E081E790E0880ECE +:101D3000991ED401ED91FC918FE89FEF880E991EBA +:101D4000E20FF31F80818F1571F0F082F999FECFB9 +:101D50001FBA2D5F3F4F32BD21BDF0BC0FB6F894C6 +:101D6000FA9AF99A0FBE033009F081C1183009F0D0 +:101D700053C0D40154968C91882309F04DC0C301FF +:101D80000E94A80A482F282F30E0F401808990E0B3 +:101D90000197281739070CF0AEC14F5F408B278998 +:101DA0002787F999FECF1FBA81E090E092BD81BDEF +:101DB00020BD0FB6F894FA9AF99A0FBED401509646 +:101DC0003C91F999FECF1FBA82E090E092BD81BDAF +:101DD00030BD0FB6F894FA9AF99A0FBEEDB7FEB778 +:101DE00038970FB6F894FEBF0FBEEDBF3196ADB772 +:101DF000BEB712969C928E9211978AE890E09383D8 +:101E0000828324831582368317820E942C0B80E004 +:101E1000EDB7FEB73896A3C0EE2009F028C1163002 +:101E200009F4A3C0173038F4113009F40FC114308D +:101E300009F061C112C01A3009F4B0C01D3009F0B8 +:101E40005AC128E088E190E00FB6F894A8958093F5 +:101E500060000FBE20936000FFCFD4011E968C91CE +:101E60008F3F09F048C1C3010E94A80AF401868788 +:101E70008F3FA9F400D000D0ADB7BEB712969C92A8 +:101E80008E92119784E890E014969C938E9313970A +:101E90000E942C0B0F900F900F900F90FFCF282FC8 +:101EA00030E040E050E060E070E080E090E0E22E62 +:101EB00001E03D3F08F400E011E0423E08F410E08C +:101EC0000F511060E1E0593A08F4E0E01855F1E0F4 +:101ED000183A08F0F0E0EF2BF1E0693A08F4F0E08E +:101EE000BE2FB855E1E0B83A08F0E0E0FE2BA1E0E3 +:101EF000772309F4A0E0E1E0882309F4E0E0852DF0 +:101F0000942D61E04CEFF42E2B2F3F2F4A2F5E2FA4 +:101F10000E947317F4012685F999FECF1FBA12BCEF +:101F200011BC20BD0FB6F894FA9AF99A0FBE00D0F2 +:101F300000D000D0EDB7FEB73196ADB7BEB7129660 +:101F40009C928E9211978DE790E0938382832483F5 +:101F500015820E942C0B80E0EDB7FEB736960FB6C7 +:101F6000F894FEBF0FBEEDBFC7C0C3010E94A80A10 +:101F700020E08D3409F421E0D40151968C915197E1 +:101F8000821709F4B8C051962C93F999FECF1FBA65 +:101F900083E091E092BD81BD20BDA8C0F40182899B +:101FA000882309F4A8C0C3010E94A80A833409F059 +:101FB000A2C000D000D0ADB7BEB712969C928E9250 +:101FC000119783E790E014969C938E9313970E9449 +:101FD0002C0B20E030E00F900F900F900F90D40169 +:101FE000AF58BF4F9FEFED91FC911197E20FF31F98 +:101FF00080818F3F81F09083F999FECF1FBA2D5FCA +:102000003F4F32BD21BD2350304090BD0FB6F894F4 +:10201000FA9AF99A0FBE2F5F3F4F2230310519F718 +:10202000F4018685878B118E8FEF838F8AE0828FF4 +:102030008689807F8360868BC3016FE171E00E9497 +:10204000840ABC01C4010E94501155C023E730E04E +:10205000820E931ED4010D911C910115110509F4F6 +:102060004AC0C3010E94BA0AF801099544C0E5E7D5 +:10207000F0E08E0E9F1ED401ED91FC91309711F08F +:10208000C301099581E038C09923A9F18981813084 +:1020900091F584010F581F4FD801ED91FC91E30F8A +:1020A000F11D6081862F81508E3F30F4C401A30161 +:1020B00020E00E94AA0C1FC0C401F4016785A3019F +:1020C00020E00E94AA0C6E2D70E0D801ED91FC91E9 +:1020D000E60FF71F80818F1571F0F082F999FECF1E +:1020E0001FBA6D5F7F4F72BD61BDF0BC0FB6F89433 +:1020F000FA9AF99A0FBE80E00F90CF91DF911F916D +:102100000F91FF90EF90DF90CF90BF90AF909F9096 +:102110008F907F906F905F904F900895EF92FF9215 +:102120000F931F93CF93DF93EC010E94D31F7B018A +:102130008C0103C0CE010E94870D0E94D31F6E192F +:102140007F09800B910B605D77408040904090F359 +:10215000DF91CF911F910F91FF90EF900895EF9233 +:10216000FF920F931F938C0100591F4FF8011082AB +:10217000005710409FEFF801908B8685878B918FD9 +:10218000938F87E0828F8689807F8360868B75E15D +:10219000E72EF12CE00EF11EC7016FE171E00E9405 +:1021A000840AC8016FEFA70121E00E94AA0CC801B0 +:1021B0000E948E101F910F91FF90EF900895EF9263 +:1021C000FF920F931F93CF93DF93EC0100D000D0C9 +:1021D000EDB7FEB79283818383E191E0948383839B +:1021E0000E942C0B0F900F900F900F908E85282F30 +:1021F00030E040E050E060E070E080E090E0E22E0F +:1022000001E03D3F08F400E011E0423E08F410E038 +:102210000F511060E1E0593A08F4E0E01855F1E0A0 +:10222000183A08F0F0E0EF2BF1E0693A08F4F0E03A +:10223000BE2FB855E1E0B83A08F0E0E0FE2BA1E08F +:10224000772309F4A0E0E1E0882309F4E0E0CE017F +:1022500061E02CEFF22E2B2F3F2F4A2F5E2F0E9492 +:1022600073178E858F8B198E8FEF8B8F83E08A8FFC +:102270008E89807F83608E8BCE0145966FE171E001 +:102280000E94840ABC01CE010E945011CE010E941E +:102290008E10DF91CF911F910F91FF90EF900895D5 +:1022A0001F93CF93DF93EC01DB0120E011968C911B +:1022B00011978770833009F421E08E858F3F59F4A0 +:1022C000222329F015968C911597833021F0CE01A9 +:1022D0000E94DF102CC08A89882331F114969C91CA +:1022E0001497CF58DF4FE881F981C157D040E90FEB +:1022F000F11D6081862F81508E3F30F4992321F0AB +:10230000CE01AD0120E00DC0222371F015968C9115 +:102310001597843049F49F3F39F4CE016FEFAD013A +:1023200021E00E94AA0C27C08C89882311F080E04C +:1023300022C0CE016F85AD0120E00E94AA0C182FAB +:10234000882329F011E0C059DF4F188213C08B8910 +:10235000882351F0C059DF4F8881C057D040863064 +:1023600018F0CE010E94AF10FE01E059FF4F8081AE +:102370008F5F8083812FDF91CF911F910895FF920E +:102380000F931F93CF93DF93EC018A01F22E611517 +:102390007105E1F08E858F8B198E8FEF8B8F8BE01F +:1023A0008A8F30E02170307053E0220F331F5A952E +:1023B000E1F78E89807F8360822B8E8BCE014596DC +:1023C0000E94840ABC01CE010E9450110115110522 +:1023D000F1F08E858F8B198E8FEF8B8F8CE08A8F2B +:1023E0002F2D30E02170307043E0220F331F4A95CB +:1023F000E1F78E89807F8360822B8E8BCE0145969C +:10240000B8010E94840ABC01CE010E945011DF91E4 +:10241000CF911F910F91FF9008950F931F938C01FF +:10242000FC018685878B118E638F428F30E021708F +:10243000307063E0220F331F6A95E1F78689807F51 +:10244000822B868BC801459660E271E00E94840A67 +:10245000BC01C8010E9450111F910F910895DC0129 +:10246000FB011E968C911E97828350E04170507044 +:1024700083E0440F551F8A95E1F78181807F816059 +:10248000842B8183CD010E945011811181E0089538 +:102490000F931F938C0180E091E00E9419230F5845 +:1024A0001F4FF8018083918363E070E040E051E0CA +:1024B00021E23BE00E9454031F910F910895EF9297 +:1024C000FF920F931F93CF93DF93EC01E62EF42E30 +:1024D0008901C059DF4F1882C057D040CE010E94F9 +:1024E0009518CE010E947A14882389F400D000D078 +:1024F000EDB7FEB7D283C18380E291E094838383FA +:102500000E942C0B0F900F900F900F90FFCFCE01D9 +:1025100061E00E94EE15CE0162E040E00E940C17DF +:10252000CE010E943817CE016F2D0E941F16CE01DA +:102530006E2D0E94F316CE01B8010E94C216CE0184 +:1025400065E04FE00E94E415CE0162E070E00E9479 +:10255000A716CE010E945417CE0162E0EE24EA9441 +:102560002CEFF22E01EE18EA28EA30E040E050E0CD +:102570000E947317DF91CF911F910F91FF90EF9001 +:1025800008958F929F92AF92BF92CF92DF92EF9277 +:10259000FF920F931F93CF93DF93EC014B01D42E47 +:1025A000122F88E692E040E052EC61E070E026E015 +:1025B0000E9451211C8A1A8A112311F081E08A8B12 +:1025C000CB58DF4F99828882C557D0408A898823AB +:1025D00019F0CE010E944812CE01B7014C2D950191 +:1025E0000E945F12CE010E9660E070E043E050E082 +:1025F00021E23BE00E945403CE01419663E271E088 +:1026000041E050E021E23BE00E94540389898F3F82 +:1026100011F481E0898B0F3F19F00F871B8A02C0EC +:1026200081E08B8B8FEFD812DE868B89882331F087 +:102630008F858F3F19F4CE010E94AF108E858F3F9A +:1026400019F4CE010E94DF108A89882319F420E34F +:1026500031E002C027E331E0ADB7BEB718970FB63F +:10266000F894BEBF0FBEADBFEDB7FEB73196129660 +:10267000DC93CE9311978DE291E09383828335832F +:1026800024838E85868317820E942C0BDC2ECD2E10 +:102690008DB79EB708960FB6F8949EBF0FBE8DBF3C +:1026A0008E85282F30E040E050E060E070E080E070 +:1026B00090E0E22E01E03D3F08F400E011E0423EF0 +:1026C00008F410E00F511060E1E0593A08F4E0E03E +:1026D0001855F1E0183A08F0F0E0EF2BF1E0693A14 +:1026E00008F4F0E0BE2FB855E1E0B83A08F0E0E0B9 +:1026F000FE2BA1E0772309F4A0E0E1E0882309F4B0 +:10270000E0E08D2D9C2D60E04CEFF42E2B2F3F2F21 +:102710004A2F5E2F0E9473178E85282F30E040E0ED +:1027200050E060E070E080E090E0E22E01E03D3FAC +:1027300008F400E011E0423E08F410E00F51106090 +:10274000E1E0593A08F4E0E01855F1E0183A08F0F1 +:10275000F0E0EF2BF1E0693A08F4F0E0BE2FB85555 +:10276000E1E0B83A08F0E0E0FE2BA1E0772309F4BD +:10277000A0E0E1E0882309F4E0E08D2D9C2D61E0EC +:102780003CEFF32E2B2F3F2F4A2F5E2F0E94731703 +:102790008A89882311F441E101C042E1CE016FEF43 +:1027A00020E00E940D128E858F8B198E8FEF8B8FFC +:1027B00086E08A8F8E89807F83608E8BCE014596DE +:1027C0006F850E94490ABC01CE010E945011CE01C2 +:1027D0000E948E10DF91CF911F910F91FF90EF908B +:1027E000DF90CF90BF90AF909F908F9008950F9300 +:1027F0001F938C010E946914C80145960E943E0AED +:10280000C801C6960E943E0A1F910F910895411576 +:10281000510529F480917A008F7780937A006A308D +:102820007105B9F063FD02C0E8E001C0E8E2862F5F +:102830008770E82B88E190E00FB6F894A895809314 +:1028400060000FBEE0936000809160008064809320 +:102850006000232BA1F483B7817F846083BFF89449 +:1028600083B7816083BF85B7806685BF8F7D85BF55 +:102870007894889583B78E7F83BF78940EC083B792 +:10288000817F846083BFF89483B7816083BF78942D +:10289000889583B78E7F83BF7894452B29F48091E8 +:1028A0007A00806880937A0008951F920F920FB685 +:1028B0000F9211248F9388E10FB6F89480936000F3 +:1028C000109260000FBE8F910F900FBE0F901F905F +:1028D0001895FC01608341831282138280E2848315 +:1028E0001582168217821086118612861386148628 +:1028F00015860895FC0183810895FF920F931F931D +:102900008C01F62E81E00E94E71880E00E94F0180A +:1029100084E00E94F518F80181816F2D0E94CD207E +:102920001F910F91FF900895EF92FF920F931F93C5 +:10293000CF93DF93EC01162F042FF52EE22E60E0EB +:102940000E947D141770186A1EBD0DB407FEFDCFDE +:10295000802F9F2D9C01F9012E2D213208F020E2BD +:102960008EB508C080818EBD0DB407FEFDCF3196B7 +:102970008EB521502223B1F7CE0161E00E947D1473 +:10298000DF91CF911F910F91FF90EF900895CF931A +:10299000DF93EC0160E00E947D1480E58EBD0DB4F4 +:1029A00007FEFDCF8EB583E78EBD0DB407FEFDCFCC +:1029B0008EB5CE0161E00E947D14DF91CF91089524 +:1029C0001F93CF93DF93EC01162F60E00E947D14DC +:1029D0001EBD0DB407FEFDCF1EB5CE0161E00E9405 +:1029E0007D14812FDF91CF911F9108956FEF0E9489 +:1029F000E014089561EE0E94E014089562EE0E94D2 +:102A0000E01408951F93CF93DF93EC0160E00E94E0 +:102A10007D1480E68EBD0DB407FEFDCF8EB58FEF21 +:102A20008EBD0DB407FEFDCF1EB5CE0161E00E9444 +:102A30007D14113220F0CE010E94FE1410E0812F8F +:102A4000DF91CF911F910895EF92FF920F931F9303 +:102A5000CF93DF93EC01F62EE72E9C81142F941771 +:102A600008F4192F8D81882311F000E002C0092F8E +:102A7000011BCE0160E00E947D1481E68EBD0DB485 +:102A800007FEFDCF8F2D9E2D9C01F901FEB49FEF17 +:102A900007C09EBD0DB407FEFDCF8EB581931150CA +:102AA0001123B9F707C08EBD0DB407FEFDCF9EB54B +:102AB000015001C08FEF0023B1F7CE0161E00E9409 +:102AC0007D148F2DDF91CF911F910F91FF90EF908B +:102AD0000895DF92EF92FF920F931F93CF93DF93AE +:102AE000EC01E62ED72EF22E9C81142F941708F4B9 +:102AF000192F8D81882311F000E002C0092F011BDE +:102B0000CE0160E00E947D14FEBC0DB407FEFDCF37 +:102B10008E2D9D2D9C01F901FEB408C080818EBDD3 +:102B20000DB407FEFDCF31968EB511501123B1F7CC +:102B300006C01EBC0DB407FEFDCF8EB501500023AC +:102B4000C1F7CE0161E00E947D148F2DDF91CF91FE +:102B50001F910F91FF90EF90DF900895CF93DF9337 +:102B6000EC01222311F420EA01C020EBCE010E94E7 +:102B70006915888161E00E94CD20888160E00E9413 +:102B8000CD20DF91CF9108950F931F93CF93DF93C3 +:102B9000EC01162F042F60E00E947D141F7110625B +:102BA0001EBD0DB407FEFDCF1EB50EBD0DB407FE54 +:102BB000FDCF8EB5CE0161E00E947D14812FDF91A3 +:102BC000CF911F910F910895262F4F702295207F4E +:102BD000242B64E0422F0E94C4150895662319F047 +:102BE00061E04FE302C061E040E00E94C415089537 +:102BF0000F931F938C010E942415C80167E040E7E2 +:102C00000E94C4151F910F910895CF93DF93EC019B +:102C10000E94AE15CE010E94F6148073D9F3CE0146 +:102C200067E040E70E94C41584FD02C081E004C053 +:102C3000CE010E94FA1480E0DF91CF910895462FD3 +:102C4000603808F04FE765E00E94C4150895EF92E0 +:102C5000FF920F931F93CF93DF937C01162FEA010E +:102C6000022F60E00E947D141F7110621EBD0DB422 +:102C700007FEFDCF1EB508C088818EBD0DB407FECE +:102C8000FDCF21968EB501500023B1F7C70161E059 +:102C90000E947D14812FDF91CF911F910F91FF90A2 +:102CA000EF900895EF92FF920F931F93DF93CF93CE +:102CB000CDB7DEB728970FB6F894DEBF0FBECDBFF5 +:102CC0007C0109831A832B833C834D835E836F834E +:102CD00078878E010F5F1F4F6AE0A80125E00E94F0 +:102CE0002716C70160E1A80125E00E942716C70149 +:102CF00061E1F70144810E94C41528960FB6F8944B +:102D0000DEBF0FBECDBFCF91DF911F910F91FF901E +:102D1000EF9008951F93CF93DF93EC01162F60E09F +:102D20000E947D141F711EBD0DB407FEFDCF8EB530 +:102D30008FEF8EBD0DB407FEFDCF1EB5CE0161E055 +:102D40000E947D14812FDF91CF911F9108950F93E1 +:102D50001F93CF93DF938C01EB0160E00E948A16F2 +:102D6000482F437F209729F0219711F4486001C034 +:102D70004C60C80160E00E94C415DF91CF911F91A3 +:102D80000F910895FF920F931F93CF93DF93EC0160 +:102D90008B0166E00E948A161A82F7EDFF2EF82258 +:102DA0000230110511F480E206C00130110529F44A +:102DB00081E08A8388E0F82A01C01A82CE0166E0A9 +:102DC0004F2D0E94C415CE0166E00E948A168F1511 +:102DD00011F481E002C01A8280E0DF91CF911F914F +:102DE0000F91FF9008951F93CF93DF93EC01162F5F +:102DF00066E00E948A16143010F04CE003C0412FA8 +:102E0000440F4F5F887F482BCE0166E00E94C415B7 +:102E1000DF91CF911F9108950F931F93CF93DF936D +:102E2000EC01162F042F6730F0F461E00E948A163F +:102E3000282F002351F081E090E002C0880F991FF5 +:102E40001A95E2F7422F482B0AC081E090E002C0B9 +:102E5000880F991F1A95E2F7482F40954223CE011B +:102E600061E00E94C415DF91CF911F910F910895E9 +:102E70000F931F938C010E94C714C8016DE10E943B +:102E80008A16482F4660C8016DE10E94C415C8012A +:102E90006CE10E948A16482F4360C8016CE10E94D1 +:102EA000C4151F910F9108950F931F938C010E94D9 +:102EB000C714C8016DE10E948A16482F4460C801FA +:102EC0006DE10E94C415C8016CE10E948A16482F6A +:102ED0004F63C8016CE10E94C41581E0F80185834D +:102EE0001F910F910895BF92CF92DF92EF92FF92C0 +:102EF0000F931F93DF93CF93CDB7DEB728970FB60D +:102F0000F894DEBF0FBECDBF6C01B62EE982FA8207 +:102F10000B831C832D833E834F835887662389F45C +:102F2000F601E6828A8187838B8180878C81818705 +:102F30008D8182878E8183878F818487888585872D +:102F400007C0F6E0F61708F43DC081E0681761F4A9 +:102F5000EB2DF0E0EA5BFE4FE491C6016E2FAE016F +:102F60004F5F5F4F25E00BC0E62FF0E0EA5BFE4FBE +:102F7000E491C6016E2FAE014F5F5F4F21E00E94CA +:102F800027160B2D10E0F801E45BFE4FE491C6011B +:102F90006E2FF60144810E94C415C60162E00E94B2 +:102FA0008A16005C1E4FF801649121E030E002C0F7 +:102FB000220F331F6A95E2F7482F422BC60162E0C9 +:102FC0000E94C41528960FB6F894DEBF0FBECDBF81 +:102FD000CF91DF911F910F91FF90EF90DF90CF90F5 +:102FE000BF9008950F931F93CF93DF93EC018B0154 +:102FF00067E10E948A1680FF02C080E00DC00115C3 +:10300000110549F0CE010E94F61490E09595879540 +:103010008770F801808381E0DF91CF911F910F913C +:103020000895CF93DF93EC0160E00E948A1681FD42 +:1030300010C0CE0160E00E948A16482F4260CE0187 +:1030400060E00E94C41565E070E080E090E00E94BE +:103050002620DF91CF9108950F931F938C01FC01DF +:10306000808160E00E94CD20C80160E00E948A1645 +:10307000482F4D7FC80160E00E94C4151F910F9139 +:1030800008950F931F938C01FC01808160E00E94E2 +:10309000CD20C8010E94FA14C8010E94FE14C80184 +:1030A00060E00E948A16482F4E7FC80160E00E94AF +:1030B000C4151F910F910895CF93DF93EC010E94E7 +:1030C0001118CE0160E00E948A16482F4160CE019F +:1030D00060E00E94C415CE0167E040E70E94C4157D +:1030E0008E819F81892B9885892B9985892B9A853B +:1030F000892B9B85892B9C85892B9D85892B41F06C +:10310000AE014A5F5F4FCE016AE025E00E942716BC +:10311000CE010E94FE14CE010E94FA14888161E063 +:103120000E94CD20DF91CF910895CF93DF93EC01E2 +:10313000888161E00E948E20898161E00E948E205A +:103140000E940619888160E00E94CD20CE0161E0D6 +:103150000E947D1465E070E080E090E00E942620EF +:10316000CE0165E04FE00E94E415CE0162E070E020 +:103170000E94C216882311F081E08B83CE0160E0AB +:1031800070E00E94C216CE0162E070E00E94A716B5 +:10319000CE0167E040E70E94C415CE016CE40E94B6 +:1031A0001F16CE010E94FE14CE010E94FA14CE0119 +:1031B0000E941118CE0160E00E948A16482F4E7FAF +:1031C000CE0160E00E94C415DF91CF91089588235D +:1031D00019F48CB5806202C08CB58F7D8CBD0895CA +:1031E0009CB5937F982B9CBD08952CB5382F3370D8 +:1031F0002C7F322B3CBD2DB590E09595879595950C +:10320000879581702E7F822B8DBD08958AE061E0C5 +:103210000E94CD208AE061E00E948E208CB5806102 +:103220008CBD8CB580648CBD8DE061E00E948E20E9 +:103230008BE061E00E948E200895FC0185EE99E10B +:10324000918B808B75836483138210828FE190E071 +:10325000928381830895FC01838108956F927F9208 +:103260008F929F92AF92BF92CF92DF92EF92FF9296 +:103270000F931F93CF93DF93FB01EA01998180E0C5 +:10328000288130E0282B392BE081E23231F0E8321E +:1032900021F0E03109F084C04BC04C814F3329F15B +:1032A000403420F44F3109F07BC02FC04F3579F006 +:1032B0004F3709F075C0B901882777FD8095982FA1 +:1032C0000E946A2420E030E040E85DE32EC035959E +:1032D0002795B901882777FD8095982F0E946A2449 +:1032E00020E030E040E05EE320C03595279535953D +:1032F0002795B901882777FD8095982F0E946A2429 +:1033000020E030E040E85EE310C093E0359527957B +:103310009A95E1F7B901882777FD8095982F0E944B +:103320006A2420E030E040E05FE30E941A2532C0CA +:10333000EF8035952795B901882777FD8095982FDF +:103340000E946A2420E030E040E85EE30E946623A9 +:103350003B014C016E2D70E02E81621B71098827A4 +:1033600077FD8095982F0E946A245B016C01FF24F1 +:1033700000E010E0C801B7010E9468249B01AC0185 +:10338000C601B5010E94CF239B01AC01C401B3016A +:103390000E9467239B01AC01832F942F752F00C0DF +:1033A000262F382F492F572FB901CA01DF91CF910E +:1033B0001F910F91FF90EF90DF90CF90BF90AF9053 +:1033C0009F908F907F906F9008950895EF92FF9255 +:1033D0000F931F938C017B01FC01848195810E94D6 +:1033E000E51CF80184819581B7010E94C41CF80195 +:1033F0008481958164EB40E00E947F1CF801848108 +:1034000095810E94FA1BF82EF801848195810E9413 +:10341000E51C80E0FF2009F481E01F910F91FF90EF +:10342000EF9008950F931F938C01FC018481958187 +:103430000E94E51CF801848195810E94BF1CF8015F +:103440008481958164E440810E947F1CF801818120 +:1034500092818F33910551F08F35910561F04F972F +:1034600079F46EE570E080E090E00EC06CEB70E007 +:1034700080E090E009C067E771E080E090E004C080 +:103480006EEE72E080E090E00E9426201F910F9186 +:103490000895CF92DF92EF92FF920F931F938C01CA +:1034A0006B017A01FC01848195810E94E51CF80181 +:1034B00084819581B6010E94C41CF80184819581A4 +:1034C0006EEB40E00E947F1CF801848195810E9490 +:1034D0002E1CF7018083F801848195810E942E1CA7 +:1034E000F7018183F801848195810E942E1CF701E8 +:1034F0008283F801848195810E942E1CF7018383C9 +:10350000F801848195810E942E1CF7018483F801C3 +:10351000848195810E942E1CF7018583F8018481A6 +:1035200095810E942E1CF7018683F8018481958184 +:103530000E942E1CF7018783F801848195810E94E7 +:103540002E1CF7018087F801848195810E94E51C7B +:103550001F910F91FF90EF90DF90CF9008950F9300 +:103560001F938A010E94491AC80168E00E94E91B62 +:1035700020E0F8019085891709F421E0822F1F913E +:103580000F910895CF92DF92EF92FF920F931F93C6 +:10359000DF93CF93CDB7DEB729970FB6F894DEBF90 +:1035A0000FBECDBF8C017B016E010894C11CD11CE4 +:1035B000A6010E94AF1A882329F460E070E08EEF24 +:1035C00092EC05C0C801B701A6010E942E192996E8 +:1035D0000FB6F894DEBF0FBECDBFCF91DF911F9124 +:1035E0000F91FF90EF90DF90CF9008950F931F936E +:1035F0008B01CB0167E00E94E91B20E0F801978175 +:10360000891709F421E0822F1F910F910895EF92FD +:10361000FF920F931F93CF93DF93EC017B01042F55 +:103620008C819D810E94DC1B10E007C0CE01B70198 +:103630000E94F61A8823A9F00AC08C819D81B701E7 +:103640000E94301D882329F0101759F4EFCF81E034 +:1036500001C080E0DF91CF911F910F91FF90EF901B +:1036600008951F5F0117A8F3E8CFEF92FF920F9321 +:103670001F93DF93CF93CDB7DEB728970FB6F8949B +:10368000DEBF0FBECDBF7C01462F8E010F5F1F4FE7 +:10369000B8010E94071BC701B8010E94C21A2896F0 +:1036A0000FB6F894DEBF0FBECDBFCF91DF911F9153 +:1036B0000F91FF90EF9008950E94351B26E636E6A5 +:1036C00046EE5FE30E941A2520E030E040E052E43D +:1036D0000E94672308959F92AF92BF92CF92DF928C +:1036E000EF92FF920F931F93DF93CF93CDB7DEB787 +:1036F00061970FB6F894DEBF0FBECDBF8C01FC0101 +:10370000848195810E94DC1BF80113827E0108945C +:10371000E11CF11CE9E0AE2EB12CAC0EBD1E7FE722 +:10372000C72ED12C992493942DC0C801B7010E94B3 +:10373000F61A882339F1F8018081882341F4C80101 +:10374000B7010E94E619882311F0F8019082C801A0 +:10375000B701A5010E94491A8981803121F4F8013D +:10376000D282C1820BC08D85282F30E0F801818183 +:1037700092818217930714F432832183F8018381A5 +:103780008F5F8383F80184819581B7010E94301D8A +:10379000882359F661960FB6F894DEBF0FBECDBFF1 +:1037A000CF91DF911F910F91FF90EF90DF90CF901D +:1037B000BF90AF909F900895FC01138615861486E4 +:1037C00087E090E012863197009711F00197FACFC9 +:1037D0000895DC0180E00BC0E82FF0E08D9190E0CF +:1037E000E827F927ED5FFC4FE49161508E2F6623A7 +:1037F00099F70895DF92EF92FF920F931F93FC01C8 +:10380000E08001811281F894F80181818E29818301 +:103810008281DE2CD0948D21828383E090E00E940F +:10382000E11FF80181818D2181838AE090E00E946F +:10383000E11FF8010081789485E390E00E94E11F88 +:1038400080E010E0FF240E211F21012B09F081E010 +:103850001F910F91FF90EF90DF900895EF92FF92EC +:103860000F931F93CF93DF937C0101E010E0C0E042 +:10387000D0E0C7010E94FA1B8111102B000F219686 +:10388000C830D105B1F7812FDF91CF911F910F91F2 +:10389000FF90EF9008951F93CF93DF93FC01108169 +:1038A000C181D281912F909560FF12C0F8948A81D6 +:1038B00089238A838981812B89838AE090E00E9411 +:1038C000E11F8A81812B8A83789487E390E011C07D +:1038D000F8948A8189238A838981812B898381E471 +:1038E00090E00E94E11F8A81812B8A83789485E091 +:1038F00090E00E94E11FDF91CF911F910895CF9238 +:10390000DF92EF92FF920F931F93CF93DF938C017F +:10391000E42EFF24F394C0E0D0E0C62EDD2460E066 +:103920008F2D90E08C219D21892B09F061E0C80149 +:103930000E944B1CFF0C2196C830D10581F7EE2068 +:10394000A9F4F894D8011196ED91FC911297918108 +:103950008C918095982391831196ED91FC9112970B +:1039600092818C918095982392837894DF91CF9166 +:103970001F910F91FF90EF90DF90CF9008956CEC26 +:1039800040E00E947F1C0895EF92FF920F931F93D7 +:10399000CF93DF938C017B0165E540E00E947F1CA3 +:1039A000C0E0D0E0F701EC0FFD1FC801608140E0EE +:1039B0000E947F1C2196C830D105A1F7DF91CF91DD +:1039C0001F910F91FF90EF900895DF92EF92FF9279 +:1039D0000F931F93CF93DF93FC010081C181D281AC +:1039E000F8948981D02ED0948D21898378941DE715 +:1039F000E02EFF24115059F182E090E00E94E11F77 +:103A0000888190E08E219F21892BA1F3F8948A81EF +:103A10008D218A838981802B8983789484EF91E03A +:103A20000E94E11FF89489818D21898380E590E0CF +:103A30000E94E11F888110E090E0E822F922EF283F +:103A400009F411E0789484EA91E00E94E11F812F4B +:103A5000DF91CF911F910F91FF90EF90DF9008952C +:103A6000AF92BF92DF92EF92FF920F931F93CF938B +:103A7000DF93EC015B018D85882309F061C0CE01E5 +:103A80000E94E51C882329F41B861D861C8690E075 +:103A90006BC0CE0160EF40E00E947F1C01E0DD249E +:103AA000EE24FF24F394CE010E94FA1B182FCE01BE +:103AB0000E94FA1B113019F48130E1F439C0181753 +:103AC00009F58B85081770F460E0FE01EE0DF11D1D +:103AD000838190E02F2D30E082239323181619065E +:103AE0004CF003C060E0081729F0093008F04CC022 +:103AF0000C874AC0FE01EE0DF11D83818F2983835F +:103B000061E009C0612FFE01EE0DF11D9F2D909522 +:103B1000838189238383CE010E944B1C0F5FFF0C9E +:103B200019F4E394FF24F39487E08E1508F0BBCFDB +:103B3000013430F0DB86DD2011F581E08D871FC078 +:103B40001B861D861C8690E0DE0120E030E0F5013A +:103B5000E20FF31F13968C91139780832F5F3F4FD3 +:103B600011962830310599F7892FDF91CF911F9158 +:103B70000F91FF90EF90DF90BF90AF9008958B81F1 +:103B80008823F1F291E0E0CFD02EBDCFFF920F93CA +:103B90001F938C01F62E862F60E00E948E208F2DC1 +:103BA00090E0FC01EB5CFB4FE491D801EC938F5D5E +:103BB0009B4FFC016491E62FF0E0EE0FFF1FE95EE2 +:103BC000FB4F8591949112969C938E9311971B961F +:103BD0001C921B971D961C921D971C961C92F80117 +:103BE00087E090E012863197009711F00197FACFA5 +:103BF0001F910F91FF9008950F931F93CF93DF9321 +:103C0000BC018230910510F462E070E0E09107039E +:103C1000F091080340E050E0A0E0B0E024C08081D3 +:103C2000918186179707D0F08617970771F48281E4 +:103C30009381109729F013969C938E9312972CC022 +:103C4000909308038093070327C04115510519F08D +:103C50008417950718F48D01AC01EF01DF01828113 +:103C600093819C01F9013097D1F641155105F9F086 +:103C7000CA01861B970B8430910580F48A819B8151 +:103C80000115110521F0F8019383828304C09093FC +:103C9000080380930703FE01329645C0FE01E80F3A +:103CA000F91F619371930297998388833CC0809137 +:103CB000050390910603892B41F480914C0190916A +:103CC0004D01909306038093050340914E0150915E +:103CD0004F014115510541F44DB75EB780914A013E +:103CE00090914B01481B590B20910503309106031D +:103CF00024173507B0F4CA01821B930B8617970768 +:103D000080F0AB014E5F5F4F8417950750F0420F74 +:103D1000531F5093060340930503F9016193719378 +:103D200002C0E0E0F0E0CF01DF91CF911F910F9151 +:103D30000895CF93DF939C01009709F48FC0EC01A5 +:103D400022971B821A826091070370910803611504 +:103D5000710581F488819981820F931F2091050359 +:103D6000309106032817390739F5D0930603C0931D +:103D7000050374C0DB0140E050E0AC17BD0708F15B +:103D8000BB83AA83FE0121913191E20FF31FAE178D +:103D9000BF0779F48D919C911197280F391F2E5FE1 +:103DA0003F4F3983288312968D919C9113979B8363 +:103DB0008A834115510571F4D0930803C09307031A +:103DC0004DC012968D919C911397AD01009711F003 +:103DD000DC01D3CFDA011396DC93CE931297FA016C +:103DE00021913191E20FF31FCE17DF0769F488812B +:103DF0009981280F391F2E5F3F4FFA0131832083AD +:103E00008A819B8193838283E0E0F0E0DB0112965C +:103E10008D919C911397009719F0BC01FD01F6CF8D +:103E2000AB014E5F5F4FDB018D919C91840F951F1D +:103E300020910503309106032817390779F430974C +:103E400029F4109208031092070302C01382128211 +:103E5000425050405093060340930503DF91CF91A9 +:103E600008951F920F920FB60F9211242F933F9334 +:103E70004F935F936F937F938F939F93AF93BF9372 +:103E8000EF93FF9380915B0290915C02892B29F064 +:103E9000E0915B02F0915C020995FF91EF91BF9177 +:103EA000AF919F918F917F916F915F914F913F91D2 +:103EB0002F910F900FBE0F901F9018951F920F9289 +:103EC0000FB60F9211242F933F934F935F936F93ED +:103ED0007F938F939F93AF93BF93EF93FF938091C3 +:103EE0005D0290915E02892B29F0E0915D02F091D4 +:103EF0005E020995FF91EF91BF91AF919F918F91D4 +:103F00007F916F915F914F913F912F910F900FBED5 +:103F10000F901F9018951F920F920FB60F921124B9 +:103F20002F933F938F939F93AF93BF93809163029F +:103F300090916402A0916502B0916602309167028F +:103F40000196A11DB11D232F2D5F2D3720F02D5778 +:103F50000196A11DB11D2093670280936302909387 +:103F60006402A0936502B093660280915F02909113 +:103F70006002A0916102B09162020196A11DB11D83 +:103F800080935F0290936002A0936102B0936202FB +:103F9000BF91AF919F918F913F912F910F900FBE45 +:103FA0000F901F9018958FB7F8942091630230916D +:103FB000640240916502509166028FBFB901CA0147 +:103FC0000895019739F0880F991F880F991F02975C +:103FD0000197F1F70895789484B5826084BD84B523 +:103FE000816084BD85B5826085BD85B5816085BDF4 +:103FF000EEE6F0E0808181608083E1E8F0E010820D +:10400000808182608083808181608083E0E8F0E04D +:10401000808181608083E1EBF0E080818460808337 +:10402000E0EBF0E0808181608083EAE7F0E080816E +:1040300084608083808182608083808181608083CE +:104040008081806880831092C1000895EF92FF9272 +:104050000F931F93CF93DF937B018C013FB7F894AD +:1040600080915F0290916002A0916102B091620222 +:1040700026B5A89B05C02F3F19F00196A11DB11DC3 +:104080003FBFBA2FA92F982F8827820F911DA11DFE +:10409000B11D52E0880F991FAA1FBB1F5A95D1F777 +:1040A000EC0130C00E9465233FB7F89480915F0215 +:1040B00090916002A0916102B091620226B5A89B26 +:1040C00005C02F3F19F00196A11DB11D3FBFBA2FAA +:1040D000A92F982F8827820F911DA11DB11D32E0B5 +:1040E000880F991FAA1FBB1F3A95D1F78C1B9D0BF8 +:1040F000885E9340B8F20894E108F10801091109BB +:10410000C851DC4FE114F1040105110559F6DF91A6 +:10411000CF911F910F91FF90EF900895CF93DF9370 +:10412000482F50E0CA018B5C9B4FFC0134914F5DDE +:104130005B4FFA018491882369F190E0880F991F01 +:10414000FC01ED5FFB4FA591B491FC01E35FFB4FD8 +:10415000C591D491662351F42FB7F8948C91932F85 +:10416000909589238C93888189230BC0623061F4F8 +:104170002FB7F8948C91932F909589238C938881F5 +:10418000832B88832FBF06C09FB7F8948C91832B15 +:104190008C939FBFDF91CF910895482F50E0CA01C3 +:1041A000875B9B4FFC012491CA018B5C9B4FFC01F8 +:1041B00094914F5D5B4FFA013491332309F440C071 +:1041C000222351F1233071F0243028F42130A1F062 +:1041D000223011F514C02630B1F02730C1F0243060 +:1041E000D9F404C0809180008F7703C08091800053 +:1041F0008F7D8093800010C084B58F7702C084B516 +:104200008F7D84BD09C08091B0008F7703C08091FD +:10421000B0008F7D8093B000E32FF0E0EE0FFF1F22 +:10422000E35FFB4FA591B4912FB7F894662321F477 +:104230008C919095892302C08C91892B8C932FBFF0 +:104240000895DC015C968C915C97FD01E80FF11DEF +:10425000E35AFF4F20815C968C915C9790E0019629 +:104260008F7390705C968C935C975696ED91FC9151 +:10427000579720835096ED91FC91519780818064EF +:1042800080835B969C915B975C968C915C9798176A +:1042900039F45296ED91FC91539780818F7D808304 +:1042A0000895DF92EF92FF920F931F93CF93DF93C6 +:1042B000EC017A018B01D22EE889F98982E08083B2 +:1042C000403081EE580780E0680780E07807A1F071 +:1042D00060E079E08DE390E0A80197010E947D25E0 +:1042E000215030404040504056954795379527958E +:1042F00080E12030380798F0E889F989108260E879 +:1043000074E88EE190E0A80197010E947D2521507C +:104310003040404050405695479537952795EC855D +:10432000FD853083EE85FF852083188EEC89FD891D +:10433000D082EA89FB89808180618083EA89FB8958 +:10434000808188608083EA89FB898081806880839E +:10435000EA89FB8980818F7D8083DF91CF911F91D6 +:104360000F91FF90EF90DF900895FC01218D828DD9 +:1043700030E0205C3F4F281B31092F733070C9019A +:104380000895FC01918D828D981719F42FEF3FEF5E +:1043900006C0828DE80FF11D858D282F30E0C90100 +:1043A0000895DC0159969C9159975A968C915A9789 +:1043B000981719F42FEF3FEF10C05A968C915A9727 +:1043C000FD01E80FF11D958D5A968C915A978F5FDC +:1043D0008F735A968C93292F30E0C9010895CF939B +:1043E000DF93EC01888D882361F419C08C9185FFDF +:1043F0000AC0E889F989808185FF05C0CE010E9445 +:104400002121AA89BB898C9185FD05C0E889F9899C +:10441000808186FD04C00FB607FEE8CFF4CFDF91A0 +:10442000CF9108950F931F93CF93DF93EC01062F45 +:104430009B8D8C8D981791F5E889F989808185FF8E +:104440002DC0EE89FF896083E889F98980818064C5 +:1044500080831DC00FB607FC08C0E889F9898081F8 +:1044600085FF03C0CE010E9421218C8D181791F386 +:104470008B8DFE01E80FF11DE35AFF4F00831B8F68 +:10448000EA89FB8980818062808381E0888F81E076 +:1044900090E0DF91CF911F910F9108951B8D1F5FC9 +:1044A0001F73E3CF8AED92E2892B51F080E090E018 +:1044B000892B31F00E94DA22882311F00E9400003B +:1044C00008951F920F920FB60F9211242F938F937E +:1044D0009F93EF93FF93E0917802F09179028081AE +:1044E00082FD16C0E0917E02F0917F0220819091C2 +:1044F00081029F5F9F7380918202981771F0E09113 +:104500008102F0E0E859FD4F258F9093810205C0AC +:10451000E0917E02F0917F02E081FF91EF919F9107 +:104520008F912F910F900FBE0F901F9018951092A2 +:104530006B0210926A0288EE93E0A0E0B0E08093F4 +:104540006C0290936D02A0936E02B0936F0284E5AB +:1045500091E0909369028093680285EC90E09093DB +:1045600075028093740284EC90E0909377028093BC +:10457000760280EC90E0909379028093780281EC4F +:1045800090E090937B0280937A0282EC90E090938B +:104590007D0280937C0286EC90E090937F02809372 +:1045A0007E02109281021092820210928302109277 +:1045B0008402089588E692E00E94B52120E0892BCC +:1045C00009F021E0822F08951F920F920FB60F92EB +:1045D00011242F933F934F935F936F937F938F9308 +:1045E0009F93AF93BF93EF93FF9388E692E00E946F +:1045F0002121FF91EF91BF91AF919F918F917F9179 +:104600006F915F914F913F912F910F900FBE0F903F +:104610001F901895CF93DF930E94EB1F0E94F20921 +:10462000C2E5D2E20E945B092097E1F30E94522288 +:10463000F9CF0E94FC1D0895CF92DF92EF92FF9276 +:104640000F931F93CF93DF937C016B018A01C0E02E +:10465000D0E00FC0D6016D916D01D701ED91FC91B5 +:104660000190F081E02DC7010995C80FD91F0150B5 +:1046700010400115110571F7CE01DF91CF911F9107 +:104680000F91FF90EF90DF90CF900895CF93DF933D +:10469000EC016115710519F420E030E00FC0DB0179 +:1046A0000D900020E9F71197A61BB70BE881F9815F +:1046B0000280F381E02DAD0109959C01C901DF91D4 +:1046C000CF9108950E944623089508955058BB271E +:1046D000AA270ED075C166D130F06BD120F031F42D +:1046E0009F3F11F41EF45BC10EF4E095E7FB51C14E +:1046F000E92F77D180F3BA1762077307840795070C +:1047000018F071F49EF58FC10EF4E0950B2EBA2FC0 +:10471000A02D0B01B90190010C01CA01A0011124C7 +:10472000FF27591B99F0593F50F4503E68F11A1673 +:10473000F040A22F232F342F4427585FF3CF469504 +:1047400037952795A795F0405395C9F77EF41F1626 +:10475000BA0B620B730B840BBAF09150A1F0FF0FF0 +:10476000BB1F661F771F881FC2F70EC0BA0F621FDC +:10477000731F841F48F4879577956795B795F795CC +:104780009E3F08F0B3CF9395880F08F09927EE0F5E +:10479000979587950895D9D008F481E008950CD0B5 +:1047A0000FC107D140F0FED030F021F45F3F19F087 +:1047B000F0C0511139C1F3C014D198F39923C9F352 +:1047C0005523B1F3951B550BBB27AA276217730717 +:1047D000840738F09F5F5F4F220F331F441FAA1FCB +:1047E000A9F333D00E2E3AF0E0E830D0915050408B +:1047F000E695001CCAF729D0FE2F27D0660F771F39 +:10480000881FBB1F261737074807AB07B0E809F01A +:10481000BB0B802DBF01FF2793585F4F2AF09E3FAF +:10482000510568F0B6C000C15F3FECF3983EDCF381 +:10483000869577956795B795F7959F5FC9F7880F28 +:10484000911D9695879597F90895E1E0660F771F7A +:10485000881FBB1F621773078407BA0720F0621B0B +:10486000730B840BBA0BEE1F88F7E095089504D004 +:104870006894B111D9C00895BCD088F09F5790F0CA +:10488000B92F9927B751A0F0D1F0660F771F881F75 +:10489000991F1AF0BA95C9F712C0B13081F0C3D090 +:1048A000B1E00895C0C0672F782F8827B85F39F02E +:1048B000B93FCCF3869577956795B395D9F73EF4D4 +:1048C00090958095709561957F4F8F4F9F4F08957C +:1048D000E89409C097FB3EF490958095709561959A +:1048E0007F4F8F4F9F4F9923A9F0F92F96E9BB2750 +:1048F0009395F695879577956795B795F111F8CFCC +:10490000FAF4BB0F11F460FF1BC06F5F7F4F8F4F36 +:104910009F4F16C0882311F096E911C0772321F02C +:104920009EE8872F762F05C0662371F096E8862FC4 +:1049300070E060E02AF09A95660F771F881FDAF71B +:10494000880F9695879597F90895990F0008550F48 +:10495000AA0BE0E8FEEF16161706E807F907C0F005 +:1049600012161306E407F50798F0621B730B840B0D +:10497000950B39F40A2661F0232B242B252B21F4E7 +:1049800008950A2609F4A140A6958FEF811D811D87 +:10499000089597F99F6780E870E060E008959FEFC1 +:1049A00080EC089500240A941616170618060906C6 +:1049B000089500240A941216130614060506089595 +:1049C000092E0394000C11F4882352F0BB0F40F41D +:1049D000BF2B11F460FF04C06F5F7F4F8F4F9F4F5D +:1049E000089557FD9058440F551F59F05F3F71F0DF +:1049F0004795880F97FB991F61F09F3F79F0879546 +:104A00000895121613061406551FF2CF4695F1DFCE +:104A100008C0161617061806991FF1CF869571055E +:104A2000610508940895E894BB2766277727CB0192 +:104A300097F908950BD0C4CFB5DF28F0BADF18F08E +:104A4000952309F0A6CFABCF1124EECFCADFA0F398 +:104A5000959FD1F3950F50E0551F629FF001729F13 +:104A6000BB27F00DB11D639FAA27F00DB11DAA1F32 +:104A7000649F6627B00DA11D661F829F2227B00D7F +:104A8000A11D621F739FB00DA11D621F839FA00D0A +:104A9000611D221F749F3327A00D611D231F849F5A +:104AA000600D211D822F762F6A2F11249F575040B1 +:104AB0008AF0E1F088234AF0EE0FFF1FBB1F661F4C +:104AC000771F881F91505040A9F79E3F510570F005 +:104AD00060CFAACF5F3FECF3983EDCF386957795E5 +:104AE0006795B795F795E7959F5FC1F7FE2B880F00 +:104AF000911D9695879597F90895A1E21A2EAA1B04 +:104B0000BB1BFD010DC0AA1FBB1FEE1FFF1FA2177D +:104B1000B307E407F50720F0A21BB30BE40BF50B7A +:104B2000661F771F881F991F1A9469F76095709503 +:104B3000809590959B01AC01BD01CF010895EE0FCA +:104B4000FF1F0590F491E02D0994AA1BBB1B51E1B6 +:104B500007C0AA1FBB1FA617B70710F0A61BB70BED +:104B6000881F991F5A95A9F780959095BC01CD0192 +:104B700008952F923F924F925F926F927F928F9201 +:104B80009F92AF92BF92CF92DF92EF92FF920F93DC +:104B90001F93CF93DF93CDB7DEB7CA1BDB0B0FB6E6 +:104BA000F894DEBF0FBECDBF09942A8839884888A3 +:104BB0005F846E847D848C849B84AA84B984C88439 +:104BC000DF80EE80FD800C811B81AA81B981CE0F30 +:104BD000D11D0FB6F894DEBF0FBECDBFED01089515 +:044BE000F894FFCF77 +:104BE40054656D70657261747572652053656E737A +:104BF4006F7200312E30006661696C006F6B0000CB +:104C0400312E346231202831383834386132290069 +:104C140073656E736F72007265706561746572009E +:104C240030750000307500000100800009030000A9 +:104C34000000000012221C23B521D121C121EF2143 +:00000001FF diff --git a/NodeJsController/DallasTemperatureSensor/DallasTemperatureSensor.ino b/NodeJsController/DallasTemperatureSensor/DallasTemperatureSensor.ino new file mode 100644 index 0000000..3ac3888 --- /dev/null +++ b/NodeJsController/DallasTemperatureSensor/DallasTemperatureSensor.ino @@ -0,0 +1,69 @@ +// Example sketch showing how to send in OneWire temperature readings +#include +#include +#include +#include + +#define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected +#define MAX_ATTACHED_DS18B20 16 +unsigned long WAIT_TIME = 30000; // Wait for feedback from controller after sending and before going to sleep (in milliseconds) +unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) +OneWire oneWire(ONE_WIRE_BUS); +DallasTemperature sensors(&oneWire); +MySensor gw; +float lastTemperature[MAX_ATTACHED_DS18B20]; +int numSensors=0; +boolean receivedConfig = false; +boolean metric = true; +// Initialize temperature message +MyMessage msg(0,V_TEMP); + +void setup() +{ + // Startup OneWire + sensors.begin(); + + // Startup and initialize MySensors library. Set callback for incoming messages. + gw.begin(); + + // Send the sketch version information to the gateway and Controller + gw.sendSketchInfo("Temperature Sensor", "1.0"); + + // Fetch the number of attached temperature sensors + numSensors = sensors.getDeviceCount(); + + // Present all sensors to controller + for (int i=0; i(static_cast((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; + + // Only send data if temperature has changed and no error + if (lastTemperature[i] != temperature && temperature != -127.00) { + + // Send in the new temperature + gw.send(msg.setSensor(i).set(temperature,1)); + lastTemperature[i]=temperature; + } + } + delay(WAIT_TIME); + gw.process(); + gw.sleep(SLEEP_TIME); +} + + diff --git a/NodeJsController/DropDb.js b/NodeJsController/DropDb.js new file mode 100644 index 0000000..128168b --- /dev/null +++ b/NodeJsController/DropDb.js @@ -0,0 +1,17 @@ +const dbAddress = '127.0.0.1'; +const dbPort = 27017; +const dbName = 'MySensorsDb'; + +var dbc = require('mongodb').MongoClient; +dbc.connect('mongodb://' + dbAddress + ':' + dbPort + '/' + dbName, function(err, db) { + if (err) { + console.log('Error connecting to database at mongodb://' + dbAddress + ':' + dbPort + '/' + dbName); + } else { + db.dropDatabase(function(err, result) { + if (err) + console.log('Error dropping database at mongodb://' + dbAddress + ':' + dbPort + '/' + dbName); + else + console.log('Successfully dropped database at mongodb://' + dbAddress + ':' + dbPort + '/' + dbName); + }); + } +}); diff --git a/NodeJsController/NodeJsController.js b/NodeJsController/NodeJsController.js new file mode 100644 index 0000000..2a127fa --- /dev/null +++ b/NodeJsController/NodeJsController.js @@ -0,0 +1,666 @@ +const gwType = 'Ethernet'; +const gwAddress = '10.0.1.99'; +const gwPort = 9999; + +//const gwType = 'Serial'; +//const gwPort = 'COM4'; +//const gwBaud = 115200; + +const dbAddress = '127.0.0.1'; +const dbPort = 27017; +const dbName = 'MySensorsDb'; + +const fwHexFiles = [ 'BlinkRed.hex', 'BlinkGreen.hex', 'DallasTemperatureSensor.cpp.hex' ]; +const fwDefaultType = 2; // index of hex file from array above + +const FIRMWARE_BLOCK_SIZE = 16; +const BROADCAST_ADDRESS = 255; +const NODE_SENSOR_ID = 255; + +const C_PRESENTATION = 0; +const C_SET = 1; +const C_REQ = 2; +const C_INTERNAL = 3; +const C_STREAM = 4; + +const V_TEMP = 0; +const V_HUM = 1; +const V_LIGHT = 2; +const V_DIMMER = 3; +const V_PRESSURE = 4; +const V_FORECAST = 5; +const V_RAIN = 6; +const V_RAINRATE = 7; +const V_WIND = 8; +const V_GUST = 9; +const V_DIRECTION = 10; +const V_UV = 11; +const V_WEIGHT = 12; +const V_DISTANCE = 13; +const V_IMPEDANCE = 14; +const V_ARMED = 15; +const V_TRIPPED = 16; +const V_WATT = 17; +const V_KWH = 18; +const V_SCENE_ON = 19; +const V_SCENE_OFF = 20; +const V_HEATER = 21; +const V_HEATER_SW = 22; +const V_LIGHT_LEVEL = 23; +const V_VAR1 = 24; +const V_VAR2 = 25; +const V_VAR3 = 26; +const V_VAR4 = 27; +const V_VAR5 = 28; +const V_UP = 29; +const V_DOWN = 30; +const V_STOP = 31; +const V_IR_SEND = 32; +const V_IR_RECEIVE = 33; +const V_FLOW = 34; +const V_VOLUME = 35; +const V_LOCK_STATUS = 36; + +const I_BATTERY_LEVEL = 0; +const I_TIME = 1; +const I_VERSION = 2; +const I_ID_REQUEST = 3; +const I_ID_RESPONSE = 4; +const I_INCLUSION_MODE = 5; +const I_CONFIG = 6; +const I_PING = 7; +const I_PING_ACK = 8; +const I_LOG_MESSAGE = 9; +const I_CHILDREN = 10; +const I_SKETCH_NAME = 11; +const I_SKETCH_VERSION = 12; +const I_REBOOT = 13; + +const S_DOOR = 0; +const S_MOTION = 1; +const S_SMOKE = 2; +const S_LIGHT = 3; +const S_DIMMER = 4; +const S_COVER = 5; +const S_TEMP = 6; +const S_HUM = 7; +const S_BARO = 8; +const S_WIND = 9; +const S_RAIN = 10; +const S_UV = 11; +const S_WEIGHT = 12; +const S_POWER = 13; +const S_HEATER = 14; +const S_DISTANCE = 15; +const S_LIGHT_LEVEL = 16; +const S_ARDUINO_NODE = 17; +const S_ARDUINO_REPEATER_NODE = 18; +const S_LOCK = 19; +const S_IR = 20; +const S_WATER = 21; +const S_AIR_QUALITY = 22; + +const ST_FIRMWARE_CONFIG_REQUEST = 0; +const ST_FIRMWARE_CONFIG_RESPONSE = 1; +const ST_FIRMWARE_REQUEST = 2; +const ST_FIRMWARE_RESPONSE = 3; +const ST_SOUND = 4; +const ST_IMAGE = 5; + +const P_STRING = 0; +const P_BYTE = 1; +const P_INT16 = 2; +const P_UINT16 = 3; +const P_LONG32 = 4; +const P_ULONG32 = 5; +const P_CUSTOM = 6; + +var fs = require('fs'); + +function crcUpdate(old, value) { + var c = old ^ value; + for (var i = 0; i < 8; ++i) { + if ((c & 1) > 0) + c = ((c >> 1) ^ 0xA001); + else + c = (c >> 1); + } + return c; +} + +function pullWord(arr, pos) { + return arr[pos] + 256 * arr[pos + 1]; +} + +function pushWord(arr, val) { + arr.push(val & 0x00FF); + arr.push((val >> 8) & 0x00FF); +} + +function pushDWord(arr, val) { + arr.push(val & 0x000000FF); + arr.push((val >> 8) & 0x000000FF); + arr.push((val >> 16) & 0x000000FF); + arr.push((val >> 24) & 0x000000FF); +} + +function loadFirmware(fwtype, fwversion, filename, db) { + console.log("loading firmware: " + filename); + fwdata = []; + var start = 0; + var end = 0; + var pos = 0; + var hex = fs.readFileSync(filename).toString().split("\n"); + for(l in hex) { + line = hex[l].trim(); + if (line.length > 0) { + while (line.substring(0, 1) != ":") + line = line.substring(1); + var reclen = parseInt(line.substring(1, 3), 16); + var offset = parseInt(line.substring(3, 7), 16); + var rectype = parseInt(line.substring(7, 9), 16); + var data = line.substring(9, 9 + 2 * reclen); + var chksum = parseInt(line.substring(9 + (2 * reclen), 9 + (2 * reclen) + 2), 16); + if (rectype == 0) { + if ((start == 0) && (end == 0)) { + if (offset % 128 > 0) + throw new Error("error loading hex file - offset can't be devided by 128"); + start = offset; + end = offset; + } + if (offset < end) + throw new Error("error loading hex file - offset lower than end"); + while (offset > end) { + fwdata.push(255); + pos++; + end++; + } + for (var i = 0; i < reclen; i++) { + fwdata.push(parseInt(data.substring(i * 2, (i * 2) + 2), 16)); + pos++; + } + end += reclen; + } + } + } + var pad = end % 128; // ATMega328 has 64 words per page / 128 bytes per page + for (var i = 0; i < 128 - pad; i++) { + fwdata.push(255); + pos++; + end++; + } + var blocks = (end - start) / FIRMWARE_BLOCK_SIZE; + var crc = 0xFFFF; + for (var i = 0; i < blocks * FIRMWARE_BLOCK_SIZE; ++i) { + var v = crc; + crc = crcUpdate(crc, fwdata[i]); + } + db.collection('firmware', function(err, c) { + c.update({ + 'type': fwtype, + 'version': fwversion + }, { + $set: { + 'filename': filename, + 'blocks': blocks, + 'crc': crc, + 'data': fwdata + } + }, { + upsert: true + }, function(err, result) { + if (err) + console.log('Error writing firmware to database'); + }); + }); + console.log("loading firmware done. blocks: " + blocks + " / crc: " + crc); +} + +/* +function decode(msg) { + var msgs = msg.toString().split(";"); + rsender = +msgs[0]; + rsensor = +msgs[1]; + rcommand = +msgs[2]; + rtype = +msgs[3]; + var pl = msgs[4].trim(); + rpayload = []; + for (var i = 0; i < pl.length; i+=2) { + var b = parseInt(pl.substring(i, i + 2), 16); + rpayload.push(b); + } +} +*/ + +function encode(destination, sensor, command, acknowledge, type, payload) { + var msg = destination.toString(10) + ";" + sensor.toString(10) + ";" + command.toString(10) + ";" + acknowledge.toString(10) + ";" + type.toString(10) + ";"; + if (command == 4) { + for (var i = 0; i < payload.length; i++) { + if (payload[i] < 16) + msg += "0"; + msg += payload[i].toString(16); + } + } else { + msg += payload; + } + msg += '\n'; + return msg.toString(); +} + +function saveProtocol(sender, payload, db) { + db.collection('node', function(err, c) { + c.update({ + 'id': sender + }, { + $set: { + 'protocol': payload + } + }, { + upsert: true + }, function(err, result) { + if (err) + console.log("Error writing protocol to database"); + }); + }); +} + +function saveSensor(sender, sensor, type, db) { + db.collection('node', function(err, c) { + c.update({ + 'id': sender + }, { + $addToSet: { + sensor: type + } + }, function(err, result) { + if (err) + console.log("Error writing sensor to database"); + }); + }); +} + +function saveValue(sender, sensor, type, payload, db) { + var cn = "Value-" + sender.toString() + "-" + sensor.toString(); + db.createCollection(cn, function(err, c) { + c.save({ + 'timestamp': new Date().getTime(), + 'type': type, + 'value': payload + }, function(err, result) { + if (err) + console.log("Error writing value to database"); + }); + }); +} + +function saveBatteryLevel(sender, payload, db) { + var cn = "BatteryLevel-" + sender.toString(); + db.createCollection(cn, function(err, c) { + c.save({ + 'timestamp': new Date().getTime(), + 'value': payload + }, function(err, result) { + if (err) + console.log("Error writing battery level to database"); + }); + }); +} + +function saveSketchName(sender, payload, db) { + db.collection('node', function(err, c) { + c.update({ + 'id': sender + }, { + $set: { + 'sketchName': payload + } + }, function(err, result) { + if (err) + console.log("Error writing sketch name to database"); + }); + }); +} + +function saveSketchVersion(sender, payload, db) { + db.collection('node', function(err, c) { + c.update({ + 'id': sender + }, { + $set: { + 'sketchVersion': payload + } + }, function(err, result) { + if (err) + console.log("Error writing sketch version to database"); + }); + }); +} + +function sendTime(destination, sensor, gw) { + var payload = new Date().getTime(); + var command = C_INTERNAL; + var acknowledge = 0; // no ack + var type = I_TIME; + var td = encode(destination, sensor, command, acknowledge, type, payload); + console.log('-> ' + td.toString()); + gw.write(td); +} + +function sendNextAvailableSensorId(db, gw) { + db.collection('node', function(err, c) { + c.find({ + $query: { }, + $orderby: { + 'id': 1 + } + }).toArray(function(err, results) { + if (err) + console.log('Error finding nodes'); + var id = 1; + for (var i = 0; i < results.length; i++) + if (results[i].id > i + 1) { + id = i + 1; + break; + } + if (id < 255) { + c.save({ + 'id': id + }, function(err, result) { + if (err) + console.log('Error writing node to database'); + var destination = BROADCAST_ADDRESS; + var sensor = NODE_SENSOR_ID; + var command = C_INTERNAL; + var acknowledge = 0; // no ack + var type = I_ID_RESPONSE; + var payload = id; + var td = encode(destination, sensor, command, acknowledge, type, payload); + console.log('-> ' + td.toString()); + gw.write(td); + }); + } + }); + }); +} + +function sendConfig(destination, gw) { + var payload = "M"; + var sensor = NODE_SENSOR_ID; + var command = C_INTERNAL; + var acknowledge = 0; // no ack + var type = I_CONFIG; + var td = encode(destination, sensor, command, acknowledge, type, payload); + console.log('-> ' + td.toString()); + gw.write(td); +} + +function sendFirmwareConfigResponse(destination, fwtype, fwversion, db, gw) { + // keep track of type/versin info for each node + // at the same time update the last modified date + // could be used to remove nodes not seen for a long time etc. + db.collection('node', function(err, c) { + c.update({ + 'id': destination + }, { + $set: { + 'type': fwtype, + 'version': fwversion, + 'reboot': 0 + } + }, { + upsert: true + }, function(err, result) { + if (err) + console.log("Error writing node type and version to database"); + }); + }); + if (fwtype == 0xFFFF) { + // sensor does not know which type / blank EEPROM + // take predefined type (ideally selected in UI prior to connection of new sensor) + if (fwDefaultType == 0xFFFF) + throw new Error('No default sensor type defined'); + fwtype = fwDefaultType; + } + db.collection('firmware', function(err, c) { + c.findOne({ + $query: { + 'type': fwtype + }, + $orderby: { + 'version': -1 + } + }, function(err, result) { + if (err) + console.log('Error finding firmware for type ' + fwtype); + else if (!result) + console.log('No firmware found for type ' + fwtype); + else { + var payload = []; + pushWord(payload, result.type); + pushWord(payload, result.version); + pushWord(payload, result.blocks); + pushWord(payload, result.crc); + var sensor = NODE_SENSOR_ID; + var command = C_STREAM; + var acknowledge = 0; // no ack + var type = ST_FIRMWARE_CONFIG_RESPONSE; + var td = encode(destination, sensor, command, acknowledge, type, payload); + console.log('-> ' + td.toString()); + gw.write(td); + } + }); + }); +} + +function sendFirmwareResponse(destination, fwtype, fwversion, fwblock, db, gw) { + db.collection('firmware', function(err, c) { + c.findOne({ + 'type': fwtype, + 'version': fwversion + }, function(err, result) { + if (err) + console.log('Error finding firmware version ' + fwversion + ' for type ' + fwtype); + var payload = []; + pushWord(payload, result.type); + pushWord(payload, result.version); + pushWord(payload, fwblock); + for (var i = 0; i < FIRMWARE_BLOCK_SIZE; i++) + payload.push(result.data[fwblock * FIRMWARE_BLOCK_SIZE + i]); + var sensor = NODE_SENSOR_ID; + var command = C_STREAM; + var acknowledge = 0; // no ack + var type = ST_FIRMWARE_RESPONSE; + var td = encode(destination, sensor, command, acknowledge, type, payload); + console.log('-> ' + td.toString()); + gw.write(td); + }); + }); +} + +function saveRebootRequest(destination, db) { + db.collection('node', function(err, c) { + c.update({ + 'id': destination + }, { + $set: { + 'reboot': 1 + } + }, function(err, result) { + if (err) + console.log("Error writing reboot request to database"); + }); + }); +} + +function checkRebootRequest(destination, db, gw) { + db.collection('node', function(err, c) { + c.find({ + 'id': destination + }, function(err, item) { + if (err) + console.log('Error checking reboot request'); + else if (item.reboot == 1) + sendRebootMessage(destination, gw); + }); + }); +} + +function sendRebootMessage(destination, gw) { + var sensor = NODE_SENSOR_ID; + var command = C_INTERNAL; + var acknowledge = 0; // no ack + var type = I_REBOOT; + var payload = ""; + var td = encode(destination, sensor, command, acknowledge, type, payload); + console.log('-> ' + td.toString()); + gw.write(td); +} + +function rfReceived(data, db, gw) { + if ((data != null) && (data != "")) { + console.log('<- ' + data); + // decoding message + var datas = data.toString().split(";"); + var sender = +datas[0]; + var sensor = +datas[1]; + var command = +datas[2]; + var type = +datas[3]; + var rawpayload = datas[4].trim(); + var payload; + if (command == C_STREAM) { + payload = []; + for (var i = 0; i < rawpayload.length; i+=2) + payload.push(parseInt(rawpayload.substring(i, i + 2), 16)); + } else { + payload = rawpayload; + } + // decision on appropriate response + switch (command) { + case C_PRESENTATION: + if (sensor == NODE_SENSOR_ID) + saveProtocol(sender, payload, db); + saveSensor(sender, sensor, type, db); + break; + case C_SET: + saveValue(sender, sensor, type, payload, db); + break; + case C_REQ: + break; + case C_INTERNAL: + switch (type) { + case I_BATTERY_LEVEL: + saveBatteryLevel(sender, payload, db); + break; + case I_TIME: + sendTime(sender, sensor, gw); + break; + case I_VERSION: + break; + case I_ID_REQUEST: + sendNextAvailableSensorId(db, gw); + break; + case I_ID_RESPONSE: + break; + case I_INCLUSION_MODE: + break; + case I_CONFIG: + sendConfig(sender, gw); + break; + case I_PING: + break; + case I_PING_ACK: + break; + case I_LOG_MESSAGE: + break; + case I_CHILDREN: + break; + case I_SKETCH_NAME: + saveSketchName(sender, payload, db); + break; + case I_SKETCH_VERSION: + saveSketchVersion(sender, payload, db); + break; + case I_REBOOT: + break; + } + break; + case C_STREAM: + switch (type) { + case ST_FIRMWARE_CONFIG_REQUEST: + var fwtype = pullWord(payload, 0); + var fwversion = pullWord(payload, 2); + sendFirmwareConfigResponse(sender, fwtype, fwversion, db, gw); + break; + case ST_FIRMWARE_CONFIG_RESPONSE: + break; + case ST_FIRMWARE_REQUEST: + var fwtype = pullWord(payload, 0); + var fwversion = pullWord(payload, 2); + var fwblock = pullWord(payload, 4); + sendFirmwareResponse(sender, fwtype, fwversion, fwblock, db, gw); + break; + case ST_FIRMWARE_RESPONSE: + break; + case ST_SOUND: + break; + case ST_IMAGE: + break; + } + break; + } + checkRebootRequest(sender, db, gw); + } +} + +var dbc = require('mongodb').MongoClient; +dbc.connect('mongodb://' + dbAddress + ':' + dbPort + '/' + dbName, function(err, db) { + if(err) { + console.log('Error connecting to database at mongodb://' + dbAddress + ':' + dbPort + '/' + dbName); + return; + } + console.log('Connected to database at mongodb://' + dbAddress + ':' + dbPort + '/' + dbName); + db.createCollection('node', function(err, collection) { }); + db.createCollection('firmware', function(err, collection) { }); + + // ToDo : check for new hex files / only load if new / get type and version from filename + for (var i = 0; i < fwHexFiles.length; i++) + loadFirmware(i, 1, fwHexFiles[i], db); + + var gw; + if (gwType == 'Ethernet') { + gw = require('net').Socket(); + gw.connect(gwPort, gwAddress); + gw.setEncoding('ascii'); + gw.on('connect', function() { + console.log('connected to ethernet gateway at ' + gwAddress + ":" + gwPort); + }).on('data', function(rd) { + var rds = rd.toString().split('\n'); + for (var i = 0; i < rds.length; i++) + rfReceived(rds[i].trim(), db, gw); + }).on('end', function() { + console.log('disconnected from gateway'); + }).on('error', function() { + console.log('connection error - trying to reconnect'); + gw.connect(gwPort, gwAddress); + gw.setEncoding('ascii'); + }); + } else if (gwType == 'Serial') { + gw = require('serialport').SerialPort(gwPort, { baudrate: gwBaud }, false); + gw.open(); + gw.on('open', function() { + console.log('connected to serial gateway at ' + gwPort); + }).on('data', function(rd) { + var rds = rd.toString().split('\n'); + for (var i = 0; i < rds.length; i++) + rfReceived(rds[i].trim(), db, gw); + }).on('end', function() { + console.log('disconnected from gateway'); + }).on('error', function() { + console.log('connection error - trying to reconnect'); + gw.open(); + }); + } else { + throw new Error('unknown Gateway type'); + } +}); + diff --git a/NodeJsController/Reboot.js b/NodeJsController/Reboot.js new file mode 100644 index 0000000..2afb2b9 --- /dev/null +++ b/NodeJsController/Reboot.js @@ -0,0 +1,28 @@ +var NodeIdToReboot = 1; + +const dbAddress = '127.0.0.1'; +const dbPort = 27017; +const dbName = 'MySensorsDb'; + +var dbc = require('mongodb').MongoClient; +dbc.connect('mongodb://' + dbAddress + ':' + dbPort + '/' + dbName, function(err, db) { + if (err) { + console.log('Error connecting to database at mongodb://' + dbAddress + ':' + dbPort + '/' + dbName); + } else { + db.collection('node', function(err, c) { + c.update({ + 'id': NodeIdToReboot + }, { + $set: { + 'reboot': 1 + } + }, function(err, result) { + if (err) + console.log("Error writing reboot request to database"); + else + console.log("Reboot request saved to database"); + }); + }); + } +}); + diff --git a/NodeJsController/package.json b/NodeJsController/package.json new file mode 100644 index 0000000..f9ec6ff --- /dev/null +++ b/NodeJsController/package.json @@ -0,0 +1,9 @@ +{ + "name": "NodeJsController", + "version": "0.0.1", + "description": "MySensors Controller based on Node JS", + "dependencies": { + "net": "~1.0.2", + "mongodb": "~1.4.7" + } +} diff --git a/libraries/MySensors/MyGateway.cpp b/libraries/MySensors/MyGateway.cpp index 9fde171..114a8da 100644 --- a/libraries/MySensors/MyGateway.cpp +++ b/libraries/MySensors/MyGateway.cpp @@ -105,10 +105,22 @@ void MyGateway::checkInclusionFinished() { } } +uint8_t MyGateway::h2i(char c) { + uint8_t i = 0; + if (c <= '9') + i += c - '0'; + else if (c >= 'a') + i += c - 'a' + 10; + else + i += c - 'A' + 10; + return i; +} void MyGateway::parseAndSend(char *commandBuffer) { boolean ok = false; char *str, *p, *value=NULL; + uint8_t bvalue[MAX_PAYLOAD]; + uint8_t blen = 0; int i = 0; uint16_t destination = 0; uint8_t sensor = 0; @@ -138,7 +150,18 @@ void MyGateway::parseAndSend(char *commandBuffer) { type = atoi(str); break; case 5: // Variable value - value = str; + if (command == C_STREAM) { + blen = 0; + uint8_t val; + while (*str) { + val = h2i(*str++) << 4; + val += h2i(*str++); + bvalue[blen] = val; + blen++; + } + } else { + value = str; + } break; } i++; @@ -163,6 +186,10 @@ void MyGateway::parseAndSend(char *commandBuffer) { mSetRequestAck(msg,ack?1:0); mSetAck(msg,false); msg.set(value); + if (command == C_STREAM) + msg.set(bvalue, blen); + else + msg.set(value); ok = sendRoute(msg); if (!ok) { errBlink(1); diff --git a/libraries/MySensors/MyGateway.h b/libraries/MySensors/MyGateway.h index 185d933..e527bc3 100644 --- a/libraries/MySensors/MyGateway.h +++ b/libraries/MySensors/MyGateway.h @@ -68,6 +68,8 @@ class MyGateway : public MySensor uint8_t pinTx; uint8_t pinEr; + uint8_t h2i(char c); + void serial(const char *fmt, ... ); void serial(MyMessage &msg); void interruptStartInclusion(); diff --git a/libraries/MySensors/MyMessage.cpp b/libraries/MySensors/MyMessage.cpp index 6f973bb..3e4d17c 100644 --- a/libraries/MySensors/MyMessage.cpp +++ b/libraries/MySensors/MyMessage.cpp @@ -33,6 +33,30 @@ const char* MyMessage::getString() const { } } +// handles single character hex (0 - 15) +char MyMessage::i2h(uint8_t i) const { + uint8_t k = i & 0x0F; + if (k <= 9) + return '0' + k; + else + return 'A' + k - 10; +} + +char* MyMessage::getStream(char *buffer) const { + uint8_t cmd = miGetCommand(); + if ((cmd == C_STREAM) && (buffer != NULL)) { + for (uint8_t i = 0; i < miGetLength(); i++) + { + buffer[i * 2] = i2h(data[i] >> 4); + buffer[(i * 2) + 1] = i2h(data[i]); + } + buffer[miGetLength() * 2] = '\0'; + return buffer; + } else { + return NULL; + } +} + char* MyMessage::getString(char *buffer) const { uint8_t payloadType = miGetPayloadType(); if (payloadType == P_STRING) { @@ -57,10 +81,7 @@ char* MyMessage::getString(char *buffer) const { ultoa(ulValue, buffer, 10); break; case P_CUSTOM: - // TODO: Ok, what do we do here? We should probably convert this to hex - // Mostly gateway interested in this so we do the special handling of this - // over there. - + return getStream(buffer); break; } return buffer; diff --git a/libraries/MySensors/MyMessage.h b/libraries/MySensors/MyMessage.h index 2453531..67ff9b5 100644 --- a/libraries/MySensors/MyMessage.h +++ b/libraries/MySensors/MyMessage.h @@ -12,11 +12,15 @@ #ifndef MyMessage_h #define MyMessage_h -#include +#ifdef __cplusplus +#include +#include +#include +#endif #define PROTOCOL_VERSION 2 #define MAX_MESSAGE_LENGTH 32 -#define HEADER_SIZE 8 +#define HEADER_SIZE 7 #define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE) // Message types @@ -41,7 +45,8 @@ typedef enum { typedef enum { I_BATTERY_LEVEL, I_TIME, I_VERSION, I_ID_REQUEST, I_ID_RESPONSE, I_INCLUSION_MODE, I_CONFIG, I_PING, I_PING_ACK, - I_LOG_MESSAGE, I_CHILDREN, I_SKETCH_NAME, I_SKETCH_VERSION + I_LOG_MESSAGE, I_CHILDREN, I_SKETCH_NAME, I_SKETCH_VERSION, + I_REBOOT } internal; // Type of sensor (for presentation message) @@ -53,7 +58,8 @@ typedef enum { // Type of data stream (for streamed message) typedef enum { - ST_FIRMWARE, ST_SOUND, ST_IMAGE + ST_FIRMWARE_CONFIG_REQUEST, ST_FIRMWARE_CONFIG_RESPONSE, ST_FIRMWARE_REQUEST, ST_FIRMWARE_RESPONSE, + ST_SOUND, ST_IMAGE } stream; typedef enum { @@ -96,6 +102,8 @@ typedef enum { // internal access for special fields +#define miGetCommand() BF_GET(command_ack_payload, 0, 3) + #define miSetLength(_length) BF_SET(version_length, _length, 3, 5) #define miGetLength() BF_GET(version_length, 3, 5) @@ -109,7 +117,7 @@ typedef enum { #define miGetPayloadType() BF_GET(command_ack_payload, 5, 3) - +#ifdef __cplusplus class MyMessage { public: @@ -118,11 +126,14 @@ public: MyMessage(uint8_t sensor, uint8_t type); + char i2h(uint8_t i) const; + /** * If payload is something else than P_STRING you can have the payload value converted * into string representation by supplying a buffer with the minimum size of * 2*MAX_PAYLOAD+1. This is to be able to fit hex-conversion of a full binary payload. */ + char* getStream(char *buffer) const; char* getString(char *buffer) const; const char* getString() const; void* getCustom() const; @@ -152,6 +163,13 @@ public: MyMessage& set(unsigned int value); MyMessage& set(int value); +#else + +typedef union { +struct +{ + +#endif uint8_t version_length; // 3 bit - Protocol version // 5 bit - Length of payload @@ -176,6 +194,12 @@ public: int iValue; char data[MAX_PAYLOAD + 1]; } __attribute__((packed)); +#ifdef __cplusplus } __attribute__((packed)); +#else +}; +uint8_t array[HEADER_SIZE + MAX_PAYLOAD + 1]; +} __attribute__((packed)) MyMessage; +#endif #endif diff --git a/libraries/MySensors/MySensor.cpp b/libraries/MySensors/MySensor.cpp index 7c2933f..0308f6c 100644 --- a/libraries/MySensors/MySensor.cpp +++ b/libraries/MySensors/MySensor.cpp @@ -328,6 +328,10 @@ boolean MySensor::process() { bool isMetric; switch (type) { + case I_REBOOT: + wdt_enable(WDTO_15MS); + for (;;); + break; case I_ID_RESPONSE: if (nc.nodeId == AUTO) { nc.nodeId = msg.getByte(); diff --git a/libraries/MySensors/MySensor.h b/libraries/MySensors/MySensor.h index 38f16e4..7db57b6 100644 --- a/libraries/MySensors/MySensor.h +++ b/libraries/MySensors/MySensor.h @@ -15,15 +15,19 @@ #include "Version.h" // Auto generated by bot #include "MyConfig.h" #include "MyMessage.h" -#include #include -#include #include #include +#include #include + +#ifdef __cplusplus +#include +#include #include "utility/LowPower.h" #include "utility/RF24.h" #include "utility/RF24_config.h" +#endif #ifdef DEBUG #define debug(x,...) debugPrint(x, ##__VA_ARGS__) @@ -46,7 +50,11 @@ #define EEPROM_DISTANCE_ADDRESS (EEPROM_PARENT_NODE_ID_ADDRESS+1) #define EEPROM_ROUTES_ADDRESS (EEPROM_DISTANCE_ADDRESS+1) // Where to start storing routing information in EEPROM. Will allocate 256 bytes. #define EEPROM_CONTROLLER_CONFIG_ADDRESS (EEPROM_ROUTES_ADDRESS+256) // Location of controller sent configuration (we allow one payload of config data from controller) -#define EEPROM_LOCAL_CONFIG_ADDRESS (EEPROM_CONTROLLER_CONFIG_ADDRESS+24) // First free address for sketch static configuration +#define EEPROM_FIRMWARE_TYPE_ADDRESS (EEPROM_CONTROLLER_CONFIG_ADDRESS+24) +#define EEPROM_FIRMWARE_VERSION_ADDRESS (EEPROM_FIRMWARE_TYPE_ADDRESS+2) +#define EEPROM_FIRMWARE_BLOCKS_ADDRESS (EEPROM_FIRMWARE_VERSION_ADDRESS+2) +#define EEPROM_FIRMWARE_CRC_ADDRESS (EEPROM_FIRMWARE_BLOCKS_ADDRESS+2) +#define EEPROM_LOCAL_CONFIG_ADDRESS (EEPROM_FIRMWARE_CRC_ADDRESS+2) // First free address for sketch static configuration // This is the nodeId for sensor net gateway receiver sketch (where all sensors should send their data). // This is also act as base value for sensor nodeId @@ -73,8 +81,7 @@ struct ControllerConfig { uint8_t isMetric; }; - - +#ifdef __cplusplus class MySensor : public RF24 { public: @@ -266,5 +273,6 @@ class MySensor : public RF24 void removeChildRoute(uint8_t childId); void internalSleep(unsigned long ms); }; +#endif #endif diff --git a/libraries/UIPEthernet/utility/Enc28J60Network.cpp b/libraries/UIPEthernet/utility/Enc28J60Network.cpp deleted file mode 100644 index baf5b11..0000000 --- a/libraries/UIPEthernet/utility/Enc28J60Network.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* - Enc28J60Network.h - UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface. - - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - based on enc28j60.c file from the AVRlib library by Pascal Stang. - For AVRlib See http://www.procyonengineering.com/ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#include "Enc28J60Network.h" -#include "Arduino.h" - -extern "C" { -#include -#include "enc28j60.h" -#include "uip.h" -} - -#ifdef ENC28J60DEBUG -#include "HardwareSerial.h" -#endif - -// set CS to 0 = active -#define CSACTIVE digitalWrite(ENC28J60_CONTROL_CS, LOW) -// set CS to 1 = passive -#define CSPASSIVE digitalWrite(ENC28J60_CONTROL_CS, HIGH) -// -#define waitspi() while(!(SPSR&(1< ip checksum for theses bytes=f7f9 - // in binary these poitions are:11 0000 0011 1111 - // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 - //TODO define specific pattern to receive dhcp-broadcast packages instead of setting ERFCON_BCEN! - writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN); - writeRegPair(EPMM0, 0x303f); - writeRegPair(EPMCSL, 0xf7f9); - // - // - // do bank 2 stuff - // enable MAC receive - // and bring MAC out of reset (writes 0x00 to MACON2) - writeRegPair(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); - // enable automatic padding to 60bytes and CRC operations - writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); - // set inter-frame gap (non-back-to-back) - writeRegPair(MAIPGL, 0x0C12); - // set inter-frame gap (back-to-back) - writeReg(MABBIPG, 0x12); - // Set the maximum packet size which the controller will accept - // Do not send packets longer than MAX_FRAMELEN: - writeRegPair(MAMXFLL, MAX_FRAMELEN); - // do bank 3 stuff - // write MAC address - // NOTE: MAC address in ENC28J60 is byte-backward - writeReg(MAADR5, macaddr[0]); - writeReg(MAADR4, macaddr[1]); - writeReg(MAADR3, macaddr[2]); - writeReg(MAADR2, macaddr[3]); - writeReg(MAADR1, macaddr[4]); - writeReg(MAADR0, macaddr[5]); - // no loopback of transmitted frames - phyWrite(PHCON2, PHCON2_HDLDIS); - // switch to bank 0 - setBank(ECON1); - // enable interrutps - writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); - // enable packet reception - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); - //Configure leds - phyWrite(PHLCON,0x476); -} - -memhandle -Enc28J60Network::receivePacket() -{ - uint16_t rxstat; - uint16_t len; - // check if a packet has been received and buffered - //if( !(readReg(EIR) & EIR_PKTIF) ){ - // The above does not work. See Rev. B4 Silicon Errata point 6. - if (readReg(EPKTCNT) != 0) - { - uint16_t readPtr = nextPacketPtr+6; - // Set the read pointer to the start of the received packet - writeRegPair(ERDPTL, nextPacketPtr); - // read the next packet pointer - nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0); - nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; - // read the packet length (see datasheet page 43) - len = readOp(ENC28J60_READ_BUF_MEM, 0); - len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; - len -= 4; //remove the CRC count - // read the receive status (see datasheet page 43) - rxstat = readOp(ENC28J60_READ_BUF_MEM, 0); - rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; - // decrement the packet counter indicate we are done with this packet - writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); - // check CRC and symbol errors (see datasheet page 44, table 7-3): - // The ERXFCON.CRCEN is set by default. Normally we should not - // need to check this. - if ((rxstat & 0x80) != 0) - { - receivePkt.begin = readPtr; - receivePkt.size = len; - return UIP_RECEIVEBUFFERHANDLE; - } - // Move the RX read pointer to the start of the next received packet - // This frees the memory we just read out - setERXRDPT(); - } - return (NOBLOCK); -} - -void -Enc28J60Network::setERXRDPT() -{ - writeRegPair(ERXRDPTL, nextPacketPtr == RXSTART_INIT ? RXSTOP_INIT : nextPacketPtr-1); -} - -memaddress -Enc28J60Network::blockSize(memhandle handle) -{ - return handle == UIP_RECEIVEBUFFERHANDLE ? receivePkt.size : blocks[handle].size; -} - -void -Enc28J60Network::sendPacket(memhandle handle) -{ - memblock *packet = &blocks[handle]; - uint16_t start = packet->begin-1; - uint16_t end = start + packet->size; - - // backup data at control-byte position - uint8_t data = readByte(start); - // write control-byte (if not 0 anyway) - if (data) - writeByte(start, 0); - -#ifdef ENC28J60DEBUG - Serial.print("sendPacket("); - Serial.print(handle); - Serial.print(") ["); - Serial.print(start); - Serial.print("-"); - Serial.print(end); - Serial.println("]:"); - for (uint16_t i=start; i<=end; i++) - { - Serial.print(readByte(i),HEX); - Serial.print(" "); - } - Serial.println(); -#endif - - // TX start - writeRegPair(ETXSTL, start); - // Set the TXND pointer to correspond to the packet size given - writeRegPair(ETXNDL, end); - // send the contents of the transmit buffer onto the network - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); - // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. - if( (readReg(EIR) & EIR_TXERIF) ) - { - writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS); - } - - //restore data on control-byte position - if (data) - writeByte(start, data); -} - -uint16_t -Enc28J60Network::setReadPtr(memhandle handle, memaddress position, uint16_t len) -{ - memblock *packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle]; - memaddress start = packet->begin + position; - - writeRegPair(ERDPTL, start); - - if (len > packet->size - position) - len = packet->size - position; - return len; -} - -uint16_t -Enc28J60Network::readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) -{ - len = setReadPtr(handle, position, len); - readBuffer(len, buffer); - return len; -} - -uint16_t -Enc28J60Network::writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) -{ - memblock *packet = &blocks[handle]; - uint16_t start = packet->begin + position; - - writeRegPair(EWRPTL, start); - - if (len > packet->size - position) - len = packet->size - position; - writeBuffer(len, buffer); - return len; -} - -uint8_t Enc28J60Network::readByte(uint16_t addr) -{ - writeRegPair(ERDPTL, addr); - - CSACTIVE; - // issue read command - SPDR = ENC28J60_READ_BUF_MEM; - waitspi(); - // read data - SPDR = 0x00; - waitspi(); - CSPASSIVE; - return (SPDR); -} - -void Enc28J60Network::writeByte(uint16_t addr, uint8_t data) -{ - writeRegPair(EWRPTL, addr); - - CSACTIVE; - // issue write command - SPDR = ENC28J60_WRITE_BUF_MEM; - waitspi(); - // write data - SPDR = data; - waitspi(); - CSPASSIVE; -} - -void -Enc28J60Network::copyPacket(memhandle dest_pkt, memaddress dest_pos, memhandle src_pkt, memaddress src_pos, uint16_t len) -{ - memblock *dest = &blocks[dest_pkt]; - memblock *src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt]; - memblock_mv_cb(dest->begin+dest_pos,src->begin+src_pos,len); - // Move the RX read pointer to the start of the next received packet - // This frees the memory we just read out - setERXRDPT(); -} - -void -Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len) -{ - //as ENC28J60 DMA is unable to copy single bytes: - if (len == 1) - { - writeByte(dest,readByte(src)); - } - else - { - // calculate address of last byte - len += src - 1; - - /* 1. Appropriately program the EDMAST, EDMAND - and EDMADST register pairs. The EDMAST - registers should point to the first byte to copy - from, the EDMAND registers should point to the - last byte to copy and the EDMADST registers - should point to the first byte in the destination - range. The destination range will always be - linear, never wrapping at any values except from - 8191 to 0 (the 8-Kbyte memory boundary). - Extreme care should be taken when - programming the start and end pointers to - prevent a never ending DMA operation which - would overwrite the entire 8-Kbyte buffer. - */ - writeRegPair(EDMASTL, src); - writeRegPair(EDMADSTL, dest); - - if ((src <= RXSTOP_INIT)&& (len > RXSTOP_INIT))len -= (RXSTOP_INIT-RXSTART_INIT); - writeRegPair(EDMANDL, len); - - /* - 2. If an interrupt at the end of the copy process is - desired, set EIE.DMAIE and EIE.INTIE and - clear EIR.DMAIF. - - 3. Verify that ECON1.CSUMEN is clear. */ - writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN); - - /* 4. Start the DMA copy by setting ECON1.DMAST. */ - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST); - - // wait until runnig DMA is completed - while (readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST); - } -} - -void -Enc28J60Network::freePacket() -{ - setERXRDPT(); -} - -uint8_t -Enc28J60Network::readOp(uint8_t op, uint8_t address) -{ - CSACTIVE; - // issue read command - SPDR = op | (address & ADDR_MASK); - waitspi(); - // read data - SPDR = 0x00; - waitspi(); - // do dummy read if needed (for mac and mii, see datasheet page 29) - if(address & 0x80) - { - SPDR = 0x00; - waitspi(); - } - // release CS - CSPASSIVE; - return(SPDR); -} - -void -Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data) -{ - CSACTIVE; - // issue write command - SPDR = op | (address & ADDR_MASK); - waitspi(); - // write data - SPDR = data; - waitspi(); - CSPASSIVE; -} - -void -Enc28J60Network::readBuffer(uint16_t len, uint8_t* data) -{ - CSACTIVE; - // issue read command - SPDR = ENC28J60_READ_BUF_MEM; - waitspi(); - while(len) - { - len--; - // read data - SPDR = 0x00; - waitspi(); - *data = SPDR; - data++; - } - //*data='\0'; - CSPASSIVE; -} - -void -Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data) -{ - CSACTIVE; - // issue write command - SPDR = ENC28J60_WRITE_BUF_MEM; - waitspi(); - while(len) - { - len--; - // write data - SPDR = *data; - data++; - waitspi(); - } - CSPASSIVE; -} - -void -Enc28J60Network::setBank(uint8_t address) -{ - // set the bank (if needed) - if((address & BANK_MASK) != bank) - { - // set the bank - writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0)); - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5); - bank = (address & BANK_MASK); - } -} - -uint8_t -Enc28J60Network::readReg(uint8_t address) -{ - // set the bank - setBank(address); - // do the read - return readOp(ENC28J60_READ_CTRL_REG, address); -} - -void -Enc28J60Network::writeReg(uint8_t address, uint8_t data) -{ - // set the bank - setBank(address); - // do the write - writeOp(ENC28J60_WRITE_CTRL_REG, address, data); -} - -void -Enc28J60Network::writeRegPair(uint8_t address, uint16_t data) -{ - // set the bank - setBank(address); - // do the write - writeOp(ENC28J60_WRITE_CTRL_REG, address, (data&0xFF)); - writeOp(ENC28J60_WRITE_CTRL_REG, address+1, (data) >> 8); -} - -void -Enc28J60Network::phyWrite(uint8_t address, uint16_t data) -{ - // set the PHY register address - writeReg(MIREGADR, address); - // write the PHY data - writeRegPair(MIWRL, data); - // wait until the PHY write completes - while(readReg(MISTAT) & MISTAT_BUSY){ - delayMicroseconds(15); - } -} - -void -Enc28J60Network::clkout(uint8_t clk) -{ - //setup clkout: 2 is 12.5MHz: - writeReg(ECOCON, clk & 0x7); -} - -// read the revision of the chip: -uint8_t -Enc28J60Network::getrev(void) -{ - return(readReg(EREVID)); -} - -uint16_t -Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len) -{ - uint16_t t; - len = setReadPtr(handle, pos, len)-1; - CSACTIVE; - // issue read command - SPDR = ENC28J60_READ_BUF_MEM; - waitspi(); - uint16_t i; - for (i = 0; i < len; i+=2) - { - // read data - SPDR = 0x00; - waitspi(); - t = SPDR << 8; - SPDR = 0x00; - waitspi(); - t += SPDR; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - if(i == len) { - SPDR = 0x00; - waitspi(); - t = (SPDR << 8) + 0; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - CSPASSIVE; - - /* Return sum in host byte order. */ - return sum; -} diff --git a/libraries/UIPEthernet/utility/Enc28J60Network.h b/libraries/UIPEthernet/utility/Enc28J60Network.h deleted file mode 100644 index 96f5600..0000000 --- a/libraries/UIPEthernet/utility/Enc28J60Network.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Enc28J60Network.h - UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface. - - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - inspired by enc28j60.c file from the AVRlib library by Pascal Stang. - For AVRlib See http://www.procyonengineering.com/ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#ifndef ENC28J60NETWORK_H_ -#define ENC28J60NETWORK_H_ - -#include "mempool.h" - -#define ENC28J60_CONTROL_CS SS -#define SPI_MOSI MOSI -#define SPI_MISO MISO -#define SPI_SCK SCK -#define SPI_SS SS - -#define UIP_RECEIVEBUFFERHANDLE 0xff - -//#define ENC28J60DEBUG - -/* - * Empfangen von ip-header, arp etc... - * wenn tcp/udp -> tcp/udp-callback -> assign new packet to connection - */ - -class Enc28J60Network : public MemoryPool -{ - -private: - uint16_t nextPacketPtr; - uint8_t bank; - - struct memblock receivePkt; - - uint8_t readOp(uint8_t op, uint8_t address); - void writeOp(uint8_t op, uint8_t address, uint8_t data); - uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len); - void setERXRDPT(); - void readBuffer(uint16_t len, uint8_t* data); - void writeBuffer(uint16_t len, uint8_t* data); - uint8_t readByte(uint16_t addr); - void writeByte(uint16_t addr, uint8_t data); - void setBank(uint8_t address); - uint8_t readReg(uint8_t address); - void writeReg(uint8_t address, uint8_t data); - void writeRegPair(uint8_t address, uint16_t data); - void phyWrite(uint8_t address, uint16_t data); - void clkout(uint8_t clk); - uint8_t getrev(void); - -protected: - void memblock_mv_cb(memaddress dest, memaddress src, memaddress size); - -public: - Enc28J60Network(); - void init(uint8_t* macaddr); - memhandle receivePacket(); - void freePacket(); - memaddress blockSize(memhandle handle); - void sendPacket(memhandle handle); - uint16_t readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); - uint16_t writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); - void copyPacket(memhandle dest, memaddress dest_pos, memhandle src, memaddress src_pos, uint16_t len); - uint16_t chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len); -}; - -#endif /* ENC28J60NETWORK_H_ */ diff --git a/libraries/UIPEthernet/utility/clock-arch.c b/libraries/UIPEthernet/utility/clock-arch.c deleted file mode 100644 index 13b886d..0000000 --- a/libraries/UIPEthernet/utility/clock-arch.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - clock-arch.c - Arduino implementation of uIP clock device. - Copyright (c) 2010 Adam Nielsen - All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "clock-arch.h" - -clock_time_t -clock_time(void) -{ - return (clock_time_t) millis(); -} diff --git a/libraries/UIPEthernet/utility/clock-arch.h b/libraries/UIPEthernet/utility/clock-arch.h deleted file mode 100644 index d7a828b..0000000 --- a/libraries/UIPEthernet/utility/clock-arch.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - clock-arch.h - Arduino implementation of uIP clock device. - Copyright (c) 2010 Adam Nielsen - All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef clock_h_ -#define clock_h_ - -typedef unsigned long clock_time_t; -#define CLOCK_CONF_SECOND 1000 - -#endif diff --git a/libraries/UIPEthernet/utility/enc28j60.h b/libraries/UIPEthernet/utility/enc28j60.h deleted file mode 100644 index 3a45c59..0000000 --- a/libraries/UIPEthernet/utility/enc28j60.h +++ /dev/null @@ -1,257 +0,0 @@ -/***************************************************************************** -* -* Title : Microchip ENC28J60 Ethernet Interface Driver -* Author : Pascal Stang (c)2005 -* Modified by Norbert Truchsess -* Copyright: GPL V2 -* -*This driver provides initialization and transmit/receive -*functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. -*This chip is novel in that it is a full MAC+PHY interface all in a 28-pin -*chip, using an SPI interface to the host processor. -* -* -*****************************************************************************/ - -#ifndef ENC28J60_H -#define ENC28J60_H -#include - -// ENC28J60 Control Registers -// Control register definitions are a combination of address, -// bank number, and Ethernet/MAC/PHY indicator bits. -// - Register address (bits 0-4) -// - Bank number (bits 5-6) -// - MAC/PHY indicator (bit 7) -#define ADDR_MASK 0x1F -#define BANK_MASK 0x60 -#define SPRD_MASK 0x80 -// All-bank registers -#define EIE 0x1B -#define EIR 0x1C -#define ESTAT 0x1D -#define ECON2 0x1E -#define ECON1 0x1F -// Bank 0 registers -#define ERDPTL (0x00|0x00) -#define ERDPTH (0x01|0x00) -#define EWRPTL (0x02|0x00) -#define EWRPTH (0x03|0x00) -#define ETXSTL (0x04|0x00) -#define ETXSTH (0x05|0x00) -#define ETXNDL (0x06|0x00) -#define ETXNDH (0x07|0x00) -#define ERXSTL (0x08|0x00) -#define ERXSTH (0x09|0x00) -#define ERXNDL (0x0A|0x00) -#define ERXNDH (0x0B|0x00) -#define ERXRDPTL (0x0C|0x00) -#define ERXRDPTH (0x0D|0x00) -#define ERXWRPTL (0x0E|0x00) -#define ERXWRPTH (0x0F|0x00) -#define EDMASTL (0x10|0x00) -#define EDMASTH (0x11|0x00) -#define EDMANDL (0x12|0x00) -#define EDMANDH (0x13|0x00) -#define EDMADSTL (0x14|0x00) -#define EDMADSTH (0x15|0x00) -#define EDMACSL (0x16|0x00) -#define EDMACSH (0x17|0x00) -// Bank 1 registers -#define EHT0 (0x00|0x20) -#define EHT1 (0x01|0x20) -#define EHT2 (0x02|0x20) -#define EHT3 (0x03|0x20) -#define EHT4 (0x04|0x20) -#define EHT5 (0x05|0x20) -#define EHT6 (0x06|0x20) -#define EHT7 (0x07|0x20) -#define EPMM0 (0x08|0x20) -#define EPMM1 (0x09|0x20) -#define EPMM2 (0x0A|0x20) -#define EPMM3 (0x0B|0x20) -#define EPMM4 (0x0C|0x20) -#define EPMM5 (0x0D|0x20) -#define EPMM6 (0x0E|0x20) -#define EPMM7 (0x0F|0x20) -#define EPMCSL (0x10|0x20) -#define EPMCSH (0x11|0x20) -#define EPMOL (0x14|0x20) -#define EPMOH (0x15|0x20) -#define EWOLIE (0x16|0x20) -#define EWOLIR (0x17|0x20) -#define ERXFCON (0x18|0x20) -#define EPKTCNT (0x19|0x20) -// Bank 2 registers -#define MACON1 (0x00|0x40|0x80) -#define MACON2 (0x01|0x40|0x80) -#define MACON3 (0x02|0x40|0x80) -#define MACON4 (0x03|0x40|0x80) -#define MABBIPG (0x04|0x40|0x80) -#define MAIPGL (0x06|0x40|0x80) -#define MAIPGH (0x07|0x40|0x80) -#define MACLCON1 (0x08|0x40|0x80) -#define MACLCON2 (0x09|0x40|0x80) -#define MAMXFLL (0x0A|0x40|0x80) -#define MAMXFLH (0x0B|0x40|0x80) -#define MAPHSUP (0x0D|0x40|0x80) -#define MICON (0x11|0x40|0x80) -#define MICMD (0x12|0x40|0x80) -#define MIREGADR (0x14|0x40|0x80) -#define MIWRL (0x16|0x40|0x80) -#define MIWRH (0x17|0x40|0x80) -#define MIRDL (0x18|0x40|0x80) -#define MIRDH (0x19|0x40|0x80) -// Bank 3 registers -#define MAADR1 (0x00|0x60|0x80) -#define MAADR0 (0x01|0x60|0x80) -#define MAADR3 (0x02|0x60|0x80) -#define MAADR2 (0x03|0x60|0x80) -#define MAADR5 (0x04|0x60|0x80) -#define MAADR4 (0x05|0x60|0x80) -#define EBSTSD (0x06|0x60) -#define EBSTCON (0x07|0x60) -#define EBSTCSL (0x08|0x60) -#define EBSTCSH (0x09|0x60) -#define MISTAT (0x0A|0x60|0x80) -#define EREVID (0x12|0x60) -#define ECOCON (0x15|0x60) -#define EFLOCON (0x17|0x60) -#define EPAUSL (0x18|0x60) -#define EPAUSH (0x19|0x60) -// PHY registers -#define PHCON1 0x00 -#define PHSTAT1 0x01 -#define PHHID1 0x02 -#define PHHID2 0x03 -#define PHCON2 0x10 -#define PHSTAT2 0x11 -#define PHIE 0x12 -#define PHIR 0x13 -#define PHLCON 0x14 - -// ENC28J60 ERXFCON Register Bit Definitions -#define ERXFCON_UCEN 0x80 -#define ERXFCON_ANDOR 0x40 -#define ERXFCON_CRCEN 0x20 -#define ERXFCON_PMEN 0x10 -#define ERXFCON_MPEN 0x08 -#define ERXFCON_HTEN 0x04 -#define ERXFCON_MCEN 0x02 -#define ERXFCON_BCEN 0x01 -// ENC28J60 EIE Register Bit Definitions -#define EIE_INTIE 0x80 -#define EIE_PKTIE 0x40 -#define EIE_DMAIE 0x20 -#define EIE_LINKIE 0x10 -#define EIE_TXIE 0x08 -#define EIE_WOLIE 0x04 -#define EIE_TXERIE 0x02 -#define EIE_RXERIE 0x01 -// ENC28J60 EIR Register Bit Definitions -#define EIR_PKTIF 0x40 -#define EIR_DMAIF 0x20 -#define EIR_LINKIF 0x10 -#define EIR_TXIF 0x08 -#define EIR_WOLIF 0x04 -#define EIR_TXERIF 0x02 -#define EIR_RXERIF 0x01 -// ENC28J60 ESTAT Register Bit Definitions -#define ESTAT_INT 0x80 -#define ESTAT_LATECOL 0x10 -#define ESTAT_RXBUSY 0x04 -#define ESTAT_TXABRT 0x02 -#define ESTAT_CLKRDY 0x01 -// ENC28J60 ECON2 Register Bit Definitions -#define ECON2_AUTOINC 0x80 -#define ECON2_PKTDEC 0x40 -#define ECON2_PWRSV 0x20 -#define ECON2_VRPS 0x08 -// ENC28J60 ECON1 Register Bit Definitions -#define ECON1_TXRST 0x80 -#define ECON1_RXRST 0x40 -#define ECON1_DMAST 0x20 -#define ECON1_CSUMEN 0x10 -#define ECON1_TXRTS 0x08 -#define ECON1_RXEN 0x04 -#define ECON1_BSEL1 0x02 -#define ECON1_BSEL0 0x01 -// ENC28J60 MACON1 Register Bit Definitions -#define MACON1_LOOPBK 0x10 -#define MACON1_TXPAUS 0x08 -#define MACON1_RXPAUS 0x04 -#define MACON1_PASSALL 0x02 -#define MACON1_MARXEN 0x01 -// ENC28J60 MACON2 Register Bit Definitions -#define MACON2_MARST 0x80 -#define MACON2_RNDRST 0x40 -#define MACON2_MARXRST 0x08 -#define MACON2_RFUNRST 0x04 -#define MACON2_MATXRST 0x02 -#define MACON2_TFUNRST 0x01 -// ENC28J60 MACON3 Register Bit Definitions -#define MACON3_PADCFG2 0x80 -#define MACON3_PADCFG1 0x40 -#define MACON3_PADCFG0 0x20 -#define MACON3_TXCRCEN 0x10 -#define MACON3_PHDRLEN 0x08 -#define MACON3_HFRMLEN 0x04 -#define MACON3_FRMLNEN 0x02 -#define MACON3_FULDPX 0x01 -// ENC28J60 MICMD Register Bit Definitions -#define MICMD_MIISCAN 0x02 -#define MICMD_MIIRD 0x01 -// ENC28J60 MISTAT Register Bit Definitions -#define MISTAT_NVALID 0x04 -#define MISTAT_SCAN 0x02 -#define MISTAT_BUSY 0x01 -// ENC28J60 PHY PHCON1 Register Bit Definitions -#define PHCON1_PRST 0x8000 -#define PHCON1_PLOOPBK 0x4000 -#define PHCON1_PPWRSV 0x0800 -#define PHCON1_PDPXMD 0x0100 -// ENC28J60 PHY PHSTAT1 Register Bit Definitions -#define PHSTAT1_PFDPX 0x1000 -#define PHSTAT1_PHDPX 0x0800 -#define PHSTAT1_LLSTAT 0x0004 -#define PHSTAT1_JBSTAT 0x0002 -// ENC28J60 PHY PHCON2 Register Bit Definitions -#define PHCON2_FRCLINK 0x4000 -#define PHCON2_TXDIS 0x2000 -#define PHCON2_JABBER 0x0400 -#define PHCON2_HDLDIS 0x0100 - -// ENC28J60 Packet Control Byte Bit Definitions -#define PKTCTRL_PHUGEEN 0x08 -#define PKTCTRL_PPADEN 0x04 -#define PKTCTRL_PCRCEN 0x02 -#define PKTCTRL_POVERRIDE 0x01 - -// SPI operation codes -#define ENC28J60_READ_CTRL_REG 0x00 -#define ENC28J60_READ_BUF_MEM 0x3A -#define ENC28J60_WRITE_CTRL_REG 0x40 -#define ENC28J60_WRITE_BUF_MEM 0x7A -#define ENC28J60_BIT_FIELD_SET 0x80 -#define ENC28J60_BIT_FIELD_CLR 0xA0 -#define ENC28J60_SOFT_RESET 0xFF - - -// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata -// buffer boundaries applied to internal 8K ram -// the entire available packet buffer space is allocated -// -// start with recbuf at 0/ -#define RXSTART_INIT 0x0 -// receive buffer end. make sure this is an odd value ( See Rev. B1,B4,B5,B7 Silicon Errata 'Memory (Ethernet Buffer)') -#define RXSTOP_INIT (0x1FFF-0x1800) -// start TX buffer RXSTOP_INIT+1 -#define TXSTART_INIT (RXSTOP_INIT+1) -// stp TX buffer at end of mem -#define TXSTOP_INIT 0x1FFF -// -// max frame length which the conroller will accept: -#define MAX_FRAMELEN 1500 // (note: maximum ethernet frame length would be 1518) -//#define MAX_FRAMELEN 600 - -#endif diff --git a/libraries/UIPEthernet/utility/mempool.cpp b/libraries/UIPEthernet/utility/mempool.cpp deleted file mode 100644 index 01f17fb..0000000 --- a/libraries/UIPEthernet/utility/mempool.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - mempool.cpp - sleek implementation of a memory pool - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#include "mempool.h" -#include - -#define POOLOFFSET 1 - -MemoryPool::MemoryPool(memaddress start, memaddress size) -{ - memset(&blocks[0], 0, sizeof(blocks)); - blocks[POOLSTART].begin = start; - blocks[POOLSTART].size = 0; - blocks[POOLSTART].nextblock = NOBLOCK; - poolsize = size; -} - -memhandle -MemoryPool::allocBlock(memaddress size) -{ - memblock* best = NULL; - memhandle cur = POOLSTART; - memblock* block = &blocks[POOLSTART]; - memaddress bestsize = poolsize + 1; - - do - { - memhandle next = block->nextblock; - memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + poolsize : blocks[next].begin) - block->begin - block->size; - if (freesize == size) - { - best = &blocks[cur]; - goto found; - } - if (freesize > size && freesize < bestsize) - { - bestsize = freesize; - best = &blocks[cur]; - } - if (next == NOBLOCK) - { - if (best) - goto found; - else - goto collect; - } - block = &blocks[next]; - cur = next; - } - while (true); - - collect: - { - cur = POOLSTART; - block = &blocks[POOLSTART]; - memhandle next; - while ((next = block->nextblock) != NOBLOCK) - { - memaddress dest = block->begin + block->size; - memblock* nextblock = &blocks[next]; - memaddress* src = &nextblock->begin; - if (dest != *src) - { -#ifdef MEMBLOCK_MV - memblock_mv_cb(dest,*src,nextblock->size); -#endif - *src = dest; - } - block = nextblock; - } - if (blocks[POOLSTART].begin + poolsize - block->begin - block->size >= size) - best = block; - else - goto notfound; - } - - found: - { - block = &blocks[POOLOFFSET]; - for (cur = POOLOFFSET; cur < NUM_MEMBLOCKS + POOLOFFSET; cur++) - { - if (block->size) - { - block++; - continue; - } - memaddress address = best->begin + best->size; -#ifdef MEMBLOCK_ALLOC - MEMBLOCK_ALLOC(address,size); -#endif - block->begin = address; - block->size = size; - block->nextblock = best->nextblock; - best->nextblock = cur; - return cur; - } - } - - notfound: return NOBLOCK; -} - -void -MemoryPool::freeBlock(memhandle handle) -{ - memblock *b = &blocks[POOLSTART]; - - do - { - memhandle next = b->nextblock; - if (next == handle) - { - memblock *f = &blocks[next]; -#ifdef MEMBLOCK_FREE - MEMBLOCK_FREE(f->begin,f->size); -#endif - b->nextblock = f->nextblock; - f->size = 0; - f->nextblock = NOBLOCK; - return; - } - if (next == NOBLOCK) - return; - b = &blocks[next]; - } - while (true); -} - -void -MemoryPool::resizeBlock(memhandle handle, memaddress position) -{ - memblock * block = &blocks[handle]; - block->begin += position; - block->size -= position; -} - -void -MemoryPool::resizeBlock(memhandle handle, memaddress position, memaddress size) -{ - memblock * block = &blocks[handle]; - block->begin += position; - block->size = size; -} - -memaddress -MemoryPool::blockSize(memhandle handle) -{ - return blocks[handle].size; -} diff --git a/libraries/UIPEthernet/utility/mempool.h b/libraries/UIPEthernet/utility/mempool.h deleted file mode 100644 index ea79473..0000000 --- a/libraries/UIPEthernet/utility/mempool.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - mempool.h - sleek implementation of a memory pool - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#ifndef MEMPOOL_H -#define MEMPOOL_H - -#include - -#define POOLSTART 0 -#define NOBLOCK 0 - -#include "mempool_conf.h" - -//#ifdef MEMBLOCK_MV -//#define memblock_mv_cb(dest,src,size) MEMBLOCK_MV(dest,src,size) -//#endif - -#ifdef MEMBLOCK_ALLOC -#define memblock_alloc_cb(address,size) MEMBLOCK_ALLOC(address,size) -#endif - -#ifdef MEMBLOCK_FREE -#define memblock_free_cb(address,size) MEMBLOCK_FREE(address,size) -#endif - -struct memblock -{ - memaddress begin; - memaddress size; - memhandle nextblock; -}; - -class MemoryPool -{ -#ifdef MEMPOOLTEST_H - friend class MemoryPoolTest; -#endif - -protected: - memaddress poolsize; - struct memblock blocks[NUM_MEMBLOCKS+1]; -#ifdef MEMBLOCK_MV - virtual void memblock_mv_cb(memaddress dest, memaddress src, memaddress size) = 0; -#endif - -public: - MemoryPool(memaddress start, memaddress size); - memhandle - allocBlock(memaddress); - void freeBlock(memhandle); - void resizeBlock(memhandle handle, memaddress position); - void resizeBlock(memhandle handle, memaddress position, memaddress size); - memaddress blockSize(memhandle); -}; -#endif diff --git a/libraries/UIPEthernet/utility/mempool_conf.h b/libraries/UIPEthernet/utility/mempool_conf.h deleted file mode 100644 index bd5a726..0000000 --- a/libraries/UIPEthernet/utility/mempool_conf.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef MEMPOOLCONF_H -#define MEMPOOLCONF_H -#include "uipethernet-conf.h" -extern "C" { - #include "uipopt.h" -} -#include - -typedef uint16_t memaddress; -typedef uint8_t memhandle; - -#if UIP_SOCKET_NUMPACKETS and UIP_CONNS -#define NUM_TCP_MEMBLOCKS (UIP_SOCKET_NUMPACKETS*2)*UIP_CONNS -#else -#define NUM_TCP_MEMBLOCKS 0 -#endif - -#if UIP_UDP and UIP_UDP_NUMPACKETS and UIP_UDP_CONNS -#define NUM_UDP_MEMBLOCKS (UIP_UDP_NUMPACKETS+1)*UIP_UDP_CONNS -#else -#define NUM_UDP_MEMBLOCKS 0 -#endif - -#define NUM_MEMBLOCKS (NUM_TCP_MEMBLOCKS+NUM_UDP_MEMBLOCKS) - -#define MEMBLOCK_MV - -#endif diff --git a/libraries/UIPEthernet/utility/uip-conf.h b/libraries/UIPEthernet/utility/uip-conf.h deleted file mode 100644 index 814aeb9..0000000 --- a/libraries/UIPEthernet/utility/uip-conf.h +++ /dev/null @@ -1,185 +0,0 @@ -/** - * UIPEthernet Project-specific configuration options - * Copyright (c) 2013 Norbert Truchsess - * @{ - * - * uIP has a number of configuration options that can be overridden - * for each project. These are kept in a project-specific uip-conf.h - * file and all configuration names have the prefix UIP_CONF. - */ - -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - */ - -#ifndef __UIP_CONF_H__ -#define __UIP_CONF_H__ - -#include -#include "uipethernet-conf.h" - -/** - * 8 bit datatype - * - * This typedef defines the 8-bit type used throughout uIP. - * - * \hideinitializer - */ -typedef uint8_t u8_t; - -/** - * 16 bit datatype - * - * This typedef defines the 16-bit type used throughout uIP. - * - * \hideinitializer - */ -typedef uint16_t u16_t; - -/** - * Statistics datatype - * - * This typedef defines the dataype used for keeping statistics in - * uIP. - * - * \hideinitializer - */ -typedef unsigned short uip_stats_t; - -/** - * Maximum number of TCP connections. - * (see uipethernet-conf.h) - * \hideinitializer - * - * #define UIP_CONF_MAX_CONNECTIONS 4 - */ - -/** - * Maximum number of listening TCP ports. - * - * \hideinitializer - */ -#define UIP_CONF_MAX_LISTENPORTS 4 - -/** - * uIP buffer size. - * - * \hideinitializer - */ -#define UIP_CONF_BUFFER_SIZE 98 -//#define UIP_CONF_BUFFER_SIZE 118 - -/** - * The TCP maximum segment size. - * - * This is should not be to set to more than - * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. - */ - -#define UIP_CONF_TCP_MSS 512 - -/** - * The size of the advertised receiver's window. - * - * Should be set low (i.e., to the size of the uip_buf buffer) is the - * application is slow to process incoming data, or high (32768 bytes) - * if the application processes data quickly. - * - * \hideinitializer - */ -#define UIP_CONF_RECEIVE_WINDOW 512 - -/** - * CPU byte order. - * - * \hideinitializer - */ -#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN - -/** - * Logging on or off - * - * \hideinitializer - */ -#define UIP_CONF_LOGGING 0 - -/** - * UDP support on or off - * (see uipethernet-conf.h) - * \hideinitializer - * - * #define UIP_CONF_UDP 1 - * - * #define UIP_CONF_UDP_CONNS 4 - */ - -/** - * UDP checksums on or off - * - * \hideinitializer - */ -#define UIP_CONF_UDP_CHECKSUMS 1 - -/** - * UDP Broadcast (receive) on or off - * (see uipethernet-conf.h) - * \hideinitializer - * #define UIP_CONF_BROADCAST 1 - */ - - -/** - * uIP statistics on or off - * - * \hideinitializer - */ -#define UIP_CONF_STATISTICS 0 - -// SLIP -//#define UIP_CONF_LLH_LEN 0 - -typedef void* uip_tcp_appstate_t; - -void uipclient_appcall(void); - -#define UIP_APPCALL uipclient_appcall - -typedef void* uip_udp_appstate_t; - -void uipudp_appcall(void); - -#define UIP_UDP_APPCALL uipudp_appcall - -#define CC_REGISTER_ARG register - -#define UIP_ARCH_CHKSUM 1 - -#endif /* __UIP_CONF_H__ */ diff --git a/libraries/UIPEthernet/utility/uip-neighbor.c b/libraries/UIPEthernet/utility/uip-neighbor.c deleted file mode 100644 index 739c03e..0000000 --- a/libraries/UIPEthernet/utility/uip-neighbor.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $ - */ - -/** - * \file - * Database of link-local neighbors, used by IPv6 code and - * to be used by a future ARP code rewrite. - * \author - * Adam Dunkels - */ - -#include "uip-neighbor.h" - -#include - -#define MAX_TIME 128 - -#ifdef UIP_NEIGHBOR_CONF_ENTRIES -#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES -#else /* UIP_NEIGHBOR_CONF_ENTRIES */ -#define ENTRIES 8 -#endif /* UIP_NEIGHBOR_CONF_ENTRIES */ - -struct neighbor_entry { - uip_ipaddr_t ipaddr; - struct uip_neighbor_addr addr; - u8_t time; -}; -static struct neighbor_entry entries[ENTRIES]; - -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_init(void) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - entries[i].time = MAX_TIME; - } -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_periodic(void) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - if(entries[i].time < MAX_TIME) { - entries[i].time++; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr) -{ - int i, oldest; - u8_t oldest_time; - - printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", - addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], - addr->addr.addr[4], addr->addr.addr[5]); - - /* Find the first unused entry or the oldest used entry. */ - oldest_time = 0; - oldest = 0; - for(i = 0; i < ENTRIES; ++i) { - if(entries[i].time == MAX_TIME) { - oldest = i; - break; - } - if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) { - oldest = i; - break; - } - if(entries[i].time > oldest_time) { - oldest = i; - oldest_time = entries[i].time; - } - } - - /* Use the oldest or first free entry (either pointed to by the - "oldest" variable). */ - entries[oldest].time = 0; - uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr); - memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); -} -/*---------------------------------------------------------------------------*/ -static struct neighbor_entry * -find_entry(uip_ipaddr_t ipaddr) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) { - return &entries[i]; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_update(uip_ipaddr_t ipaddr) -{ - struct neighbor_entry *e; - - e = find_entry(ipaddr); - if(e != NULL) { - e->time = 0; - } -} -/*---------------------------------------------------------------------------*/ -struct uip_neighbor_addr * -uip_neighbor_lookup(uip_ipaddr_t ipaddr) -{ - struct neighbor_entry *e; - - e = find_entry(ipaddr); - if(e != NULL) { - /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", - e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], - e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ - - return &e->addr; - } - return NULL; -} -/*---------------------------------------------------------------------------*/ diff --git a/libraries/UIPEthernet/utility/uip-neighbor.h b/libraries/UIPEthernet/utility/uip-neighbor.h deleted file mode 100644 index d3b351c..0000000 --- a/libraries/UIPEthernet/utility/uip-neighbor.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $ - */ - -/** - * \file - * Header file for database of link-local neighbors, used by - * IPv6 code and to be used by future ARP code. - * \author - * Adam Dunkels - */ - -#ifndef __UIP_NEIGHBOR_H__ -#define __UIP_NEIGHBOR_H__ - -#include "uip.h" - -struct uip_neighbor_addr { -#if UIP_NEIGHBOR_CONF_ADDRTYPE - UIP_NEIGHBOR_CONF_ADDRTYPE addr; -#else - struct uip_eth_addr addr; -#endif -}; - -void uip_neighbor_init(void); -void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr); -void uip_neighbor_update(uip_ipaddr_t ipaddr); -struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr); -void uip_neighbor_periodic(void); - -#endif /* __UIP-NEIGHBOR_H__ */ diff --git a/libraries/UIPEthernet/utility/uip.c b/libraries/UIPEthernet/utility/uip.c deleted file mode 100644 index 84ea8c3..0000000 --- a/libraries/UIPEthernet/utility/uip.c +++ /dev/null @@ -1,1897 +0,0 @@ -#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ - -/** - * \defgroup uip The uIP TCP/IP stack - * @{ - * - * uIP is an implementation of the TCP/IP protocol stack intended for - * small 8-bit and 16-bit microcontrollers. - * - * uIP provides the necessary protocols for Internet communication, - * with a very small code footprint and RAM requirements - the uIP - * code size is on the order of a few kilobytes and RAM usage is on - * the order of a few hundred bytes. - */ - -/** - * \file - * The uIP TCP/IP stack code. - * \author Adam Dunkels - */ - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ - * - */ - -/* - * uIP is a small implementation of the IP, UDP and TCP protocols (as - * well as some basic ICMP stuff). The implementation couples the IP, - * UDP, TCP and the application layers very tightly. To keep the size - * of the compiled code down, this code frequently uses the goto - * statement. While it would be possible to break the uip_process() - * function into many smaller functions, this would increase the code - * size because of the overhead of parameter passing and the fact that - * the optimier would not be as efficient. - * - * The principle is that we have a small buffer, called the uip_buf, - * in which the device driver puts an incoming packet. The TCP/IP - * stack parses the headers in the packet, and calls the - * application. If the remote host has sent data to the application, - * this data is present in the uip_buf and the application read the - * data from there. It is up to the application to put this data into - * a byte stream if needed. The application will not be fed with data - * that is out of sequence. - * - * If the application whishes to send data to the peer, it should put - * its data into the uip_buf. The uip_appdata pointer points to the - * first available byte. The TCP/IP stack will calculate the - * checksums, and fill in the necessary header fields and finally send - * the packet back to the peer. -*/ - -#include "uip.h" -#include "uipopt.h" -#include "uip_arch.h" - -#if UIP_CONF_IPV6 -#include "uip-neighbor.h" -#endif /* UIP_CONF_IPV6 */ - -#include - -/*---------------------------------------------------------------------------*/ -/* Variable definitions. */ - - -/* The IP address of this host. If it is defined to be fixed (by - setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set - here. Otherwise, the address */ -#if UIP_FIXEDADDR > 0 -const uip_ipaddr_t uip_hostaddr = - {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), - HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; -const uip_ipaddr_t uip_draddr = - {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), - HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; -const uip_ipaddr_t uip_netmask = - {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), - HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; -#else -uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; -#endif /* UIP_FIXEDADDR */ - -static const uip_ipaddr_t all_ones_addr = -#if UIP_CONF_IPV6 - {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; -#else /* UIP_CONF_IPV6 */ - {0xffff,0xffff}; -#endif /* UIP_CONF_IPV6 */ -static const uip_ipaddr_t all_zeroes_addr = -#if UIP_CONF_IPV6 - {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; -#else /* UIP_CONF_IPV6 */ - {0x0000,0x0000}; -#endif /* UIP_CONF_IPV6 */ - - -#if UIP_FIXEDETHADDR -const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, - UIP_ETHADDR1, - UIP_ETHADDR2, - UIP_ETHADDR3, - UIP_ETHADDR4, - UIP_ETHADDR5}}; -#else -struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}; -#endif - -#ifndef UIP_CONF_EXTERNAL_BUFFER -u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains - incoming packets. */ -#endif /* UIP_CONF_EXTERNAL_BUFFER */ - -void *uip_appdata; /* The uip_appdata pointer points to - application data. */ -void *uip_sappdata; /* The uip_appdata pointer points to - the application data which is to - be sent. */ -#if UIP_URGDATA > 0 -void *uip_urgdata; /* The uip_urgdata pointer points to - urgent data (out-of-band data), if - present. */ -u16_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - -u16_t uip_len, uip_slen; - /* The uip_len is either 8 or 16 bits, - depending on the maximum packet - size. */ - -u8_t uip_flags; /* The uip_flags variable is used for - communication between the TCP/IP stack - and the application program. */ -struct uip_conn *uip_conn; /* uip_conn always points to the current - connection. */ - -struct uip_conn uip_conns[UIP_CONNS]; - /* The uip_conns array holds all TCP - connections. */ -u16_t uip_listenports[UIP_LISTENPORTS]; - /* The uip_listenports list all currently - listning ports. */ -#if UIP_UDP -struct uip_udp_conn *uip_udp_conn; -struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; -#endif /* UIP_UDP */ - -static u16_t ipid; /* Ths ipid variable is an increasing - number that is used for the IP ID - field. */ - -void uip_setipid(u16_t id) { ipid = id; } - -static u8_t iss[4]; /* The iss variable is used for the TCP - initial sequence number. */ - -#if UIP_ACTIVE_OPEN -static u16_t lastport; /* Keeps track of the last port used for - a new connection. */ -#endif /* UIP_ACTIVE_OPEN */ - -/* Temporary variables. */ -u8_t uip_acc32[4]; -static u8_t c, opt; -static u16_t tmp16; - -/* Structures and definitions. */ -#define TCP_FIN 0x01 -#define TCP_SYN 0x02 -#define TCP_RST 0x04 -#define TCP_PSH 0x08 -#define TCP_ACK 0x10 -#define TCP_URG 0x20 -#define TCP_CTL 0x3f - -#define TCP_OPT_END 0 /* End of TCP options list */ -#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ -#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ - -#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ - -#define ICMP_ECHO_REPLY 0 -#define ICMP_ECHO 8 - -#define ICMP6_ECHO_REPLY 129 -#define ICMP6_ECHO 128 -#define ICMP6_NEIGHBOR_SOLICITATION 135 -#define ICMP6_NEIGHBOR_ADVERTISEMENT 136 - -#define ICMP6_FLAG_S (1 << 6) - -#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 -#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 - - -/* Macros. */ -#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) -#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) - - -#if UIP_STATISTICS == 1 -struct uip_stats uip_stat; -#define UIP_STAT(s) s -#else -#define UIP_STAT(s) -#endif /* UIP_STATISTICS == 1 */ - -#if UIP_LOGGING == 1 -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -#if ! UIP_ARCH_ADD32 -void -uip_add32(u8_t *op32, u16_t op16) -{ - uip_acc32[3] = op32[3] + (op16 & 0xff); - uip_acc32[2] = op32[2] + (op16 >> 8); - uip_acc32[1] = op32[1]; - uip_acc32[0] = op32[0]; - - if(uip_acc32[2] < (op16 >> 8)) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - - - if(uip_acc32[3] < (op16 & 0xff)) { - ++uip_acc32[2]; - if(uip_acc32[2] == 0) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - } -} - -#endif /* UIP_ARCH_ADD32 */ - -#if ! UIP_ARCH_CHKSUM -/*---------------------------------------------------------------------------*/ -static u16_t -chksum(u16_t sum, const u8_t *data, u16_t len) -{ - u16_t t; - const u8_t *dataptr; - const u8_t *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while(dataptr < last_byte) { /* At least two more bytes */ - t = (dataptr[0] << 8) + dataptr[1]; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - dataptr += 2; - } - - if(dataptr == last_byte) { - t = (dataptr[0] << 8) + 0; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - - /* Return sum in host byte order. */ - return sum; -} -/*---------------------------------------------------------------------------*/ -u16_t -uip_chksum(u16_t *data, u16_t len) -{ - return htons(chksum(0, (u8_t *)data, len)); -} -/*---------------------------------------------------------------------------*/ -#ifndef UIP_ARCH_IPCHKSUM -u16_t -uip_ipchksum(void) -{ - u16_t sum; - - sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); - DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum); - return (sum == 0) ? 0xffff : htons(sum); -} -#endif -/*---------------------------------------------------------------------------*/ -static u16_t -upper_layer_chksum(u8_t proto) -{ - u16_t upper_layer_len; - u16_t sum; - -#if UIP_CONF_IPV6 - upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); -#else /* UIP_CONF_IPV6 */ - upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; -#endif /* UIP_CONF_IPV6 */ - - /* First sum pseudoheader. */ - - /* IP protocol and length fields. This addition cannot carry. */ - sum = upper_layer_len + proto; - /* Sum IP source and destination addresses. */ - sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); - - /* Sum TCP header and data. */ - sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], - upper_layer_len); - - return (sum == 0) ? 0xffff : htons(sum); -} -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 -u16_t -uip_icmp6chksum(void) -{ - return upper_layer_chksum(UIP_PROTO_ICMP6); - -} -#endif /* UIP_CONF_IPV6 */ -/*---------------------------------------------------------------------------*/ -u16_t -uip_tcpchksum(void) -{ - return upper_layer_chksum(UIP_PROTO_TCP); -} -/*---------------------------------------------------------------------------*/ -#if UIP_UDP_CHECKSUMS -u16_t -uip_udpchksum(void) -{ - return upper_layer_chksum(UIP_PROTO_UDP); -} -#endif /* UIP_UDP_CHECKSUMS */ -#endif /* UIP_ARCH_CHKSUM */ -/*---------------------------------------------------------------------------*/ -void -uip_init(void) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - uip_listenports[c] = 0; - } - for(c = 0; c < UIP_CONNS; ++c) { - uip_conns[c].tcpstateflags = UIP_CLOSED; - } -#if UIP_ACTIVE_OPEN - lastport = 1024; -#endif /* UIP_ACTIVE_OPEN */ - -#if UIP_UDP - for(c = 0; c < UIP_UDP_CONNS; ++c) { - uip_udp_conns[c].lport = 0; - } -#endif /* UIP_UDP */ - - - /* IPv4 initialization. */ -#if UIP_FIXEDADDR == 0 - /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ -#endif /* UIP_FIXEDADDR */ - -} -/*---------------------------------------------------------------------------*/ -#if UIP_ACTIVE_OPEN -struct uip_conn * -uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) -{ - register struct uip_conn *conn, *cconn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - /* Check if this port is already in use, and if so try to find - another one. */ - for(c = 0; c < UIP_CONNS; ++c) { - conn = &uip_conns[c]; - if(conn->tcpstateflags != UIP_CLOSED && - conn->lport == htons(lastport)) { - goto again; - } - } - - conn = 0; - for(c = 0; c < UIP_CONNS; ++c) { - cconn = &uip_conns[c]; - if(cconn->tcpstateflags == UIP_CLOSED) { - conn = cconn; - break; - } - if(cconn->tcpstateflags == UIP_TIME_WAIT) { - if(conn == 0 || - cconn->timer > conn->timer) { - conn = cconn; - } - } - } - - if(conn == 0) { - return 0; - } - - conn->tcpstateflags = UIP_SYN_SENT; - - conn->snd_nxt[0] = iss[0]; - conn->snd_nxt[1] = iss[1]; - conn->snd_nxt[2] = iss[2]; - conn->snd_nxt[3] = iss[3]; - - conn->initialmss = conn->mss = UIP_TCP_MSS; - - conn->len = 1; /* TCP length of the SYN is one. */ - conn->nrtx = 0; - conn->timer = 1; /* Send the SYN next time around. */ - conn->rto = UIP_RTO; - conn->sa = 0; - conn->sv = 16; /* Initial value of the RTT variance. */ - conn->lport = htons(lastport); - conn->rport = rport; - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - - return conn; -} -#endif /* UIP_ACTIVE_OPEN */ -/*---------------------------------------------------------------------------*/ -#if UIP_UDP -struct uip_udp_conn * -uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) -{ - register struct uip_udp_conn *conn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == htons(lastport)) { - goto again; - } - } - - - conn = 0; - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == 0) { - conn = &uip_udp_conns[c]; - break; - } - } - - if(conn == 0) { - return 0; - } - - conn->lport = HTONS(lastport); - conn->rport = rport; - if(ripaddr == NULL) { - memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); - } else { - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - } - conn->ttl = UIP_TTL; - - return conn; -} -#endif /* UIP_UDP */ -/*---------------------------------------------------------------------------*/ -void -uip_unlisten(u16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == port) { - uip_listenports[c] = 0; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_listen(u16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == 0) { - uip_listenports[c] = port; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -/* XXX: IP fragment reassembly: not well-tested. */ - -#if UIP_REASSEMBLY && !UIP_CONF_IPV6 -#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) -static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; -static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; -static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, - 0x0f, 0x07, 0x03, 0x01}; -static u16_t uip_reasslen; -static u8_t uip_reassflags; -#define UIP_REASS_FLAG_LASTFRAG 0x01 -static u8_t uip_reasstmr; - -#define IP_MF 0x20 - -static u8_t -uip_reass(void) -{ - u16_t offset, len; - u16_t i; - - /* If ip_reasstmr is zero, no packet is present in the buffer, so we - write the IP header of the fragment into the reassembly - buffer. The timer is updated with the maximum age. */ - if(uip_reasstmr == 0) { - memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); - uip_reasstmr = UIP_REASS_MAXAGE; - uip_reassflags = 0; - /* Clear the bitmap. */ - memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); - } - - /* Check if the incoming fragment matches the one currently present - in the reasembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] && - BUF->srcipaddr[1] == FBUF->srcipaddr[1] && - BUF->destipaddr[0] == FBUF->destipaddr[0] && - BUF->destipaddr[1] == FBUF->destipaddr[1] && - BUF->ipid[0] == FBUF->ipid[0] && - BUF->ipid[1] == FBUF->ipid[1]) { - - len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; - offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; - - /* If the offset or the offset + fragment length overflows the - reassembly buffer, we discard the entire packet. */ - if(offset > UIP_REASS_BUFSIZE || - offset + len > UIP_REASS_BUFSIZE) { - uip_reasstmr = 0; - goto nullreturn; - } - - /* Copy the fragment into the reassembly buffer, at the right - offset. */ - memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], - (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), - len); - - /* Update the bitmap. */ - if(offset / (8 * 8) == (offset + len) / (8 * 8)) { - /* If the two endpoints are in the same byte, we only update - that byte. */ - - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7] & - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } else { - /* If the two endpoints are in different bytes, we update the - bytes in the endpoints and fill the stuff inbetween with - 0xff. */ - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7]; - for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) { - uip_reassbitmap[i] = 0xff; - } - uip_reassbitmap[(offset + len) / (8 * 8)] |= - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } - - /* If this fragment has the More Fragments flag set to zero, we - know that this is the last fragment, so we can calculate the - size of the entire packet. We also set the - IP_REASS_FLAG_LASTFRAG flag to indicate that we have received - the final fragment. */ - - if((BUF->ipoffset[0] & IP_MF) == 0) { - uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; - uip_reasslen = offset + len; - } - - /* Finally, we check if we have a full packet in the buffer. We do - this by checking if we have the last fragment and if all bits - in the bitmap are set. */ - if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { - /* Check all bytes up to and including all but the last byte in - the bitmap. */ - for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { - if(uip_reassbitmap[i] != 0xff) { - goto nullreturn; - } - } - /* Check the last byte in the bitmap. It should contain just the - right amount of bits. */ - if(uip_reassbitmap[uip_reasslen / (8 * 8)] != - (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { - goto nullreturn; - } - - /* If we have come this far, we have a full packet in the - buffer, so we allocate a pbuf and copy the packet into it. We - also reset the timer. */ - uip_reasstmr = 0; - memcpy(BUF, FBUF, uip_reasslen); - - /* Pretend to be a "normal" (i.e., not fragmented) IP packet - from now on. */ - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - BUF->len[0] = uip_reasslen >> 8; - BUF->len[1] = uip_reasslen & 0xff; - BUF->ipchksum = 0; - BUF->ipchksum = ~(uip_ipchksum()); - - return uip_reasslen; - } - } - - nullreturn: - return 0; -} -#endif /* UIP_REASSEMBLY */ -/*---------------------------------------------------------------------------*/ -static void -uip_add_rcv_nxt(u16_t n) -{ - uip_add32(uip_conn->rcv_nxt, n); - uip_conn->rcv_nxt[0] = uip_acc32[0]; - uip_conn->rcv_nxt[1] = uip_acc32[1]; - uip_conn->rcv_nxt[2] = uip_acc32[2]; - uip_conn->rcv_nxt[3] = uip_acc32[3]; -} -/*---------------------------------------------------------------------------*/ -void -uip_process(u8_t flag) -{ - register struct uip_conn *uip_connr = uip_conn; - -#if UIP_UDP - if(flag == UIP_UDP_SEND_CONN) { - goto udp_send; - } -#endif /* UIP_UDP */ - - uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; - - /* Check if we were invoked because of a poll request for a - particular connection. */ - if(flag == UIP_POLL_REQUEST) { - if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && - !uip_outstanding(uip_connr)) { - uip_flags = UIP_POLL; - UIP_APPCALL(); - goto appsend; - } - goto drop; - - /* Check if we were invoked because of the perodic timer fireing. */ - } else if(flag == UIP_TIMER) { -#if UIP_REASSEMBLY - if(uip_reasstmr != 0) { - --uip_reasstmr; - } -#endif /* UIP_REASSEMBLY */ - /* Increase the initial sequence number. */ - if(++iss[3] == 0) { - if(++iss[2] == 0) { - if(++iss[1] == 0) { - ++iss[0]; - } - } - } - - /* Reset the length variables. */ - uip_len = 0; - uip_slen = 0; - - /* Check if the connection is in a state in which we simply wait - for the connection to time out. If so, we increase the - connection's timer and remove the connection if it times - out. */ - if(uip_connr->tcpstateflags == UIP_TIME_WAIT || - uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { - ++(uip_connr->timer); - if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { - uip_connr->tcpstateflags = UIP_CLOSED; - } - } else if(uip_connr->tcpstateflags != UIP_CLOSED) { - /* If the connection has outstanding data, we increase the - connection's timer and see if it has reached the RTO value - in which case we retransmit. */ - if(uip_outstanding(uip_connr)) { - if(uip_connr->timer-- == 0) { - if(uip_connr->nrtx == UIP_MAXRTX || - ((uip_connr->tcpstateflags == UIP_SYN_SENT || - uip_connr->tcpstateflags == UIP_SYN_RCVD) && - uip_connr->nrtx == UIP_MAXSYNRTX)) { - uip_connr->tcpstateflags = UIP_CLOSED; - - /* We call UIP_APPCALL() with uip_flags set to - UIP_TIMEDOUT to inform the application that the - connection has timed out. */ - uip_flags = UIP_TIMEDOUT; - UIP_APPCALL(); - - /* We also send a reset packet to the remote host. */ - BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - /* Exponential backoff. */ - uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? - 4: - uip_connr->nrtx); - ++(uip_connr->nrtx); - - /* Ok, so we need to retransmit. We do this differently - depending on which state we are in. In ESTABLISHED, we - call upon the application so that it may prepare the - data for the retransmit. In SYN_RCVD, we resend the - SYNACK that we sent earlier and in LAST_ACK we have to - retransmit our FINACK. */ - UIP_STAT(++uip_stat.tcp.rexmit); - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_SYN_RCVD: - /* In the SYN_RCVD state, we should retransmit our - SYNACK. */ - goto tcp_send_synack; - -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - BUF->flags = 0; - goto tcp_send_syn; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application - to do the actual retransmit after which we jump into - the code for sending out the packet (the apprexmit - label). */ - uip_flags = UIP_REXMIT; - UIP_APPCALL(); - goto apprexmit; - - case UIP_FIN_WAIT_1: - case UIP_CLOSING: - case UIP_LAST_ACK: - /* In all these states we should retransmit a FINACK. */ - goto tcp_send_finack; - - } - } - } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { - /* If there was no need for a retransmission, we poll the - application for new data. */ - uip_flags = UIP_POLL; - UIP_APPCALL(); - goto appsend; - } - } - goto drop; - } -#if UIP_UDP - if(flag == UIP_UDP_TIMER) { - if(uip_udp_conn->lport != 0) { - uip_conn = NULL; - uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - uip_len = uip_slen = 0; - uip_flags = UIP_POLL; - UIP_UDP_APPCALL(); - goto udp_send; - } else { - goto drop; - } - } -#endif - - /* This is where the input processing starts. */ - UIP_STAT(++uip_stat.ip.recv); - - /* Start of IP input header processing code. */ - -#if UIP_CONF_IPV6 - /* Check validity of the IP header. */ - if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.vhlerr); - UIP_LOG("ipv6: invalid version."); - goto drop; - } -#else /* UIP_CONF_IPV6 */ - /* Check validity of the IP header. */ - if(BUF->vhl != 0x45) { /* IP version and header length. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.vhlerr); - UIP_LOG("ip: invalid version or header length."); - goto drop; - } -#endif /* UIP_CONF_IPV6 */ - - /* Check the size of the packet. If the size reported to us in - uip_len is smaller the size reported in the IP header, we assume - that the packet has been corrupted in transit. If the size of - uip_len is larger than the size reported in the IP packet header, - the packet has been padded and we set uip_len to the correct - value.. */ - - if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) { - uip_len = (BUF->len[0] << 8) + BUF->len[1]; -#if UIP_CONF_IPV6 - uip_len += 40; /* The length reported in the IPv6 header is the - length of the payload that follows the - header. However, uIP uses the uip_len variable - for holding the size of the entire packet, - including the IP header. For IPv4 this is not a - problem as the length field in the IPv4 header - contains the length of the entire packet. But - for IPv6 we need to add the size of the IPv6 - header (40 bytes). */ -#endif /* UIP_CONF_IPV6 */ - } else { - UIP_LOG("ip: packet shorter than reported in IP header."); - goto drop; - } - -#if !UIP_CONF_IPV6 - /* Check the fragment flag. */ - if((BUF->ipoffset[0] & 0x3f) != 0 || - BUF->ipoffset[1] != 0) { -#if UIP_REASSEMBLY - uip_len = uip_reass(); - if(uip_len == 0) { - goto drop; - } -#else /* UIP_REASSEMBLY */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); - goto drop; -#endif /* UIP_REASSEMBLY */ - } -#endif /* UIP_CONF_IPV6 */ - - if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { - /* If we are configured to use ping IP address configuration and - hasn't been assigned an IP address yet, we accept all ICMP - packets. */ -#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 - if(BUF->proto == UIP_PROTO_ICMP) { - UIP_LOG("ip: possible ping config packet received."); - goto icmp_input; - } else { - UIP_LOG("ip: packet dropped since no address assigned."); - goto drop; - } -#endif /* UIP_PINGADDRCONF */ - - } else { - /* If IP broadcast support is configured, we check for a broadcast - UDP packet, which may be destined to us. */ -#if UIP_BROADCAST - DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); - if(BUF->proto == UIP_PROTO_UDP && - uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr) - /*&& - uip_ipchksum() == 0xffff*/) { - goto udp_input; - } -#endif /* UIP_BROADCAST */ - - /* Check if the packet is destined for our IP address. */ -#if !UIP_CONF_IPV6 - if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) { - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } -#else /* UIP_CONF_IPV6 */ - /* For IPv6, packet reception is a little trickier as we need to - make sure that we listen to certain multicast addresses (all - hosts multicast address, and the solicited-node multicast - address) as well. However, we will cheat here and accept all - multicast packets that are sent to the ff02::/16 addresses. */ - if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) && - BUF->destipaddr[0] != HTONS(0xff02)) { - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } -#endif /* UIP_CONF_IPV6 */ - } - -#if !UIP_CONF_IPV6 - if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header - checksum. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.chkerr); - UIP_LOG("ip: bad checksum."); - goto drop; - } -#endif /* UIP_CONF_IPV6 */ - - if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, - proceed with TCP input - processing. */ - goto tcp_input; - } - -#if UIP_UDP - if(BUF->proto == UIP_PROTO_UDP) { - goto udp_input; - } -#endif /* UIP_UDP */ - -#if !UIP_CONF_IPV6 - /* ICMPv4 processing code follows. */ - if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from - here. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip: neither tcp nor icmp."); - goto drop; - } - -#if UIP_PINGADDRCONF - icmp_input: -#endif /* UIP_PINGADDRCONF */ - UIP_STAT(++uip_stat.icmp.recv); - - /* ICMP echo (i.e., ping) processing. This is simple, we only change - the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP - checksum before we return the packet. */ - if(ICMPBUF->type != ICMP_ECHO) { - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.typeerr); - UIP_LOG("icmp: not icmp echo."); - goto drop; - } - - /* If we are configured to use ping IP address assignment, we use - the destination IP address of this ping packet and assign it to - ourself. */ -#if UIP_PINGADDRCONF - if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { - uip_hostaddr[0] = BUF->destipaddr[0]; - uip_hostaddr[1] = BUF->destipaddr[1]; - } -#endif /* UIP_PINGADDRCONF */ - - ICMPBUF->type = ICMP_ECHO_REPLY; - - if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) { - ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1; - } else { - ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8); - } - - /* Swap IP addresses. */ - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - - UIP_STAT(++uip_stat.icmp.sent); - goto send; - - /* End of IPv4 input header processing code. */ -#else /* !UIP_CONF_IPV6 */ - - /* This is IPv6 ICMPv6 processing code. */ - DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); - - if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from - here. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip: neither tcp nor icmp6."); - goto drop; - } - - UIP_STAT(++uip_stat.icmp.recv); - - /* If we get a neighbor solicitation for our address we should send - a neighbor advertisement message back. */ - if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { - if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { - - if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { - /* Save the sender's address in our neighbor list. */ - uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); - } - - /* We should now send a neighbor advertisement back to where the - neighbor solicication came from. */ - ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; - ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ - - ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; - - uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); - uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); - ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; - ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ - memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_icmp6chksum(); - goto send; - - } - goto drop; - } else if(ICMPBUF->type == ICMP6_ECHO) { - /* ICMP echo (i.e., ping) processing. This is simple, we only - change the ICMP type from ECHO to ECHO_REPLY and update the - ICMP checksum before we return the packet. */ - - ICMPBUF->type = ICMP6_ECHO_REPLY; - - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_icmp6chksum(); - - UIP_STAT(++uip_stat.icmp.sent); - goto send; - } else { - DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type); - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.typeerr); - UIP_LOG("icmp: unknown ICMP message."); - goto drop; - } - - /* End of IPv6 ICMP processing. */ - -#endif /* !UIP_CONF_IPV6 */ - -#if UIP_UDP - /* UDP input processing. */ - udp_input: - /* UDP processing is really just a hack. We don't do anything to the - UDP/IP headers, but let the UDP application do all the hard - work. If the application sets uip_slen, it has a packet to - send. */ -#if UIP_UDP_CHECKSUMS - uip_len = uip_len - UIP_IPUDPH_LEN; - uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { - UIP_STAT(++uip_stat.udp.drop); - UIP_STAT(++uip_stat.udp.chkerr); - UIP_LOG("udp: bad checksum."); - goto drop; - } -#else /* UIP_UDP_CHECKSUMS */ - uip_len = uip_len - UIP_IPUDPH_LEN; -#endif /* UIP_UDP_CHECKSUMS */ - - /* Demultiplex this UDP packet between the UDP "connections". */ - for(uip_udp_conn = &uip_udp_conns[0]; - uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; - ++uip_udp_conn) { - /* If the local UDP port is non-zero, the connection is considered - to be used. If so, the local port number is checked against the - destination port number in the received packet. If the two port - numbers match, the remote port number is checked if the - connection is bound to a remote port. Finally, if the - connection is bound to a remote IP address, the source IP - address of the packet is checked. */ - if(uip_udp_conn->lport != 0 && - UDPBUF->destport == uip_udp_conn->lport && - (uip_udp_conn->rport == 0 || - UDPBUF->srcport == uip_udp_conn->rport) && - (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || - uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || - uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { - goto udp_found; - } - } - UIP_LOG("udp: no matching connection found"); - goto drop; - - udp_found: - uip_conn = NULL; - uip_flags = UIP_NEWDATA; - uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - uip_slen = 0; - UIP_UDP_APPCALL(); - udp_send: - if(uip_slen == 0) { - goto drop; - } - uip_len = uip_slen + UIP_IPUDPH_LEN; - -#if UIP_CONF_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ - BUF->len[0] = (uip_len >> 8); - BUF->len[1] = (uip_len & 0xff); -#endif /* UIP_CONF_IPV6 */ - - BUF->ttl = uip_udp_conn->ttl; - BUF->proto = UIP_PROTO_UDP; - - UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN); - UDPBUF->udpchksum = 0; - - BUF->srcport = uip_udp_conn->lport; - BUF->destport = uip_udp_conn->rport; - - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr); - - uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; - -#if UIP_UDP_CHECKSUMS - /* Calculate UDP checksum. */ - UDPBUF->udpchksum = ~(uip_udpchksum()); - if(UDPBUF->udpchksum == 0) { - UDPBUF->udpchksum = 0xffff; - } -#endif /* UIP_UDP_CHECKSUMS */ - - goto ip_send_nolen; -#endif /* UIP_UDP */ - - /* TCP input processing. */ - tcp_input: - UIP_STAT(++uip_stat.tcp.recv); - - /* Start of TCP input header processing code. */ - - if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP - checksum. */ - UIP_STAT(++uip_stat.tcp.drop); - UIP_STAT(++uip_stat.tcp.chkerr); - UIP_LOG("tcp: bad checksum."); - goto drop; - } - - - /* Demultiplex this segment. */ - /* First check any active connections. */ - for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; - ++uip_connr) { - if(uip_connr->tcpstateflags != UIP_CLOSED && - BUF->destport == uip_connr->lport && - BUF->srcport == uip_connr->rport && - uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { - goto found; - } - } - - /* If we didn't find and active connection that expected the packet, - either this packet is an old duplicate, or this is a SYN packet - destined for a connection in LISTEN. If the SYN flag isn't set, - it is an old packet and we send a RST. */ - if((BUF->flags & TCP_CTL) != TCP_SYN) { - goto reset; - } - - tmp16 = BUF->destport; - /* Next, check listening connections. */ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(tmp16 == uip_listenports[c]) - goto found_listen; - } - - /* No matching connection found, so we send a RST packet. */ - UIP_STAT(++uip_stat.tcp.synrst); - reset: - - /* We do not send resets in response to resets. */ - if(BUF->flags & TCP_RST) { - goto drop; - } - - UIP_STAT(++uip_stat.tcp.rst); - - BUF->flags = TCP_RST | TCP_ACK; - uip_len = UIP_IPTCPH_LEN; - BUF->tcpoffset = 5 << 4; - - /* Flip the seqno and ackno fields in the TCP header. */ - c = BUF->seqno[3]; - BUF->seqno[3] = BUF->ackno[3]; - BUF->ackno[3] = c; - - c = BUF->seqno[2]; - BUF->seqno[2] = BUF->ackno[2]; - BUF->ackno[2] = c; - - c = BUF->seqno[1]; - BUF->seqno[1] = BUF->ackno[1]; - BUF->ackno[1] = c; - - c = BUF->seqno[0]; - BUF->seqno[0] = BUF->ackno[0]; - BUF->ackno[0] = c; - - /* We also have to increase the sequence number we are - acknowledging. If the least significant byte overflowed, we need - to propagate the carry to the other bytes as well. */ - if(++BUF->ackno[3] == 0) { - if(++BUF->ackno[2] == 0) { - if(++BUF->ackno[1] == 0) { - ++BUF->ackno[0]; - } - } - } - - /* Swap port numbers. */ - tmp16 = BUF->srcport; - BUF->srcport = BUF->destport; - BUF->destport = tmp16; - - /* Swap IP addresses. */ - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - - /* And send out the RST packet! */ - goto tcp_send_noconn; - - /* This label will be jumped to if we matched the incoming packet - with a connection in LISTEN. In that case, we should create a new - connection and send a SYNACK in return. */ - found_listen: - /* First we check if there are any connections avaliable. Unused - connections are kept in the same table as used connections, but - unused ones have the tcpstate set to CLOSED. Also, connections in - TIME_WAIT are kept track of and we'll use the oldest one if no - CLOSED connections are found. Thanks to Eddie C. Dost for a very - nice algorithm for the TIME_WAIT search. */ - uip_connr = 0; - for(c = 0; c < UIP_CONNS; ++c) { - if(uip_conns[c].tcpstateflags == UIP_CLOSED) { - uip_connr = &uip_conns[c]; - break; - } - if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { - if(uip_connr == 0 || - uip_conns[c].timer > uip_connr->timer) { - uip_connr = &uip_conns[c]; - } - } - } - - if(uip_connr == 0) { - /* All connections are used already, we drop packet and hope that - the remote end will retransmit the packet at a time when we - have more spare connections. */ - UIP_STAT(++uip_stat.tcp.syndrop); - UIP_LOG("tcp: found no unused connections."); - goto drop; - } - uip_conn = uip_connr; - - /* Fill in the necessary fields for the new connection. */ - uip_connr->rto = uip_connr->timer = UIP_RTO; - uip_connr->sa = 0; - uip_connr->sv = 4; - uip_connr->nrtx = 0; - uip_connr->lport = BUF->destport; - uip_connr->rport = BUF->srcport; - uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); - uip_connr->tcpstateflags = UIP_SYN_RCVD; - - uip_connr->snd_nxt[0] = iss[0]; - uip_connr->snd_nxt[1] = iss[1]; - uip_connr->snd_nxt[2] = iss[2]; - uip_connr->snd_nxt[3] = iss[3]; - uip_connr->len = 1; - - /* rcv_nxt should be the seqno from the incoming packet + 1. */ - uip_connr->rcv_nxt[3] = BUF->seqno[3]; - uip_connr->rcv_nxt[2] = BUF->seqno[2]; - uip_connr->rcv_nxt[1] = BUF->seqno[1]; - uip_connr->rcv_nxt[0] = BUF->seqno[0]; - uip_add_rcv_nxt(1); - - /* Parse the TCP MSS option, if present. */ - if((BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = uip_connr->mss = - tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - - /* Our response will be a SYNACK. */ -#if UIP_ACTIVE_OPEN - tcp_send_synack: - BUF->flags = TCP_ACK; - - tcp_send_syn: - BUF->flags |= TCP_SYN; -#else /* UIP_ACTIVE_OPEN */ - tcp_send_synack: - BUF->flags = TCP_SYN | TCP_ACK; -#endif /* UIP_ACTIVE_OPEN */ - - /* We send out the TCP Maximum Segment Size option with our - SYNACK. */ - BUF->optdata[0] = TCP_OPT_MSS; - BUF->optdata[1] = TCP_OPT_MSS_LEN; - BUF->optdata[2] = (UIP_TCP_MSS) / 256; - BUF->optdata[3] = (UIP_TCP_MSS) & 255; - uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; - BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; - goto tcp_send; - - /* This label will be jumped to if we found an active connection. */ - found: - uip_conn = uip_connr; - uip_flags = 0; - /* We do a very naive form of TCP reset processing; we just accept - any RST and kill our connection. We should in fact check if the - sequence number of this reset is wihtin our advertised window - before we accept the reset. */ - if(BUF->flags & TCP_RST) { - uip_connr->tcpstateflags = UIP_CLOSED; - UIP_LOG("tcp: got reset, aborting connection."); - uip_flags = UIP_ABORT; - UIP_APPCALL(); - goto drop; - } - /* Calculated the length of the data, if the application has sent - any data to us. */ - c = (BUF->tcpoffset >> 4) << 2; - /* uip_len will contain the length of the actual TCP data. This is - calculated by subtracing the length of the TCP header (in - c) and the length of the IP header (20 bytes). */ - uip_len = uip_len - c - UIP_IPH_LEN; - - /* First, check if the sequence number of the incoming packet is - what we're expecting next. If not, we send out an ACK with the - correct numbers in. */ - if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && - ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { - if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && - (BUF->seqno[0] != uip_connr->rcv_nxt[0] || - BUF->seqno[1] != uip_connr->rcv_nxt[1] || - BUF->seqno[2] != uip_connr->rcv_nxt[2] || - BUF->seqno[3] != uip_connr->rcv_nxt[3])) { - goto tcp_send_ack; - } - } - - /* Next, check if the incoming segment acknowledges any outstanding - data. If so, we update the sequence number, reset the length of - the outstanding data, calculate RTT estimations, and reset the - retransmission timer. */ - if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) { - uip_add32(uip_connr->snd_nxt, uip_connr->len); - - if(BUF->ackno[0] == uip_acc32[0] && - BUF->ackno[1] == uip_acc32[1] && - BUF->ackno[2] == uip_acc32[2] && - BUF->ackno[3] == uip_acc32[3]) { - /* Update sequence number. */ - uip_connr->snd_nxt[0] = uip_acc32[0]; - uip_connr->snd_nxt[1] = uip_acc32[1]; - uip_connr->snd_nxt[2] = uip_acc32[2]; - uip_connr->snd_nxt[3] = uip_acc32[3]; - - - /* Do RTT estimation, unless we have done retransmissions. */ - if(uip_connr->nrtx == 0) { - signed char m; - m = uip_connr->rto - uip_connr->timer; - /* This is taken directly from VJs original code in his paper */ - m = m - (uip_connr->sa >> 3); - uip_connr->sa += m; - if(m < 0) { - m = -m; - } - m = m - (uip_connr->sv >> 2); - uip_connr->sv += m; - uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; - - } - /* Set the acknowledged flag. */ - uip_flags = UIP_ACKDATA; - /* Reset the retransmission timer. */ - uip_connr->timer = uip_connr->rto; - - /* Reset length of outstanding data. */ - uip_connr->len = 0; - } - - } - - /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not - implemented, since we force the application to close when the - peer sends a FIN (hence the application goes directly from - ESTABLISHED to LAST_ACK). */ - case UIP_SYN_RCVD: - /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and - we are waiting for an ACK that acknowledges the data we sent - out the last time. Therefore, we want to have the UIP_ACKDATA - flag set. If so, we enter the ESTABLISHED state. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_flags = UIP_CONNECTED; - uip_connr->len = 0; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - uip_slen = 0; - UIP_APPCALL(); - goto appsend; - } - goto drop; -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In SYN_SENT, we wait for a SYNACK that is sent in response to - our SYN. The rcv_nxt is set to sequence number in the SYNACK - plus one, and we send an ACK. We move into the ESTABLISHED - state. */ - if((uip_flags & UIP_ACKDATA) && - (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { - - /* Parse the TCP MSS option, if present. */ - if((BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = - uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->rcv_nxt[0] = BUF->seqno[0]; - uip_connr->rcv_nxt[1] = BUF->seqno[1]; - uip_connr->rcv_nxt[2] = BUF->seqno[2]; - uip_connr->rcv_nxt[3] = BUF->seqno[3]; - uip_add_rcv_nxt(1); - uip_flags = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - uip_len = 0; - uip_slen = 0; - UIP_APPCALL(); - goto appsend; - } - /* Inform the application that the connection failed */ - uip_flags = UIP_ABORT; - UIP_APPCALL(); - /* The connection is closed after we send the RST */ - uip_conn->tcpstateflags = UIP_CLOSED; - goto reset; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application to feed - data into the uip_buf. If the UIP_ACKDATA flag is set, the - application should put new data into the buffer, otherwise we are - retransmitting an old segment, and the application should put that - data into the buffer. - - If the incoming packet is a FIN, we should close the connection on - this side as well, and we send out a FIN and enter the LAST_ACK - state. We require that there is no outstanding data; otherwise the - sequence numbers will be screwed up. */ - - if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - if(uip_outstanding(uip_connr)) { - goto drop; - } - uip_add_rcv_nxt(1 + uip_len); - uip_flags |= UIP_CLOSE; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - } - UIP_APPCALL(); - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_LAST_ACK; - uip_connr->nrtx = 0; - tcp_send_finack: - BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* Check the URG flag. If this is set, the segment carries urgent - data that we must pass to the application. */ - if((BUF->flags & TCP_URG) != 0) { -#if UIP_URGDATA > 0 - uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1]; - if(uip_urglen > uip_len) { - /* There is more urgent data in the next segment to come. */ - uip_urglen = uip_len; - } - uip_add_rcv_nxt(uip_urglen); - uip_len -= uip_urglen; - uip_urgdata = uip_appdata; - uip_appdata += uip_urglen; - } else { - uip_urglen = 0; -#else /* UIP_URGDATA > 0 */ - uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]); - uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1]; -#endif /* UIP_URGDATA > 0 */ - } - - /* If uip_len > 0 we have TCP data in the packet, and we flag this - by setting the UIP_NEWDATA flag and update the sequence number - we acknowledge. If the application has stopped the dataflow - using uip_stop(), we must not accept any data packets from the - remote host. */ - if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - - /* Check if the available buffer space advertised by the other end - is smaller than the initial MSS for this connection. If so, we - set the current MSS to the window size to ensure that the - application does not send more data than the other end can - handle. - - If the remote host advertises a zero window, we set the MSS to - the initial MSS so that the application will send an entire MSS - of data. This data will not be acknowledged by the receiver, - and the application will retransmit it. This is called the - "persistent timer" and uses the retransmission mechanim. - */ - tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1]; - if(tmp16 > uip_connr->initialmss || - tmp16 == 0) { - tmp16 = uip_connr->initialmss; - } - uip_connr->mss = tmp16; - - /* If this packet constitutes an ACK for outstanding data (flagged - by the UIP_ACKDATA flag, we should call the application since it - might want to send more data. If the incoming packet had data - from the peer (as flagged by the UIP_NEWDATA flag), the - application must also be notified. - - When the application is called, the global variable uip_len - contains the length of the incoming data. The application can - access the incoming data through the global pointer - uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN - bytes into the uip_buf array. - - If the application wishes to send any data, this data should be - put into the uip_appdata and the length of the data should be - put into uip_len. If the application don't have any data to - send, uip_len must be set to 0. */ - if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { - uip_slen = 0; - UIP_APPCALL(); - - appsend: - - if(uip_flags & UIP_ABORT) { - uip_slen = 0; - uip_connr->tcpstateflags = UIP_CLOSED; - BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - if(uip_flags & UIP_CLOSE) { - uip_slen = 0; - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_FIN_WAIT_1; - uip_connr->nrtx = 0; - BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* If uip_slen > 0, the application has data to be sent. */ - if(uip_slen > 0) { - - /* If the connection has acknowledged data, the contents of - the ->len variable should be discarded. */ - if((uip_flags & UIP_ACKDATA) != 0) { - uip_connr->len = 0; - } - - /* If the ->len variable is non-zero the connection has - already data in transit and cannot send anymore right - now. */ - if(uip_connr->len == 0) { - - /* The application cannot send more than what is allowed by - the mss (the minumum of the MSS and the available - window). */ - if(uip_slen > uip_connr->mss) { - uip_slen = uip_connr->mss; - } - - /* Remember how much data we send out now so that we know - when everything has been acknowledged. */ - uip_connr->len = uip_slen; - } else { - - /* If the application already had unacknowledged data, we - make sure that the application does not send (i.e., - retransmit) out more than it previously sent out. */ - uip_slen = uip_connr->len; - } - } - uip_connr->nrtx = 0; - apprexmit: - uip_appdata = uip_sappdata; - - /* If the application has data to be sent, or if the incoming - packet had new data in it, we must send out a packet. */ - if(uip_slen > 0 && uip_connr->len > 0) { - /* Add the length of the IP and TCP headers. */ - uip_len = uip_connr->len + UIP_TCPIP_HLEN; - /* We always set the ACK flag in response packets. */ - BUF->flags = TCP_ACK | TCP_PSH; - /* Send the packet. */ - goto tcp_send_noopts; - } - /* If there is no data to send, just send out a pure ACK if - there is newdata. */ - if(uip_flags & UIP_NEWDATA) { - uip_len = UIP_TCPIP_HLEN; - BUF->flags = TCP_ACK; - goto tcp_send_noopts; - } - } - goto drop; - case UIP_LAST_ACK: - /* We can close this connection if the peer has acknowledged our - FIN. This is indicated by the UIP_ACKDATA flag. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_CLOSED; - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - } - break; - - case UIP_FIN_WAIT_1: - /* The application has closed the connection, but the remote host - hasn't closed its end yet. Thus we do nothing but wait for a - FIN from the other side. */ - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(BUF->flags & TCP_FIN) { - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; - } else { - uip_connr->tcpstateflags = UIP_CLOSING; - } - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } else if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_FIN_WAIT_2; - uip_connr->len = 0; - goto drop; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_FIN_WAIT_2: - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(BUF->flags & TCP_FIN) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_TIME_WAIT: - goto tcp_send_ack; - - case UIP_CLOSING: - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - } - } - goto drop; - - - /* We jump here when we are ready to send the packet, and just want - to set the appropriate TCP sequence numbers in the TCP header. */ - tcp_send_ack: - BUF->flags = TCP_ACK; - tcp_send_nodata: - uip_len = UIP_IPTCPH_LEN; - tcp_send_noopts: - BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; - tcp_send: - /* We're done with the input processing. We are now ready to send a - reply. Our job is to fill in all the fields of the TCP and IP - headers before calculating the checksum and finally send the - packet. */ - BUF->ackno[0] = uip_connr->rcv_nxt[0]; - BUF->ackno[1] = uip_connr->rcv_nxt[1]; - BUF->ackno[2] = uip_connr->rcv_nxt[2]; - BUF->ackno[3] = uip_connr->rcv_nxt[3]; - - BUF->seqno[0] = uip_connr->snd_nxt[0]; - BUF->seqno[1] = uip_connr->snd_nxt[1]; - BUF->seqno[2] = uip_connr->snd_nxt[2]; - BUF->seqno[3] = uip_connr->snd_nxt[3]; - - BUF->proto = UIP_PROTO_TCP; - - BUF->srcport = uip_connr->lport; - BUF->destport = uip_connr->rport; - - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); - - if(uip_connr->tcpstateflags & UIP_STOPPED) { - /* If the connection has issued uip_stop(), we advertise a zero - window so that the remote host will stop sending data. */ - BUF->wnd[0] = BUF->wnd[1] = 0; - } else { - BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); - BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); - } - - tcp_send_noconn: - BUF->ttl = UIP_TTL; -#if UIP_CONF_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ - BUF->len[0] = (uip_len >> 8); - BUF->len[1] = (uip_len & 0xff); -#endif /* UIP_CONF_IPV6 */ - - BUF->urgp[0] = BUF->urgp[1] = 0; - - /* Calculate TCP checksum. */ - BUF->tcpchksum = 0; - BUF->tcpchksum = ~(uip_tcpchksum()); - - ip_send_nolen: - -#if UIP_CONF_IPV6 - BUF->vtc = 0x60; - BUF->tcflow = 0x00; - BUF->flow = 0x00; -#else /* UIP_CONF_IPV6 */ - BUF->vhl = 0x45; - BUF->tos = 0; - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - ++ipid; - BUF->ipid[0] = ipid >> 8; - BUF->ipid[1] = ipid & 0xff; - /* Calculate IP checksum. */ - BUF->ipchksum = 0; - BUF->ipchksum = ~(uip_ipchksum()); - DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); -#endif /* UIP_CONF_IPV6 */ - - UIP_STAT(++uip_stat.tcp.sent); - send: - DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, - (BUF->len[0] << 8) | BUF->len[1]); - - UIP_STAT(++uip_stat.ip.sent); - /* Return and let the caller do the actual transmission. */ - uip_flags = 0; - return; - drop: - uip_len = 0; - uip_flags = 0; - return; -} -/*---------------------------------------------------------------------------*/ -u16_t -htons(u16_t val) -{ - return HTONS(val); -} -/*---------------------------------------------------------------------------*/ -void -uip_send(const void *data, int len) -{ - uip_slen = len; - if(len > 0) { - if(data != uip_sappdata) { - memcpy(uip_sappdata, (data), uip_slen); - } - } -} -/** @} */ diff --git a/libraries/UIPEthernet/utility/uip.h b/libraries/UIPEthernet/utility/uip.h deleted file mode 100644 index 4fc0452..0000000 --- a/libraries/UIPEthernet/utility/uip.h +++ /dev/null @@ -1,1601 +0,0 @@ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \file - * Header file for the uIP TCP/IP stack. - * \author Adam Dunkels - * - * The uIP TCP/IP stack header file contains definitions for a number - * of C macros that are used by uIP programs as well as internal uIP - * structures, TCP/IP header structures and function declarations. - * - */ - - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $ - * - */ - -#ifndef __UIP_H__ -#define __UIP_H__ - -#include "uipopt.h" - -/** - * Repressentation of an IP address. - * - */ -typedef u16_t uip_ip4addr_t[2]; -typedef u16_t uip_ip6addr_t[8]; -#if UIP_CONF_IPV6 -typedef uip_ip6addr_t uip_ipaddr_t; -#else /* UIP_CONF_IPV6 */ -typedef uip_ip4addr_t uip_ipaddr_t; -#endif /* UIP_CONF_IPV6 */ - -/*---------------------------------------------------------------------------*/ -/* First, the functions that should be called from the - * system. Initialization, the periodic timer and incoming packets are - * handled by the following three functions. - */ - -/** - * \defgroup uipconffunc uIP configuration functions - * @{ - * - * The uIP configuration functions are used for setting run-time - * parameters in uIP such as IP addresses. - */ - -/** - * Set the IP address of this host. - * - * The IP address is represented as a 4-byte array where the first - * octet of the IP address is put in the first member of the 4-byte - * array. - * - * Example: - \code - - uip_ipaddr_t addr; - - uip_ipaddr(&addr, 192,168,1,2); - uip_sethostaddr(&addr); - - \endcode - * \param addr A pointer to an IP address of type uip_ipaddr_t; - * - * \sa uip_ipaddr() - * - * \hideinitializer - */ -#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr)) - -/** - * Get the IP address of this host. - * - * The IP address is represented as a 4-byte array where the first - * octet of the IP address is put in the first member of the 4-byte - * array. - * - * Example: - \code - uip_ipaddr_t hostaddr; - - uip_gethostaddr(&hostaddr); - \endcode - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the currently configured IP address. - * - * \hideinitializer - */ -#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr) - -/** - * Set the default router's IP address. - * - * \param addr A pointer to a uip_ipaddr_t variable containing the IP - * address of the default router. - * - * \sa uip_ipaddr() - * - * \hideinitializer - */ -#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr)) - -/** - * Set the netmask. - * - * \param addr A pointer to a uip_ipaddr_t variable containing the IP - * address of the netmask. - * - * \sa uip_ipaddr() - * - * \hideinitializer - */ -#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr)) - - -/** - * Get the default router's IP address. - * - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the IP address of the default router. - * - * \hideinitializer - */ -#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr) - -/** - * Get the netmask. - * - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the value of the netmask. - * - * \hideinitializer - */ -#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) - -/** @} */ - -/** - * \defgroup uipinit uIP initialization functions - * @{ - * - * The uIP initialization functions are used for booting uIP. - */ - -/** - * uIP initialization function. - * - * This function should be called at boot up to initilize the uIP - * TCP/IP stack. - */ -void uip_init(void); - -/** - * uIP initialization function. - * - * This function may be used at boot time to set the initial ip_id. - */ -void uip_setipid(u16_t id); - -/** @} */ - -/** - * \defgroup uipdevfunc uIP device driver functions - * @{ - * - * These functions are used by a network device driver for interacting - * with uIP. - */ - -/** - * Process an incoming packet. - * - * This function should be called when the device driver has received - * a packet from the network. The packet from the device driver must - * be present in the uip_buf buffer, and the length of the packet - * should be placed in the uip_len variable. - * - * When the function returns, there may be an outbound packet placed - * in the uip_buf packet buffer. If so, the uip_len variable is set to - * the length of the packet. If no packet is to be sent out, the - * uip_len variable is set to 0. - * - * The usual way of calling the function is presented by the source - * code below. - \code - uip_len = devicedriver_poll(); - if(uip_len > 0) { - uip_input(); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note If you are writing a uIP device driver that needs ARP - * (Address Resolution Protocol), e.g., when running uIP over - * Ethernet, you will need to call the uIP ARP code before calling - * this function: - \code - #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) - uip_len = ethernet_devicedrver_poll(); - if(uip_len > 0) { - if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { - uip_arp_ipin(); - uip_input(); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(); - if(uip_len > 0) { - ethernet_devicedriver_send(); - } - } - \endcode - * - * \hideinitializer - */ -#define uip_input() uip_process(UIP_DATA) - -/** - * Periodic processing for a connection identified by its number. - * - * This function does the necessary periodic processing (timers, - * polling) for a uIP TCP conneciton, and should be called when the - * periodic uIP timer goes off. It should be called for every - * connection, regardless of whether they are open of closed. - * - * When the function returns, it may have an outbound packet waiting - * for service in the uIP packet buffer, and if so the uip_len - * variable is set to a value larger than zero. The device driver - * should be called to send out the packet. - * - * The ususal way of calling the function is through a for() loop like - * this: - \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note If you are writing a uIP device driver that needs ARP - * (Address Resolution Protocol), e.g., when running uIP over - * Ethernet, you will need to call the uip_arp_out() function before - * calling the device driver: - \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } - \endcode - * - * \param conn The number of the connection which is to be periodically polled. - * - * \hideinitializer - */ -#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \ - uip_process(UIP_TIMER); } while (0) - -/** - * - * - */ -#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) - -/** - * Perform periodic processing for a connection identified by a pointer - * to its structure. - * - * Same as uip_periodic() but takes a pointer to the actual uip_conn - * struct instead of an integer as its argument. This function can be - * used to force periodic processing of a specific connection. - * - * \param conn A pointer to the uip_conn struct for the connection to - * be processed. - * - * \hideinitializer - */ -#define uip_periodic_conn(conn) do { uip_conn = conn; \ - uip_process(UIP_TIMER); } while (0) - -/** - * Reuqest that a particular connection should be polled. - * - * Similar to uip_periodic_conn() but does not perform any timer - * processing. The application is polled for new data. - * - * \param conn A pointer to the uip_conn struct for the connection to - * be processed. - * - * \hideinitializer - */ -#define uip_poll_conn(conn) do { uip_conn = conn; \ - uip_process(UIP_POLL_REQUEST); } while (0) - - -#if UIP_UDP -/** - * Periodic processing for a UDP connection identified by its number. - * - * This function is essentially the same as uip_periodic(), but for - * UDP connections. It is called in a similar fashion as the - * uip_periodic() function: - \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note As for the uip_periodic() function, special care has to be - * taken when using uIP together with ARP and Ethernet: - \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } - \endcode - * - * \param conn The number of the UDP connection to be processed. - * - * \hideinitializer - */ -#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ - uip_process(UIP_UDP_TIMER); } while (0) - -/** - * Periodic processing for a UDP connection identified by a pointer to - * its structure. - * - * Same as uip_udp_periodic() but takes a pointer to the actual - * uip_conn struct instead of an integer as its argument. This - * function can be used to force periodic processing of a specific - * connection. - * - * \param conn A pointer to the uip_udp_conn struct for the connection - * to be processed. - * - * \hideinitializer - */ -#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ - uip_process(UIP_UDP_TIMER); } while (0) - - -#endif /* UIP_UDP */ - -/** - * The uIP packet buffer. - * - * The uip_buf array is used to hold incoming and outgoing - * packets. The device driver should place incoming data into this - * buffer. When sending data, the device driver should read the link - * level headers and the TCP/IP headers from this buffer. The size of - * the link level headers is configured by the UIP_LLH_LEN define. - * - * \note The application data need not be placed in this buffer, so - * the device driver must read it from the place pointed to by the - * uip_appdata pointer as illustrated by the following example: - \code - void - devicedriver_send(void) - { - hwsend(&uip_buf[0], UIP_LLH_LEN); - if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { - hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); - } else { - hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); - hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); - } - } - \endcode - */ -extern u8_t uip_buf[UIP_BUFSIZE+2]; - -/** @} */ - -/*---------------------------------------------------------------------------*/ -/* Functions that are used by the uIP application program. Opening and - * closing connections, sending and receiving data, etc. is all - * handled by the functions below. -*/ -/** - * \defgroup uipappfunc uIP application functions - * @{ - * - * Functions used by an application running of top of uIP. - */ - -/** - * Start listening to the specified port. - * - * \note Since this function expects the port number in network byte - * order, a conversion using HTONS() or htons() is necessary. - * - \code - uip_listen(HTONS(80)); - \endcode - * - * \param port A 16-bit port number in network byte order. - */ -void uip_listen(u16_t port); - -/** - * Stop listening to the specified port. - * - * \note Since this function expects the port number in network byte - * order, a conversion using HTONS() or htons() is necessary. - * - \code - uip_unlisten(HTONS(80)); - \endcode - * - * \param port A 16-bit port number in network byte order. - */ -void uip_unlisten(u16_t port); - -/** - * Connect to a remote host using TCP. - * - * This function is used to start a new connection to the specified - * port on the specied host. It allocates a new connection identifier, - * sets the connection to the SYN_SENT state and sets the - * retransmission timer to 0. This will cause a TCP SYN segment to be - * sent out the next time this connection is periodically processed, - * which usually is done within 0.5 seconds after the call to - * uip_connect(). - * - * \note This function is avaliable only if support for active open - * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h. - * - * \note Since this function requires the port number to be in network - * byte order, a conversion using HTONS() or htons() is necessary. - * - \code - uip_ipaddr_t ipaddr; - - uip_ipaddr(&ipaddr, 192,168,1,2); - uip_connect(&ipaddr, HTONS(80)); - \endcode - * - * \param ripaddr The IP address of the remote hot. - * - * \param port A 16-bit port number in network byte order. - * - * \return A pointer to the uIP connection identifier for the new connection, - * or NULL if no connection could be allocated. - * - */ -struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); - - - -/** - * \internal - * - * Check if a connection has outstanding (i.e., unacknowledged) data. - * - * \param conn A pointer to the uip_conn structure for the connection. - * - * \hideinitializer - */ -#define uip_outstanding(conn) ((conn)->len) - -/** - * Send data on the current connection. - * - * This function is used to send out a single segment of TCP - * data. Only applications that have been invoked by uIP for event - * processing can send data. - * - * The amount of data that actually is sent out after a call to this - * funcion is determined by the maximum amount of data TCP allows. uIP - * will automatically crop the data so that only the appropriate - * amount of data is sent. The function uip_mss() can be used to query - * uIP for the amount of data that actually will be sent. - * - * \note This function does not guarantee that the sent data will - * arrive at the destination. If the data is lost in the network, the - * application will be invoked with the uip_rexmit() event being - * set. The application will then have to resend the data using this - * function. - * - * \param data A pointer to the data which is to be sent. - * - * \param len The maximum amount of data bytes to be sent. - * - * \hideinitializer - */ -void uip_send(const void *data, int len); - -/** - * The length of any incoming data that is currently avaliable (if avaliable) - * in the uip_appdata buffer. - * - * The test function uip_data() must first be used to check if there - * is any data available at all. - * - * \hideinitializer - */ -/*void uip_datalen(void);*/ -#define uip_datalen() uip_len - -/** - * The length of any out-of-band data (urgent data) that has arrived - * on the connection. - * - * \note The configuration parameter UIP_URGDATA must be set for this - * function to be enabled. - * - * \hideinitializer - */ -#define uip_urgdatalen() uip_urglen - -/** - * Close the current connection. - * - * This function will close the current connection in a nice way. - * - * \hideinitializer - */ -#define uip_close() (uip_flags = UIP_CLOSE) - -/** - * Abort the current connection. - * - * This function will abort (reset) the current connection, and is - * usually used when an error has occured that prevents using the - * uip_close() function. - * - * \hideinitializer - */ -#define uip_abort() (uip_flags = UIP_ABORT) - -/** - * Tell the sending host to stop sending data. - * - * This function will close our receiver's window so that we stop - * receiving data for the current connection. - * - * \hideinitializer - */ -#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) - -/** - * Find out if the current connection has been previously stopped with - * uip_stop(). - * - * \hideinitializer - */ -#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED) - -/** - * Restart the current connection, if is has previously been stopped - * with uip_stop(). - * - * This function will open the receiver's window again so that we - * start receiving data for the current connection. - * - * \hideinitializer - */ -#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ - uip_conn->tcpstateflags &= ~UIP_STOPPED; \ - } while(0) - - -/* uIP tests that can be made to determine in what state the current - connection is, and what the application function should do. */ - -/** - * Is the current connection a UDP connection? - * - * This function checks whether the current connection is a UDP connection. - * - * \hideinitializer - * - */ -#define uip_udpconnection() (uip_conn == NULL) - -/** - * Is new incoming data available? - * - * Will reduce to non-zero if there is new data for the application - * present at the uip_appdata pointer. The size of the data is - * avaliable through the uip_len variable. - * - * \hideinitializer - */ -#define uip_newdata() (uip_flags & UIP_NEWDATA) - -/** - * Has previously sent data been acknowledged? - * - * Will reduce to non-zero if the previously sent data has been - * acknowledged by the remote host. This means that the application - * can send new data. - * - * \hideinitializer - */ -#define uip_acked() (uip_flags & UIP_ACKDATA) - -/** - * Has the connection just been connected? - * - * Reduces to non-zero if the current connection has been connected to - * a remote host. This will happen both if the connection has been - * actively opened (with uip_connect()) or passively opened (with - * uip_listen()). - * - * \hideinitializer - */ -#define uip_connected() (uip_flags & UIP_CONNECTED) - -/** - * Has the connection been closed by the other end? - * - * Is non-zero if the connection has been closed by the remote - * host. The application may then do the necessary clean-ups. - * - * \hideinitializer - */ -#define uip_closed() (uip_flags & UIP_CLOSE) - -/** - * Has the connection been aborted by the other end? - * - * Non-zero if the current connection has been aborted (reset) by the - * remote host. - * - * \hideinitializer - */ -#define uip_aborted() (uip_flags & UIP_ABORT) - -/** - * Has the connection timed out? - * - * Non-zero if the current connection has been aborted due to too many - * retransmissions. - * - * \hideinitializer - */ -#define uip_timedout() (uip_flags & UIP_TIMEDOUT) - -/** - * Do we need to retransmit previously data? - * - * Reduces to non-zero if the previously sent data has been lost in - * the network, and the application should retransmit it. The - * application should send the exact same data as it did the last - * time, using the uip_send() function. - * - * \hideinitializer - */ -#define uip_rexmit() (uip_flags & UIP_REXMIT) - -/** - * Is the connection being polled by uIP? - * - * Is non-zero if the reason the application is invoked is that the - * current connection has been idle for a while and should be - * polled. - * - * The polling event can be used for sending data without having to - * wait for the remote host to send data. - * - * \hideinitializer - */ -#define uip_poll() (uip_flags & UIP_POLL) - -/** - * Get the initial maxium segment size (MSS) of the current - * connection. - * - * \hideinitializer - */ -#define uip_initialmss() (uip_conn->initialmss) - -/** - * Get the current maxium segment size that can be sent on the current - * connection. - * - * The current maxiumum segment size that can be sent on the - * connection is computed from the receiver's window and the MSS of - * the connection (which also is available by calling - * uip_initialmss()). - * - * \hideinitializer - */ -#define uip_mss() (uip_conn->mss) - -/** - * Set up a new UDP connection. - * - * This function sets up a new UDP connection. The function will - * automatically allocate an unused local port for the new - * connection. However, another port can be chosen by using the - * uip_udp_bind() call, after the uip_udp_new() function has been - * called. - * - * Example: - \code - uip_ipaddr_t addr; - struct uip_udp_conn *c; - - uip_ipaddr(&addr, 192,168,2,1); - c = uip_udp_new(&addr, HTONS(12345)); - if(c != NULL) { - uip_udp_bind(c, HTONS(12344)); - } - \endcode - * \param ripaddr The IP address of the remote host. - * - * \param rport The remote port number in network byte order. - * - * \return The uip_udp_conn structure for the new connection or NULL - * if no connection could be allocated. - */ -struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); - -/** - * Removed a UDP connection. - * - * \param conn A pointer to the uip_udp_conn structure for the connection. - * - * \hideinitializer - */ -#define uip_udp_remove(conn) (conn)->lport = 0 - -/** - * Bind a UDP connection to a local port. - * - * \param conn A pointer to the uip_udp_conn structure for the - * connection. - * - * \param port The local port number, in network byte order. - * - * \hideinitializer - */ -#define uip_udp_bind(conn, port) (conn)->lport = port - -/** - * Send a UDP datagram of length len on the current connection. - * - * This function can only be called in response to a UDP event (poll - * or newdata). The data must be present in the uip_buf buffer, at the - * place pointed to by the uip_appdata pointer. - * - * \param len The length of the data in the uip_buf buffer. - * - * \hideinitializer - */ -#define uip_udp_send(len) uip_send((char *)uip_appdata, len) - -/** @} */ - -/* uIP convenience and converting functions. */ - -/** - * \defgroup uipconvfunc uIP conversion functions - * @{ - * - * These functions can be used for converting between different data - * formats used by uIP. - */ - -/** - * Construct an IP address from four bytes. - * - * This function constructs an IP address of the type that uIP handles - * internally from four bytes. The function is handy for specifying IP - * addresses to use with e.g. the uip_connect() function. - * - * Example: - \code - uip_ipaddr_t ipaddr; - struct uip_conn *c; - - uip_ipaddr(&ipaddr, 192,168,1,2); - c = uip_connect(&ipaddr, HTONS(80)); - \endcode - * - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the IP address. - * - * \param addr0 The first octet of the IP address. - * \param addr1 The second octet of the IP address. - * \param addr2 The third octet of the IP address. - * \param addr3 The forth octet of the IP address. - * - * \hideinitializer - */ -#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ - ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \ - ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \ - } while(0) - -/** - * Construct an IPv6 address from eight 16-bit words. - * - * This function constructs an IPv6 address. - * - * \hideinitializer - */ -#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \ - ((u16_t *)(addr))[0] = HTONS((addr0)); \ - ((u16_t *)(addr))[1] = HTONS((addr1)); \ - ((u16_t *)(addr))[2] = HTONS((addr2)); \ - ((u16_t *)(addr))[3] = HTONS((addr3)); \ - ((u16_t *)(addr))[4] = HTONS((addr4)); \ - ((u16_t *)(addr))[5] = HTONS((addr5)); \ - ((u16_t *)(addr))[6] = HTONS((addr6)); \ - ((u16_t *)(addr))[7] = HTONS((addr7)); \ - } while(0) - -/** - * Copy an IP address to another IP address. - * - * Copies an IP address from one place to another. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2; - - uip_ipaddr(&ipaddr1, 192,16,1,2); - uip_ipaddr_copy(&ipaddr2, &ipaddr1); - \endcode - * - * \param dest The destination for the copy. - * \param src The source from where to copy. - * - * \hideinitializer - */ -#if !UIP_CONF_IPV6 -#define uip_ipaddr_copy(dest, src) do { \ - ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \ - ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \ - } while(0) -#else /* !UIP_CONF_IPV6 */ -#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) -#endif /* !UIP_CONF_IPV6 */ - -/** - * Compare two IP addresses - * - * Compares two IP addresses. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2; - - uip_ipaddr(&ipaddr1, 192,16,1,2); - if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { - printf("They are the same"); - } - \endcode - * - * \param addr1 The first IP address. - * \param addr2 The second IP address. - * - * \hideinitializer - */ -#if !UIP_CONF_IPV6 -#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \ - ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1]) -#else /* !UIP_CONF_IPV6 */ -#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) -#endif /* !UIP_CONF_IPV6 */ - -/** - * Compare two IP addresses with netmasks - * - * Compares two IP addresses with netmasks. The masks are used to mask - * out the bits that are to be compared. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2, mask; - - uip_ipaddr(&mask, 255,255,255,0); - uip_ipaddr(&ipaddr1, 192,16,1,2); - uip_ipaddr(&ipaddr2, 192,16,1,3); - if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { - printf("They are the same"); - } - \endcode - * - * \param addr1 The first IP address. - * \param addr2 The second IP address. - * \param mask The netmask. - * - * \hideinitializer - */ -#define uip_ipaddr_maskcmp(addr1, addr2, mask) \ - (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \ - (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \ - ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \ - (((u16_t *)addr2)[1] & ((u16_t *)mask)[1]))) - - -/** - * Mask out the network part of an IP address. - * - * Masks out the network part of an IP address, given the address and - * the netmask. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2, netmask; - - uip_ipaddr(&ipaddr1, 192,16,1,2); - uip_ipaddr(&netmask, 255,255,255,0); - uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask); - \endcode - * - * In the example above, the variable "ipaddr2" will contain the IP - * address 192.168.1.0. - * - * \param dest Where the result is to be placed. - * \param src The IP address. - * \param mask The netmask. - * - * \hideinitializer - */ -#define uip_ipaddr_mask(dest, src, mask) do { \ - ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \ - ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \ - } while(0) - -/** - * Pick the first octet of an IP address. - * - * Picks out the first octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - u8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr1(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 1. - * - * \hideinitializer - */ -#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8) - -/** - * Pick the second octet of an IP address. - * - * Picks out the second octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - u8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr2(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 2. - * - * \hideinitializer - */ -#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff) - -/** - * Pick the third octet of an IP address. - * - * Picks out the third octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - u8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr3(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 3. - * - * \hideinitializer - */ -#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8) - -/** - * Pick the fourth octet of an IP address. - * - * Picks out the fourth octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - u8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr4(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 4. - * - * \hideinitializer - */ -#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff) - -/** - * Convert 16-bit quantity from host byte order to network byte order. - * - * This macro is primarily used for converting constants from host - * byte order to network byte order. For converting variables to - * network byte order, use the htons() function instead. - * - * \hideinitializer - */ -#ifndef HTONS -# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN -# define HTONS(n) (n) -# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ -# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) -# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ -#else -#error "HTONS already defined!" -#endif /* HTONS */ - -/** - * Convert 16-bit quantity from host byte order to network byte order. - * - * This function is primarily used for converting variables from host - * byte order to network byte order. For converting constants to - * network byte order, use the HTONS() macro instead. - */ -#ifndef htons -u16_t htons(u16_t val); -#endif /* htons */ -#ifndef ntohs -#define ntohs htons -#endif - -/** @} */ - -/** - * Pointer to the application data in the packet buffer. - * - * This pointer points to the application data when the application is - * called. If the application wishes to send data, the application may - * use this space to write the data into before calling uip_send(). - */ -extern void *uip_appdata; - -#if UIP_URGDATA > 0 -/* u8_t *uip_urgdata: - * - * This pointer points to any urgent data that has been received. Only - * present if compiled with support for urgent data (UIP_URGDATA). - */ -extern void *uip_urgdata; -#endif /* UIP_URGDATA > 0 */ - - -/** - * \defgroup uipdrivervars Variables used in uIP device drivers - * @{ - * - * uIP has a few global variables that are used in device drivers for - * uIP. - */ - -/** - * The length of the packet in the uip_buf buffer. - * - * The global variable uip_len holds the length of the packet in the - * uip_buf buffer. - * - * When the network device driver calls the uIP input function, - * uip_len should be set to the length of the packet in the uip_buf - * buffer. - * - * When sending packets, the device driver should use the contents of - * the uip_len variable to determine the length of the outgoing - * packet. - * - */ -extern u16_t uip_len; - -/** @} */ - -#if UIP_URGDATA > 0 -extern u16_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - - -/** - * Representation of a uIP TCP connection. - * - * The uip_conn structure is used for identifying a connection. All - * but one field in the structure are to be considered read-only by an - * application. The only exception is the appstate field whos purpose - * is to let the application store application-specific state (e.g., - * file pointers) for the connection. The type of this field is - * configured in the "uipopt.h" header file. - */ -struct uip_conn { - uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */ - - u16_t lport; /**< The local TCP port, in network byte order. */ - u16_t rport; /**< The local remote TCP port, in network byte - order. */ - - u8_t rcv_nxt[4]; /**< The sequence number that we expect to - receive next. */ - u8_t snd_nxt[4]; /**< The sequence number that was last sent by - us. */ - u16_t len; /**< Length of the data that was previously sent. */ - u16_t mss; /**< Current maximum segment size for the - connection. */ - u16_t initialmss; /**< Initial maximum segment size for the - connection. */ - u8_t sa; /**< Retransmission time-out calculation state - variable. */ - u8_t sv; /**< Retransmission time-out calculation state - variable. */ - u8_t rto; /**< Retransmission time-out. */ - u8_t tcpstateflags; /**< TCP state and flags. */ - u8_t timer; /**< The retransmission timer. */ - u8_t nrtx; /**< The number of retransmissions for the last - segment sent. */ - - /** The application state. */ - uip_tcp_appstate_t appstate; -}; - - -/** - * Pointer to the current TCP connection. - * - * The uip_conn pointer can be used to access the current TCP - * connection. - */ -extern struct uip_conn *uip_conn; -/* The array containing all uIP connections. */ -extern struct uip_conn uip_conns[UIP_CONNS]; -/** - * \addtogroup uiparch - * @{ - */ - -/** - * 4-byte array used for the 32-bit sequence number calculations. - */ -extern u8_t uip_acc32[4]; - -/** @} */ - - -#if UIP_UDP -/** - * Representation of a uIP UDP connection. - */ -struct uip_udp_conn { - uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */ - u16_t lport; /**< The local port number in network byte order. */ - u16_t rport; /**< The remote port number in network byte order. */ - u8_t ttl; /**< Default time-to-live. */ - - /** The application state. */ - uip_udp_appstate_t appstate; -}; - -/** - * The current UDP connection. - */ -extern struct uip_udp_conn *uip_udp_conn; -extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; -#endif /* UIP_UDP */ - -/** - * The structure holding the TCP/IP statistics that are gathered if - * UIP_STATISTICS is set to 1. - * - */ -struct uip_stats { - struct { - uip_stats_t drop; /**< Number of dropped packets at the IP - layer. */ - uip_stats_t recv; /**< Number of received packets at the IP - layer. */ - uip_stats_t sent; /**< Number of sent packets at the IP - layer. */ - uip_stats_t vhlerr; /**< Number of packets dropped due to wrong - IP version or header length. */ - uip_stats_t hblenerr; /**< Number of packets dropped due to wrong - IP length, high byte. */ - uip_stats_t lblenerr; /**< Number of packets dropped due to wrong - IP length, low byte. */ - uip_stats_t fragerr; /**< Number of packets dropped since they - were IP fragments. */ - uip_stats_t chkerr; /**< Number of packets dropped due to IP - checksum errors. */ - uip_stats_t protoerr; /**< Number of packets dropped since they - were neither ICMP, UDP nor TCP. */ - } ip; /**< IP statistics. */ - struct { - uip_stats_t drop; /**< Number of dropped ICMP packets. */ - uip_stats_t recv; /**< Number of received ICMP packets. */ - uip_stats_t sent; /**< Number of sent ICMP packets. */ - uip_stats_t typeerr; /**< Number of ICMP packets with a wrong - type. */ - } icmp; /**< ICMP statistics. */ - struct { - uip_stats_t drop; /**< Number of dropped TCP segments. */ - uip_stats_t recv; /**< Number of recived TCP segments. */ - uip_stats_t sent; /**< Number of sent TCP segments. */ - uip_stats_t chkerr; /**< Number of TCP segments with a bad - checksum. */ - uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK - number. */ - uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */ - uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */ - uip_stats_t syndrop; /**< Number of dropped SYNs due to too few - connections was avaliable. */ - uip_stats_t synrst; /**< Number of SYNs for closed ports, - triggering a RST. */ - } tcp; /**< TCP statistics. */ -#if UIP_UDP - struct { - uip_stats_t drop; /**< Number of dropped UDP segments. */ - uip_stats_t recv; /**< Number of recived UDP segments. */ - uip_stats_t sent; /**< Number of sent UDP segments. */ - uip_stats_t chkerr; /**< Number of UDP segments with a bad - checksum. */ - } udp; /**< UDP statistics. */ -#endif /* UIP_UDP */ -}; - -/** - * The uIP TCP/IP statistics. - * - * This is the variable in which the uIP TCP/IP statistics are gathered. - */ -extern struct uip_stats uip_stat; - - -/*---------------------------------------------------------------------------*/ -/* All the stuff below this point is internal to uIP and should not be - * used directly by an application or by a device driver. - */ -/*---------------------------------------------------------------------------*/ -/* u8_t uip_flags: - * - * When the application is called, uip_flags will contain the flags - * that are defined in this file. Please read below for more - * infomation. - */ -extern u8_t uip_flags; - -/* The following flags may be set in the global variable uip_flags - before calling the application callback. The UIP_ACKDATA, - UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time, - whereas the others are mutualy exclusive. Note that these flags - should *NOT* be accessed directly, but only through the uIP - functions/macros. */ - -#define UIP_ACKDATA 1 /* Signifies that the outstanding data was - acked and the application should send - out new data instead of retransmitting - the last data. */ -#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent - us new data. */ -#define UIP_REXMIT 4 /* Tells the application to retransmit the - data that was last sent. */ -#define UIP_POLL 8 /* Used for polling the application, to - check if the application has data that - it wants to send. */ -#define UIP_CLOSE 16 /* The remote host has closed the - connection, thus the connection has - gone away. Or the application signals - that it wants to close the - connection. */ -#define UIP_ABORT 32 /* The remote host has aborted the - connection, thus the connection has - gone away. Or the application signals - that it wants to abort the - connection. */ -#define UIP_CONNECTED 64 /* We have got a connection from a remote - host and have set up a new connection - for it, or an active connection has - been successfully established. */ - -#define UIP_TIMEDOUT 128 /* The connection has been aborted due to - too many retransmissions. */ - -/* uip_process(flag): - * - * The actual uIP function which does all the work. - */ -void uip_process(u8_t flag); - -/* The following flags are passed as an argument to the uip_process() - function. They are used to distinguish between the two cases where - uip_process() is called. It can be called either because we have - incoming data that should be processed, or because the periodic - timer has fired. These values are never used directly, but only in - the macrose defined in this file. */ - -#define UIP_DATA 1 /* Tells uIP that there is incoming - data in the uip_buf buffer. The - length of the data is stored in the - global variable uip_len. */ -#define UIP_TIMER 2 /* Tells uIP that the periodic timer - has fired. */ -#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should - be polled. */ -#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram - should be constructed in the - uip_buf buffer. */ -#if UIP_UDP -#define UIP_UDP_TIMER 5 -#endif /* UIP_UDP */ - -/* The TCP states used in the uip_conn->tcpstateflags. */ -#define UIP_CLOSED 0 -#define UIP_SYN_RCVD 1 -#define UIP_SYN_SENT 2 -#define UIP_ESTABLISHED 3 -#define UIP_FIN_WAIT_1 4 -#define UIP_FIN_WAIT_2 5 -#define UIP_CLOSING 6 -#define UIP_TIME_WAIT 7 -#define UIP_LAST_ACK 8 -#define UIP_TS_MASK 15 - -#define UIP_STOPPED 16 - -/* The TCP and IP headers. */ -struct uip_tcpip_hdr { -#if UIP_CONF_IPV6 - /* IPv6 header. */ - u8_t vtc, - tcflow; - u16_t flow; - u8_t len[2]; - u8_t proto, ttl; - uip_ip6addr_t srcipaddr, destipaddr; -#else /* UIP_CONF_IPV6 */ - /* IPv4 header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; -#endif /* UIP_CONF_IPV6 */ - - /* TCP header. */ - u16_t srcport, - destport; - u8_t seqno[4], - ackno[4], - tcpoffset, - flags, - wnd[2]; - u16_t tcpchksum; - u8_t urgp[2]; - u8_t optdata[4]; -}; - -/* The ICMP and IP headers. */ -struct uip_icmpip_hdr { -#if UIP_CONF_IPV6 - /* IPv6 header. */ - u8_t vtc, - tcf; - u16_t flow; - u8_t len[2]; - u8_t proto, ttl; - uip_ip6addr_t srcipaddr, destipaddr; -#else /* UIP_CONF_IPV6 */ - /* IPv4 header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; -#endif /* UIP_CONF_IPV6 */ - - /* ICMP (echo) header. */ - u8_t type, icode; - u16_t icmpchksum; -#if !UIP_CONF_IPV6 - u16_t id, seqno; -#else /* !UIP_CONF_IPV6 */ - u8_t flags, reserved1, reserved2, reserved3; - u8_t icmp6data[16]; - u8_t options[1]; -#endif /* !UIP_CONF_IPV6 */ -}; - - -/* The UDP and IP headers. */ -struct uip_udpip_hdr { -#if UIP_CONF_IPV6 - /* IPv6 header. */ - u8_t vtc, - tcf; - u16_t flow; - u8_t len[2]; - u8_t proto, ttl; - uip_ip6addr_t srcipaddr, destipaddr; -#else /* UIP_CONF_IPV6 */ - /* IP header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; -#endif /* UIP_CONF_IPV6 */ - - /* UDP header. */ - u16_t srcport, - destport; - u16_t udplen; - u16_t udpchksum; -}; - - - -/** - * The buffer size available for user data in the \ref uip_buf buffer. - * - * This macro holds the available size for user data in the \ref - * uip_buf buffer. The macro is intended to be used for checking - * bounds of available user data. - * - * Example: - \code - snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i); - \endcode - * - * \hideinitializer - */ -#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) - - -#define UIP_PROTO_ICMP 1 -#define UIP_PROTO_TCP 6 -#define UIP_PROTO_UDP 17 -#define UIP_PROTO_ICMP6 58 - -/* Header sizes. */ -#if UIP_CONF_IPV6 -#define UIP_IPH_LEN 40 -#else /* UIP_CONF_IPV6 */ -#define UIP_IPH_LEN 20 /* Size of IP header */ -#endif /* UIP_CONF_IPV6 */ -#define UIP_UDPH_LEN 8 /* Size of UDP header */ -#define UIP_TCPH_LEN 20 /* Size of TCP header */ -#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + - UDP - header */ -#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + - TCP - header */ -#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN - - -#if UIP_FIXEDADDR -extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; -#else /* UIP_FIXEDADDR */ -extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; -#endif /* UIP_FIXEDADDR */ - - - -/** - * Representation of a 48-bit Ethernet address. - */ -struct uip_eth_addr { - u8_t addr[6]; -}; - -/** - * Calculate the Internet checksum over a buffer. - * - * The Internet checksum is the one's complement of the one's - * complement sum of all 16-bit words in the buffer. - * - * See RFC1071. - * - * \param buf A pointer to the buffer over which the checksum is to be - * computed. - * - * \param len The length of the buffer over which the checksum is to - * be computed. - * - * \return The Internet checksum of the buffer. - */ -u16_t uip_chksum(u16_t *buf, u16_t len); - -/** - * Calculate the IP header checksum of the packet header in uip_buf. - * - * The IP header checksum is the Internet checksum of the 20 bytes of - * the IP header. - * - * \return The IP header checksum of the IP header in the uip_buf - * buffer. - */ -u16_t uip_ipchksum(void); - -/** - * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. - * - * The TCP checksum is the Internet checksum of data contents of the - * TCP segment, and a pseudo-header as defined in RFC793. - * - * \return The TCP checksum of the TCP segment in uip_buf and pointed - * to by uip_appdata. - */ -u16_t uip_tcpchksum(void); - -/** - * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. - * - * The UDP checksum is the Internet checksum of data contents of the - * UDP segment, and a pseudo-header as defined in RFC768. - * - * \return The UDP checksum of the UDP segment in uip_buf and pointed - * to by uip_appdata. - */ -u16_t uip_udpchksum(void); - - -#endif /* __UIP_H__ */ - - -/** @} */ diff --git a/libraries/UIPEthernet/utility/uip_arch.h b/libraries/UIPEthernet/utility/uip_arch.h deleted file mode 100644 index 71fd84b..0000000 --- a/libraries/UIPEthernet/utility/uip_arch.h +++ /dev/null @@ -1,138 +0,0 @@ -/** - * \addtogroup uip - * {@ - */ - -/** - * \defgroup uiparch Architecture specific uIP functions - * @{ - * - * The functions in the architecture specific module implement the IP - * check sum and 32-bit additions. - * - * The IP checksum calculation is the most computationally expensive - * operation in the TCP/IP stack and it therefore pays off to - * implement this in efficient assembler. The purpose of the uip-arch - * module is to let the checksum functions to be implemented in - * architecture specific assembler. - * - */ - -/** - * \file - * Declarations of architecture specific functions. - * \author Adam Dunkels - */ - -/* - * Copyright (c) 2001, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $ - * - */ - -#ifndef __UIP_ARCH_H__ -#define __UIP_ARCH_H__ - -#include "uip.h" - -/** - * Carry out a 32-bit addition. - * - * Because not all architectures for which uIP is intended has native - * 32-bit arithmetic, uIP uses an external C function for doing the - * required 32-bit additions in the TCP protocol processing. This - * function should add the two arguments and place the result in the - * global variable uip_acc32. - * - * \note The 32-bit integer pointed to by the op32 parameter and the - * result in the uip_acc32 variable are in network byte order (big - * endian). - * - * \param op32 A pointer to a 4-byte array representing a 32-bit - * integer in network byte order (big endian). - * - * \param op16 A 16-bit integer in host byte order. - */ -void uip_add32(u8_t *op32, u16_t op16); - -/** - * Calculate the Internet checksum over a buffer. - * - * The Internet checksum is the one's complement of the one's - * complement sum of all 16-bit words in the buffer. - * - * See RFC1071. - * - * \note This function is not called in the current version of uIP, - * but future versions might make use of it. - * - * \param buf A pointer to the buffer over which the checksum is to be - * computed. - * - * \param len The length of the buffer over which the checksum is to - * be computed. - * - * \return The Internet checksum of the buffer. - */ -u16_t uip_chksum(u16_t *buf, u16_t len); - -/** - * Calculate the IP header checksum of the packet header in uip_buf. - * - * The IP header checksum is the Internet checksum of the 20 bytes of - * the IP header. - * - * \return The IP header checksum of the IP header in the uip_buf - * buffer. - */ -u16_t uip_ipchksum(void); - -/** - * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. - * - * The TCP checksum is the Internet checksum of data contents of the - * TCP segment, and a pseudo-header as defined in RFC793. - * - * \note The uip_appdata pointer that points to the packet data may - * point anywhere in memory, so it is not possible to simply calculate - * the Internet checksum of the contents of the uip_buf buffer. - * - * \return The TCP checksum of the TCP segment in uip_buf and pointed - * to by uip_appdata. - */ -u16_t uip_tcpchksum(void); - -u16_t uip_udpchksum(void); - -/** @} */ -/** @} */ - -#endif /* __UIP_ARCH_H__ */ diff --git a/libraries/UIPEthernet/utility/uip_arp.c b/libraries/UIPEthernet/utility/uip_arp.c deleted file mode 100644 index 44ca7c4..0000000 --- a/libraries/UIPEthernet/utility/uip_arp.c +++ /dev/null @@ -1,423 +0,0 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uiparp uIP Address Resolution Protocol - * @{ - * - * The Address Resolution Protocol ARP is used for mapping between IP - * addresses and link level addresses such as the Ethernet MAC - * addresses. ARP uses broadcast queries to ask for the link level - * address of a known IP address and the host which is configured with - * the IP address for which the query was meant, will respond with its - * link level address. - * - * \note This ARP implementation only supports Ethernet. - */ - -/** - * \file - * Implementation of the ARP Address Resolution Protocol. - * \author Adam Dunkels - * - */ - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $ - * - */ - - -#include "uip_arp.h" - -#include - -struct arp_hdr { - struct uip_eth_hdr ethhdr; - u16_t hwtype; - u16_t protocol; - u8_t hwlen; - u8_t protolen; - u16_t opcode; - struct uip_eth_addr shwaddr; - u16_t sipaddr[2]; - struct uip_eth_addr dhwaddr; - u16_t dipaddr[2]; -}; - -struct ethip_hdr { - struct uip_eth_hdr ethhdr; - /* IP header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; -}; - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -#define ARP_HWTYPE_ETH 1 - -struct arp_entry { - u16_t ipaddr[2]; - struct uip_eth_addr ethaddr; - u8_t time; -}; - -static const struct uip_eth_addr broadcast_ethaddr = - {{0xff,0xff,0xff,0xff,0xff,0xff}}; -static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; - -static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; -static u16_t ipaddr[2]; -static u8_t i, c; - -static u8_t arptime; -static u8_t tmpage; - -#define BUF ((struct arp_hdr *)&uip_buf[0]) -#define IPBUF ((struct ethip_hdr *)&uip_buf[0]) -/*-----------------------------------------------------------------------------------*/ -/** - * Initialize the ARP module. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_init(void) -{ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - memset(arp_table[i].ipaddr, 0, 4); - } -} -/*-----------------------------------------------------------------------------------*/ -/** - * Periodic ARP processing function. - * - * This function performs periodic timer processing in the ARP module - * and should be called at regular intervals. The recommended interval - * is 10 seconds between the calls. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_timer(void) -{ - struct arp_entry *tabptr; - - ++arptime; - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && - arptime - tabptr->time >= UIP_ARP_MAXAGE) { - memset(tabptr->ipaddr, 0, 4); - } - } - -} -/*-----------------------------------------------------------------------------------*/ -static void -uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) -{ - register struct arp_entry *tabptr; - /* Walk through the ARP mapping table and try to find an entry to - update. If none is found, the IP -> MAC address mapping is - inserted in the ARP table. */ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - - tabptr = &arp_table[i]; - /* Only check those entries that are actually in use. */ - if(tabptr->ipaddr[0] != 0 && - tabptr->ipaddr[1] != 0) { - - /* Check if the source IP address of the incoming packet matches - the IP address in this ARP table entry. */ - if(ipaddr[0] == tabptr->ipaddr[0] && - ipaddr[1] == tabptr->ipaddr[1]) { - - /* An old entry found, update this and return. */ - memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); - tabptr->time = arptime; - - return; - } - } - } - - /* If we get here, no existing ARP table entry was found, so we - create one. */ - - /* First, we try to find an unused entry in the ARP table. */ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(tabptr->ipaddr[0] == 0 && - tabptr->ipaddr[1] == 0) { - break; - } - } - - /* If no unused entry is found, we try to find the oldest entry and - throw it away. */ - if(i == UIP_ARPTAB_SIZE) { - tmpage = 0; - c = 0; - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(arptime - tabptr->time > tmpage) { - tmpage = arptime - tabptr->time; - c = i; - } - } - i = c; - tabptr = &arp_table[i]; - } - - /* Now, i is the ARP table entry which we will fill with the new - information. */ - memcpy(tabptr->ipaddr, ipaddr, 4); - memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); - tabptr->time = arptime; -} -/*-----------------------------------------------------------------------------------*/ -/** - * ARP processing for incoming IP packets - * - * This function should be called by the device driver when an IP - * packet has been received. The function will check if the address is - * in the ARP cache, and if so the ARP cache entry will be - * refreshed. If no ARP cache entry was found, a new one is created. - * - * This function expects an IP packet with a prepended Ethernet header - * in the uip_buf[] buffer, and the length of the packet in the global - * variable uip_len. - */ -/*-----------------------------------------------------------------------------------*/ -//#if 0 -void -uip_arp_ipin(void) -{ - uip_len -= sizeof(struct uip_eth_hdr); - - /* Only insert/update an entry if the source IP address of the - incoming IP packet comes from a host on the local network. */ - if((IPBUF->srcipaddr[0] & uip_netmask[0]) != - (uip_hostaddr[0] & uip_netmask[0])) { - return; - } - if((IPBUF->srcipaddr[1] & uip_netmask[1]) != - (uip_hostaddr[1] & uip_netmask[1])) { - return; - } - uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src)); - - return; -} -//#endif /* 0 */ -/*-----------------------------------------------------------------------------------*/ -/** - * ARP processing for incoming ARP packets. - * - * This function should be called by the device driver when an ARP - * packet has been received. The function will act differently - * depending on the ARP packet type: if it is a reply for a request - * that we previously sent out, the ARP cache will be filled in with - * the values from the ARP reply. If the incoming ARP packet is an ARP - * request for our IP address, an ARP reply packet is created and put - * into the uip_buf[] buffer. - * - * When the function returns, the value of the global variable uip_len - * indicates whether the device driver should send out a packet or - * not. If uip_len is zero, no packet should be sent. If uip_len is - * non-zero, it contains the length of the outbound packet that is - * present in the uip_buf[] buffer. - * - * This function expects an ARP packet with a prepended Ethernet - * header in the uip_buf[] buffer, and the length of the packet in the - * global variable uip_len. - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_arpin(void) -{ - - if(uip_len < sizeof(struct arp_hdr)) { - uip_len = 0; - return; - } - uip_len = 0; - - switch(BUF->opcode) { - case HTONS(ARP_REQUEST): - /* ARP request. If it asked for our address, we send out a - reply. */ - if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { - /* First, we register the one who made the request in our ARP - table, since it is likely that we will do more communication - with this host in the future. */ - uip_arp_update(BUF->sipaddr, &BUF->shwaddr); - - /* The reply opcode is 2. */ - BUF->opcode = HTONS(2); - - memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6); - memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); - memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); - memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); - - BUF->dipaddr[0] = BUF->sipaddr[0]; - BUF->dipaddr[1] = BUF->sipaddr[1]; - BUF->sipaddr[0] = uip_hostaddr[0]; - BUF->sipaddr[1] = uip_hostaddr[1]; - - BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); - uip_len = sizeof(struct arp_hdr); - } - break; - case HTONS(ARP_REPLY): - /* ARP reply. We insert or update the ARP table if it was meant - for us. */ - if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { - uip_arp_update(BUF->sipaddr, &BUF->shwaddr); - } - break; - } - - return; -} -/*-----------------------------------------------------------------------------------*/ -/** - * Prepend Ethernet header to an outbound IP packet and see if we need - * to send out an ARP request. - * - * This function should be called before sending out an IP packet. The - * function checks the destination IP address of the IP packet to see - * what Ethernet MAC address that should be used as a destination MAC - * address on the Ethernet. - * - * If the destination IP address is in the local network (determined - * by logical ANDing of netmask and our IP address), the function - * checks the ARP cache to see if an entry for the destination IP - * address is found. If so, an Ethernet header is prepended and the - * function returns. If no ARP cache entry is found for the - * destination IP address, the packet in the uip_buf[] is replaced by - * an ARP request packet for the IP address. The IP packet is dropped - * and it is assumed that they higher level protocols (e.g., TCP) - * eventually will retransmit the dropped packet. - * - * If the destination IP address is not on the local network, the IP - * address of the default router is used instead. - * - * When the function returns, a packet is present in the uip_buf[] - * buffer, and the length of the packet is in the global variable - * uip_len. - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_out(void) -{ - struct arp_entry *tabptr; - - /* Find the destination IP address in the ARP table and construct - the Ethernet header. If the destination IP addres isn't on the - local network, we use the default router's IP address instead. - - If not ARP table entry is found, we overwrite the original IP - packet with an ARP request for the IP address. */ - - /* First check if destination is a local broadcast. */ - if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) { - memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); - } else { - /* Check if the destination address is on the local network. */ - if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) { - /* Destination address was not on the local network, so we need to - use the default router's IP address instead of the destination - address when determining the MAC address. */ - uip_ipaddr_copy(ipaddr, uip_draddr); - } else { - /* Else, we use the destination IP address. */ - uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); - } - - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) { - break; - } - } - - if(i == UIP_ARPTAB_SIZE) { - /* The destination address was not in our ARP table, so we - overwrite the IP packet with an ARP request. */ - - memset(BUF->ethhdr.dest.addr, 0xff, 6); - memset(BUF->dhwaddr.addr, 0x00, 6); - memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); - memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); - - uip_ipaddr_copy(BUF->dipaddr, ipaddr); - uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr); - BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ - BUF->hwtype = HTONS(ARP_HWTYPE_ETH); - BUF->protocol = HTONS(UIP_ETHTYPE_IP); - BUF->hwlen = 6; - BUF->protolen = 4; - BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); - - uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; - - uip_len = sizeof(struct arp_hdr); - return; - } - - /* Build an ethernet header. */ - memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); - } - memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6); - - IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP); - - uip_len += sizeof(struct uip_eth_hdr); -} -/*-----------------------------------------------------------------------------------*/ - -/** @} */ -/** @} */ diff --git a/libraries/UIPEthernet/utility/uip_arp.h b/libraries/UIPEthernet/utility/uip_arp.h deleted file mode 100644 index ef93054..0000000 --- a/libraries/UIPEthernet/utility/uip_arp.h +++ /dev/null @@ -1,144 +0,0 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \addtogroup uiparp - * @{ - */ - -/** - * \file - * Macros and definitions for the ARP module. - * \author Adam Dunkels - */ - - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $ - * - */ - -#ifndef __UIP_ARP_H__ -#define __UIP_ARP_H__ - -#include "uip.h" - - -extern struct uip_eth_addr uip_ethaddr; - -/** - * The Ethernet header. - */ -struct uip_eth_hdr { - struct uip_eth_addr dest; - struct uip_eth_addr src; - u16_t type; -}; - -#define UIP_ETHTYPE_ARP 0x0806 -#define UIP_ETHTYPE_IP 0x0800 -#define UIP_ETHTYPE_IP6 0x86dd - - -/* The uip_arp_init() function must be called before any of the other - ARP functions. */ -void uip_arp_init(void); - -/* The uip_arp_ipin() function should be called whenever an IP packet - arrives from the Ethernet. This function refreshes the ARP table or - inserts a new mapping if none exists. The function assumes that an - IP packet with an Ethernet header is present in the uip_buf buffer - and that the length of the packet is in the uip_len variable. */ -void uip_arp_ipin(void); -//#define uip_arp_ipin() - -/* The uip_arp_arpin() should be called when an ARP packet is received - by the Ethernet driver. This function also assumes that the - Ethernet frame is present in the uip_buf buffer. When the - uip_arp_arpin() function returns, the contents of the uip_buf - buffer should be sent out on the Ethernet if the uip_len variable - is > 0. */ -void uip_arp_arpin(void); - -/* The uip_arp_out() function should be called when an IP packet - should be sent out on the Ethernet. This function creates an - Ethernet header before the IP header in the uip_buf buffer. The - Ethernet header will have the correct Ethernet MAC destination - address filled in if an ARP table entry for the destination IP - address (or the IP address of the default router) is present. If no - such table entry is found, the IP packet is overwritten with an ARP - request and we rely on TCP to retransmit the packet that was - overwritten. In any case, the uip_len variable holds the length of - the Ethernet frame that should be transmitted. */ -void uip_arp_out(void); - -/* The uip_arp_timer() function should be called every ten seconds. It - is responsible for flushing old entries in the ARP table. */ -void uip_arp_timer(void); - -/** @} */ - -/** - * \addtogroup uipconffunc - * @{ - */ - - -/** - * Specifiy the Ethernet MAC address. - * - * The ARP code needs to know the MAC address of the Ethernet card in - * order to be able to respond to ARP queries and to generate working - * Ethernet headers. - * - * \note This macro only specifies the Ethernet MAC address to the ARP - * code. It cannot be used to change the MAC address of the Ethernet - * card. - * - * \param eaddr A pointer to a struct uip_eth_addr containing the - * Ethernet MAC address of the Ethernet card. - * - * \hideinitializer - */ -#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \ - uip_ethaddr.addr[1] = eaddr.addr[1];\ - uip_ethaddr.addr[2] = eaddr.addr[2];\ - uip_ethaddr.addr[3] = eaddr.addr[3];\ - uip_ethaddr.addr[4] = eaddr.addr[4];\ - uip_ethaddr.addr[5] = eaddr.addr[5];} while(0) - -/** @} */ -/** @} */ - -#endif /* __UIP_ARP_H__ */ diff --git a/libraries/UIPEthernet/utility/uip_clock.h b/libraries/UIPEthernet/utility/uip_clock.h deleted file mode 100644 index 6dd72be..0000000 --- a/libraries/UIPEthernet/utility/uip_clock.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * \defgroup clock Clock interface - * - * The clock interface is the interface between the \ref timer "timer library" - * and the platform specific clock functionality. The clock - * interface must be implemented for each platform that uses the \ref - * timer "timer library". - * - * The clock interface does only one this: it measures time. The clock - * interface provides a macro, CLOCK_SECOND, which corresponds to one - * second of system time. - * - * \sa \ref timer "Timer library" - * - * @{ - */ - -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - * Author: Adam Dunkels - * - * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $ - */ -#ifndef __UIP_CLOCK_H__ -#define __UIP_CLOCK_H__ - -#include "clock-arch.h" - -/** - * Initialize the clock library. - * - * This function initializes the clock library and should be called - * from the main() function of the system. - * - */ -void uip_clock_init(void); - -/** - * Get the current clock time. - * - * This function returns the current system clock time. - * - * \return The current clock time, measured in system ticks. - */ -clock_time_t clock_time(void); - -/** - * A second, measured in system clock time. - * - * \hideinitializer - */ -#ifdef CLOCK_CONF_SECOND -#define CLOCK_SECOND CLOCK_CONF_SECOND -#else -#define CLOCK_SECOND (clock_time_t)32 -#endif - -#endif /* __CLOCK_H__ */ - -/** @} */ diff --git a/libraries/UIPEthernet/utility/uip_debug.cpp b/libraries/UIPEthernet/utility/uip_debug.cpp deleted file mode 100644 index 444bd0e..0000000 --- a/libraries/UIPEthernet/utility/uip_debug.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include -#include -extern "C" { - #import "utility/uip.h" -} - -struct uip_conn con[UIP_CONNS]; - -void -UIPDebug::uip_debug_printconns() -{ - for(uint8_t i=0;iripaddr,rhs->ripaddr)) - { - Serial.print(" ripaddr: "); - uip_debug_printbytes((const uint8_t *)lhs->ripaddr,4); - Serial.print(" -> "); - uip_debug_printbytes((const uint8_t *)rhs->ripaddr,4); - Serial.println(); - uip_ipaddr_copy(lhs->ripaddr,rhs->ripaddr); - changed = true; - } - if (lhs->lport != rhs->lport) - { - Serial.print(" lport: "); - Serial.print(htons(lhs->lport)); - Serial.print(" -> "); - Serial.println(htons(rhs->lport)); - lhs->lport = rhs->lport; - changed = true; - } - if (lhs->rport != rhs->rport) - { - Serial.print(" rport: "); - Serial.print(htons(lhs->rport)); - Serial.print(" -> "); - Serial.println(htons(rhs->rport)); - lhs->rport = rhs->rport; - changed = true; - } - if ((uint32_t)lhs->rcv_nxt[0] != (uint32_t)rhs->rcv_nxt[0]) - { - Serial.print(" rcv_nxt: "); - uip_debug_printbytes(lhs->rcv_nxt,4); - Serial.print(" -> "); - uip_debug_printbytes(rhs->rcv_nxt,4); - *((uint32_t *)&lhs->rcv_nxt[0]) = (uint32_t)rhs->rcv_nxt[0]; - Serial.println(); - changed = true; - } - if ((uint32_t)lhs->snd_nxt[0] != (uint32_t)rhs->snd_nxt[0]) - { - Serial.print(" snd_nxt: "); - uip_debug_printbytes(lhs->snd_nxt,4); - Serial.print(" -> "); - uip_debug_printbytes(rhs->snd_nxt,4); - *((uint32_t *)&lhs->snd_nxt[0]) = (uint32_t)rhs->snd_nxt[0]; - Serial.println(); - changed = true; - } - if (lhs->len != rhs->len) - { - Serial.print(" len: "); - Serial.print(lhs->len); - Serial.print(" -> "); - Serial.println(rhs->len); - lhs->len = rhs->len; - changed = true; - } - if (lhs->mss != rhs->mss) - { - Serial.print(" mss: "); - Serial.print(lhs->mss); - Serial.print(" -> "); - Serial.println(rhs->mss); - lhs->mss = rhs->mss; - changed = true; - } - if (lhs->initialmss != rhs->initialmss) - { - Serial.print(" initialmss: "); - Serial.print(lhs->initialmss); - Serial.print(" -> "); - Serial.println(rhs->initialmss); - lhs->initialmss = rhs->initialmss; - changed = true; - } - if (lhs->sa != rhs->sa) - { - Serial.print(" sa: "); - Serial.print(lhs->sa); - Serial.print(" -> "); - Serial.println(rhs->sa); - lhs->sa = rhs->sa; - changed = true; - } - if (lhs->sv != rhs->sv) - { - Serial.print(" sv: "); - Serial.print(lhs->sv); - Serial.print(" -> "); - Serial.println(rhs->sv); - lhs->sv = rhs->sv; - changed = true; - } - if (lhs->rto != rhs->rto) - { - Serial.print(" rto: "); - Serial.print(lhs->rto); - Serial.print(" -> "); - Serial.println(rhs->rto); - lhs->rto = rhs->rto; - changed = true; - } - if (lhs->tcpstateflags != rhs->tcpstateflags) - { - Serial.print(" tcpstateflags: "); - Serial.print(lhs->tcpstateflags); - Serial.print(" -> "); - Serial.println(rhs->tcpstateflags); - lhs->tcpstateflags = rhs->tcpstateflags; - changed = true; - } - if (lhs->timer != rhs->timer) - { - Serial.print(" timer: "); - Serial.print(lhs->timer); - Serial.print(" -> "); - Serial.println(rhs->timer); - lhs->timer = rhs->timer; - changed = true; - } - if (lhs->nrtx != rhs->nrtx) - { - Serial.print(" nrtx: "); - Serial.print(lhs->nrtx); - Serial.print(" -> "); - Serial.println(rhs->nrtx); - lhs->nrtx = rhs->nrtx; - changed = true; - } - return changed; -} - -void -UIPDebug::uip_debug_printbytes(const uint8_t *data, uint8_t len) -{ - for(uint8_t i=0;i - */ - -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - * Author: Adam Dunkels - * - * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $ - */ - -#include "uip_clock.h" -#include "uip_timer.h" - -/*---------------------------------------------------------------------------*/ -/** - * Set a timer. - * - * This function is used to set a timer for a time sometime in the - * future. The function timer_expired() will evaluate to true after - * the timer has expired. - * - * \param t A pointer to the timer - * \param interval The interval before the timer expires. - * - */ -void -uip_timer_set(struct uip_timer *t, clock_time_t interval) -{ - t->interval = interval; - t->start = clock_time(); -} -/*---------------------------------------------------------------------------*/ -/** - * Reset the timer with the same interval. - * - * This function resets the timer with the same interval that was - * given to the timer_set() function. The start point of the interval - * is the exact time that the timer last expired. Therefore, this - * function will cause the timer to be stable over time, unlike the - * timer_rester() function. - * - * \param t A pointer to the timer. - * - * \sa timer_restart() - */ -void -uip_timer_reset(struct uip_timer *t) -{ - t->start += t->interval; -} -/*---------------------------------------------------------------------------*/ -/** - * Restart the timer from the current point in time - * - * This function restarts a timer with the same interval that was - * given to the timer_set() function. The timer will start at the - * current time. - * - * \note A periodic timer will drift if this function is used to reset - * it. For preioric timers, use the timer_reset() function instead. - * - * \param t A pointer to the timer. - * - * \sa timer_reset() - */ -void -uip_timer_restart(struct uip_timer *t) -{ - t->start = clock_time(); -} -/*---------------------------------------------------------------------------*/ -/** - * Check if a timer has expired. - * - * This function tests if a timer has expired and returns true or - * false depending on its status. - * - * \param t A pointer to the timer - * - * \return Non-zero if the timer has expired, zero otherwise. - * - */ -int -uip_timer_expired(struct uip_timer *t) -{ - return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; -} -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/libraries/UIPEthernet/utility/uip_timer.h b/libraries/UIPEthernet/utility/uip_timer.h deleted file mode 100644 index f260349..0000000 --- a/libraries/UIPEthernet/utility/uip_timer.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * \defgroup timer Timer library - * - * The timer library provides functions for setting, resetting and - * restarting timers, and for checking if a timer has expired. An - * application must "manually" check if its timers have expired; this - * is not done automatically. - * - * A timer is declared as a \c struct \c timer and all access to the - * timer is made by a pointer to the declared timer. - * - * \note The timer library uses the \ref clock "Clock library" to - * measure time. Intervals should be specified in the format used by - * the clock library. - * - * @{ - */ - - -/** - * \file - * Timer library header file. - * \author - * Adam Dunkels - */ - -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - * Author: Adam Dunkels - * - * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $ - */ -#ifndef __UIP_TIMER_H__ -#define __UIP_TIMER_H__ - -#include "uip_clock.h" - -/** - * A timer. - * - * This structure is used for declaring a timer. The timer must be set - * with timer_set() before it can be used. - * - * \hideinitializer - */ -struct uip_timer { - clock_time_t start; - clock_time_t interval; -}; - -void uip_timer_set(struct uip_timer *t, clock_time_t interval); -void uip_timer_reset(struct uip_timer *t); -void uip_timer_restart(struct uip_timer *t); -int uip_timer_expired(struct uip_timer *t); - -#endif /* __UIP_TIMER_H__ */ - -/** @} */ diff --git a/libraries/UIPEthernet/utility/uipethernet-conf.h b/libraries/UIPEthernet/utility/uipethernet-conf.h deleted file mode 100644 index 733e26e..0000000 --- a/libraries/UIPEthernet/utility/uipethernet-conf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef UIPETHERNET_CONF_H -#define UIPETHERNET_CONF_H - -/* for TCP */ -#define UIP_SOCKET_NUMPACKETS 5 -#define UIP_CONF_MAX_CONNECTIONS 4 - -/* for UDP */ -#define UIP_CONF_UDP 0//1 -#define UIP_CONF_BROADCAST 0//1 -#define UIP_CONF_UDP_CONNS 0//4 -#define UIP_UDP_NUMPACKETS 0//5 - -/* number of attempts on write before returning number of bytes sent so far - * set to -1 to block until connection is closed by timeout */ -#define UIP_ATTEMPTS_ON_WRITE -1 - -#endif diff --git a/libraries/UIPEthernet/utility/uipopt.h b/libraries/UIPEthernet/utility/uipopt.h deleted file mode 100644 index 42badf8..0000000 --- a/libraries/UIPEthernet/utility/uipopt.h +++ /dev/null @@ -1,543 +0,0 @@ -/** - * \defgroup uipopt Configuration options for uIP - * @{ - * - * uIP is configured using the per-project configuration file - * uipopt.h. This file contains all compile-time options for uIP and - * should be tweaked to match each specific project. The uIP - * distribution contains a documented example "uipopt.h" that can be - * copied and modified for each project. - * - * \note Most of the configuration options in the uipopt.h should not - * be changed, but rather the per-project uip-conf.h file. - */ - -/** - * \file - * Configuration options for uIP. - * \author Adam Dunkels - * - * This file is used for tweaking various configuration options for - * uIP. You should make a copy of this file into one of your project's - * directories instead of editing this example "uipopt.h" file that - * comes with the uIP distribution. - */ - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $ - * - */ - -#ifndef __UIPOPT_H__ -#define __UIPOPT_H__ - -#ifndef UIP_LITTLE_ENDIAN -#define UIP_LITTLE_ENDIAN 3412 -#endif /* UIP_LITTLE_ENDIAN */ -#ifndef UIP_BIG_ENDIAN -#define UIP_BIG_ENDIAN 1234 -#endif /* UIP_BIG_ENDIAN */ - -#include "uip-conf.h" - -/*------------------------------------------------------------------------------*/ - -/** - * \name Static configuration options - * @{ - * - * These configuration options can be used for setting the IP address - * settings statically, but only if UIP_FIXEDADDR is set to 1. The - * configuration options for a specific node includes IP address, - * netmask and default router as well as the Ethernet address. The - * netmask, default router and Ethernet address are appliciable only - * if uIP should be run over Ethernet. - * - * All of these should be changed to suit your project. -*/ - -/** - * Determines if uIP should use a fixed IP address or not. - * - * If uIP should use a fixed IP address, the settings are set in the - * uipopt.h file. If not, the macros uip_sethostaddr(), - * uip_setdraddr() and uip_setnetmask() should be used instead. - * - * \hideinitializer - */ -#define UIP_FIXEDADDR 0 - -/** - * Ping IP address asignment. - * - * uIP uses a "ping" packets for setting its own IP address if this - * option is set. If so, uIP will start with an empty IP address and - * the destination IP address of the first incoming "ping" (ICMP echo) - * packet will be used for setting the hosts IP address. - * - * \note This works only if UIP_FIXEDADDR is 0. - * - * \hideinitializer - */ -#ifdef UIP_CONF_PINGADDRCONF -#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF -#else /* UIP_CONF_PINGADDRCONF */ -#define UIP_PINGADDRCONF 0 -#endif /* UIP_CONF_PINGADDRCONF */ - - -/** - * Specifies if the uIP ARP module should be compiled with a fixed - * Ethernet MAC address or not. - * - * If this configuration option is 0, the macro uip_setethaddr() can - * be used to specify the Ethernet address at run-time. - * - * \hideinitializer - */ -#define UIP_FIXEDETHADDR 0 - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \name IP configuration options - * @{ - * - */ -/** - * The IP TTL (time to live) of IP packets sent by uIP. - * - * This should normally not be changed. - */ -#define UIP_TTL 64 - -/** - * Turn on support for IP packet reassembly. - * - * uIP supports reassembly of fragmented IP packets. This features - * requires an additonal amount of RAM to hold the reassembly buffer - * and the reassembly code size is approximately 700 bytes. The - * reassembly buffer is of the same size as the uip_buf buffer - * (configured by UIP_BUFSIZE). - * - * \note IP packet reassembly is not heavily tested. - * - * \hideinitializer - */ -#define UIP_REASSEMBLY 0 - -/** - * The maximum time an IP fragment should wait in the reassembly - * buffer before it is dropped. - * - */ -#define UIP_REASS_MAXAGE 40 - -/** @} */ - -/*------------------------------------------------------------------------------*/ -/** - * \name UDP configuration options - * @{ - */ - -/** - * Toggles wether UDP support should be compiled in or not. - * - * \hideinitializer - */ -#ifdef UIP_CONF_UDP -#define UIP_UDP UIP_CONF_UDP -#else /* UIP_CONF_UDP */ -#define UIP_UDP 0 -#endif /* UIP_CONF_UDP */ - -/** - * Toggles if UDP checksums should be used or not. - * - * \note Support for UDP checksums is currently not included in uIP, - * so this option has no function. - * - * \hideinitializer - */ -#ifdef UIP_CONF_UDP_CHECKSUMS -#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS -#else -#define UIP_UDP_CHECKSUMS 0 -#endif - -/** - * The maximum amount of concurrent UDP connections. - * - * \hideinitializer - */ -#ifdef UIP_CONF_UDP_CONNS -#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS -#else /* UIP_CONF_UDP_CONNS */ -#define UIP_UDP_CONNS 10 -#endif /* UIP_CONF_UDP_CONNS */ - -/** - * The name of the function that should be called when UDP datagrams arrive. - * - * \hideinitializer - */ - - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \name TCP configuration options - * @{ - */ - -/** - * Determines if support for opening connections from uIP should be - * compiled in. - * - * If the applications that are running on top of uIP for this project - * do not need to open outgoing TCP connections, this configration - * option can be turned off to reduce the code size of uIP. - * - * \hideinitializer - */ -#define UIP_ACTIVE_OPEN 1 - -/** - * The maximum number of simultaneously open TCP connections. - * - * Since the TCP connections are statically allocated, turning this - * configuration knob down results in less RAM used. Each TCP - * connection requires approximatly 30 bytes of memory. - * - * \hideinitializer - */ -#ifndef UIP_CONF_MAX_CONNECTIONS -#define UIP_CONNS 10 -#else /* UIP_CONF_MAX_CONNECTIONS */ -#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS -#endif /* UIP_CONF_MAX_CONNECTIONS */ - - -/** - * The maximum number of simultaneously listening TCP ports. - * - * Each listening TCP port requires 2 bytes of memory. - * - * \hideinitializer - */ -#ifndef UIP_CONF_MAX_LISTENPORTS -#define UIP_LISTENPORTS 20 -#else /* UIP_CONF_MAX_LISTENPORTS */ -#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS -#endif /* UIP_CONF_MAX_LISTENPORTS */ - -/** - * Determines if support for TCP urgent data notification should be - * compiled in. - * - * Urgent data (out-of-band data) is a rarely used TCP feature that - * very seldom would be required. - * - * \hideinitializer - */ -#define UIP_URGDATA 0 - -/** - * The initial retransmission timeout counted in timer pulses. - * - * This should not be changed. - */ -#define UIP_RTO 3 - -/** - * The maximum number of times a segment should be retransmitted - * before the connection should be aborted. - * - * This should not be changed. - */ -#define UIP_MAXRTX 8 - -/** - * The maximum number of times a SYN segment should be retransmitted - * before a connection request should be deemed to have been - * unsuccessful. - * - * This should not need to be changed. - */ -#define UIP_MAXSYNRTX 5 - -/** - * The TCP maximum segment size. - * - * This is should not be to set to more than - * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. - */ -#ifndef UIP_CONF_TCP_MSS -#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) -#else -#define UIP_TCP_MSS UIP_CONF_TCP_MSS -#endif - -/** - * The size of the advertised receiver's window. - * - * Should be set low (i.e., to the size of the uip_buf buffer) is the - * application is slow to process incoming data, or high (32768 bytes) - * if the application processes data quickly. - * - * \hideinitializer - */ -#ifndef UIP_CONF_RECEIVE_WINDOW -#define UIP_RECEIVE_WINDOW UIP_TCP_MSS -#else -#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW -#endif - -/** - * How long a connection should stay in the TIME_WAIT state. - * - * This configiration option has no real implication, and it should be - * left untouched. - */ -#define UIP_TIME_WAIT_TIMEOUT 120 - - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \name ARP configuration options - * @{ - */ - -/** - * The size of the ARP table. - * - * This option should be set to a larger value if this uIP node will - * have many connections from the local network. - * - * \hideinitializer - */ -#ifdef UIP_CONF_ARPTAB_SIZE -#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE -#else -#define UIP_ARPTAB_SIZE 8 -#endif - -/** - * The maxium age of ARP table entries measured in 10ths of seconds. - * - * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD - * default). - */ -#define UIP_ARP_MAXAGE 120 - -/** @} */ - -/*------------------------------------------------------------------------------*/ - -/** - * \name General configuration options - * @{ - */ - -/** - * The size of the uIP packet buffer. - * - * The uIP packet buffer should not be smaller than 60 bytes, and does - * not need to be larger than 1500 bytes. Lower size results in lower - * TCP throughput, larger size results in higher TCP throughput. - * - * \hideinitializer - */ -#ifndef UIP_CONF_BUFFER_SIZE -#define UIP_BUFSIZE 400 -#else /* UIP_CONF_BUFFER_SIZE */ -#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE -#endif /* UIP_CONF_BUFFER_SIZE */ - - -/** - * Determines if statistics support should be compiled in. - * - * The statistics is useful for debugging and to show the user. - * - * \hideinitializer - */ -#ifndef UIP_CONF_STATISTICS -#define UIP_STATISTICS 0 -#else /* UIP_CONF_STATISTICS */ -#define UIP_STATISTICS UIP_CONF_STATISTICS -#endif /* UIP_CONF_STATISTICS */ - -/** - * Determines if logging of certain events should be compiled in. - * - * This is useful mostly for debugging. The function uip_log() - * must be implemented to suit the architecture of the project, if - * logging is turned on. - * - * \hideinitializer - */ -#ifndef UIP_CONF_LOGGING -#define UIP_LOGGING 0 -#else /* UIP_CONF_LOGGING */ -#define UIP_LOGGING UIP_CONF_LOGGING -#endif /* UIP_CONF_LOGGING */ - -/** - * Broadcast support. - * - * This flag configures IP broadcast support. This is useful only - * together with UDP. - * - * \hideinitializer - * - */ -#if UIP_UDP && UIP_CONF_BROADCAST -#define UIP_BROADCAST UIP_CONF_BROADCAST -#else /* UIP_CONF_BROADCAST */ -#define UIP_BROADCAST 0 -#endif /* UIP_CONF_BROADCAST */ - -/** - * Print out a uIP log message. - * - * This function must be implemented by the module that uses uIP, and - * is called by uIP whenever a log message is generated. - */ -void uip_log(char *msg); - -/** - * The link level header length. - * - * This is the offset into the uip_buf where the IP header can be - * found. For Ethernet, this should be set to 14. For SLIP, this - * should be set to 0. - * - * \hideinitializer - */ -#ifdef UIP_CONF_LLH_LEN -#define UIP_LLH_LEN UIP_CONF_LLH_LEN -#else /* UIP_CONF_LLH_LEN */ -#define UIP_LLH_LEN 14 -#endif /* UIP_CONF_LLH_LEN */ - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \name CPU architecture configuration - * @{ - * - * The CPU architecture configuration is where the endianess of the - * CPU on which uIP is to be run is specified. Most CPUs today are - * little endian, and the most notable exception are the Motorolas - * which are big endian. The BYTE_ORDER macro should be changed to - * reflect the CPU architecture on which uIP is to be run. - */ - -/** - * The byte order of the CPU architecture on which uIP is to be run. - * - * This option can be either BIG_ENDIAN (Motorola byte order) or - * LITTLE_ENDIAN (Intel byte order). - * - * \hideinitializer - */ -#ifdef UIP_CONF_BYTE_ORDER -#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER -#else /* UIP_CONF_BYTE_ORDER */ -#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN -#endif /* UIP_CONF_BYTE_ORDER */ - -/** @} */ -/*------------------------------------------------------------------------------*/ - -/** - * \name Appication specific configurations - * @{ - * - * An uIP application is implemented using a single application - * function that is called by uIP whenever a TCP/IP event occurs. The - * name of this function must be registered with uIP at compile time - * using the UIP_APPCALL definition. - * - * uIP applications can store the application state within the - * uip_conn structure by specifying the type of the application - * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t. - * - * The file containing the definitions must be included in the - * uipopt.h file. - * - * The following example illustrates how this can look. - \code - -void httpd_appcall(void); -#define UIP_APPCALL httpd_appcall - -struct httpd_state { - u8_t state; - u16_t count; - char *dataptr; - char *script; -}; -typedef struct httpd_state uip_tcp_appstate_t - \endcode - */ - -/** - * \var #define UIP_APPCALL - * - * The name of the application function that uIP should call in - * response to TCP/IP events. - * - */ - -/** - * \var typedef uip_tcp_appstate_t - * - * The type of the application state that is to be stored in the - * uip_conn structure. This usually is typedef:ed to a struct holding - * application state information. - */ - -/** - * \var typedef uip_udp_appstate_t - * - * The type of the application state that is to be stored in the - * uip_conn structure. This usually is typedef:ed to a struct holding - * application state information. - */ -/** @} */ -/** @} */ - -#endif /* __UIPOPT_H__ */ diff --git a/libraries/UIPEthernet/utility/util.h b/libraries/UIPEthernet/utility/util.h deleted file mode 100644 index 5042e82..0000000 --- a/libraries/UIPEthernet/utility/util.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) ) -#define ntohs(x) htons(x) - -#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ - ((x)<< 8 & 0x00FF0000UL) | \ - ((x)>> 8 & 0x0000FF00UL) | \ - ((x)>>24 & 0x000000FFUL) ) -#define ntohl(x) htonl(x) - -#endif