From 10e2d31a2f38bf15f6e6f447d45c1f9aac0b4f02 Mon Sep 17 00:00:00 2001 From: ToSa27 Date: Thu, 24 Jul 2014 13:29:35 +0200 Subject: [PATCH 1/6] Misc fixes - changed HEADER_SIZE constant from 8 to 7 to reflect message structure - removed duplicate utility folder in UIPEthernet that prevented proper compilation - removed unnecessary includes in EthernetGateway that prevented proper compilation --- EthernetGateway/EthernetGateway.ino | 2 - libraries/MySensors/MyMessage.h | 2 +- .../UIPEthernet/utility/Enc28J60Network.cpp | 554 ----- .../UIPEthernet/utility/Enc28J60Network.h | 86 - libraries/UIPEthernet/utility/clock-arch.c | 28 - libraries/UIPEthernet/utility/clock-arch.h | 27 - libraries/UIPEthernet/utility/enc28j60.h | 257 --- libraries/UIPEthernet/utility/mempool.cpp | 164 -- libraries/UIPEthernet/utility/mempool.h | 71 - libraries/UIPEthernet/utility/mempool_conf.h | 28 - libraries/UIPEthernet/utility/uip-conf.h | 185 -- libraries/UIPEthernet/utility/uip-neighbor.c | 158 -- libraries/UIPEthernet/utility/uip-neighbor.h | 61 - libraries/UIPEthernet/utility/uip.c | 1897 ----------------- libraries/UIPEthernet/utility/uip.h | 1601 -------------- libraries/UIPEthernet/utility/uip_arch.h | 138 -- libraries/UIPEthernet/utility/uip_arp.c | 423 ---- libraries/UIPEthernet/utility/uip_arp.h | 144 -- libraries/UIPEthernet/utility/uip_clock.h | 88 - libraries/UIPEthernet/utility/uip_debug.cpp | 170 -- libraries/UIPEthernet/utility/uip_debug.h | 18 - libraries/UIPEthernet/utility/uip_timer.c | 127 -- libraries/UIPEthernet/utility/uip_timer.h | 86 - .../UIPEthernet/utility/uipethernet-conf.h | 18 - libraries/UIPEthernet/utility/uipopt.h | 543 ----- libraries/UIPEthernet/utility/util.h | 13 - 26 files changed, 1 insertion(+), 6888 deletions(-) delete mode 100644 libraries/UIPEthernet/utility/Enc28J60Network.cpp delete mode 100644 libraries/UIPEthernet/utility/Enc28J60Network.h delete mode 100644 libraries/UIPEthernet/utility/clock-arch.c delete mode 100644 libraries/UIPEthernet/utility/clock-arch.h delete mode 100644 libraries/UIPEthernet/utility/enc28j60.h delete mode 100644 libraries/UIPEthernet/utility/mempool.cpp delete mode 100644 libraries/UIPEthernet/utility/mempool.h delete mode 100644 libraries/UIPEthernet/utility/mempool_conf.h delete mode 100644 libraries/UIPEthernet/utility/uip-conf.h delete mode 100644 libraries/UIPEthernet/utility/uip-neighbor.c delete mode 100644 libraries/UIPEthernet/utility/uip-neighbor.h delete mode 100644 libraries/UIPEthernet/utility/uip.c delete mode 100644 libraries/UIPEthernet/utility/uip.h delete mode 100644 libraries/UIPEthernet/utility/uip_arch.h delete mode 100644 libraries/UIPEthernet/utility/uip_arp.c delete mode 100644 libraries/UIPEthernet/utility/uip_arp.h delete mode 100644 libraries/UIPEthernet/utility/uip_clock.h delete mode 100644 libraries/UIPEthernet/utility/uip_debug.cpp delete mode 100644 libraries/UIPEthernet/utility/uip_debug.h delete mode 100644 libraries/UIPEthernet/utility/uip_timer.c delete mode 100644 libraries/UIPEthernet/utility/uip_timer.h delete mode 100644 libraries/UIPEthernet/utility/uipethernet-conf.h delete mode 100644 libraries/UIPEthernet/utility/uipopt.h delete mode 100644 libraries/UIPEthernet/utility/util.h diff --git a/EthernetGateway/EthernetGateway.ino b/EthernetGateway/EthernetGateway.ino index 9059a07..ddafef1 100644 --- a/EthernetGateway/EthernetGateway.ino +++ b/EthernetGateway/EthernetGateway.ino @@ -48,8 +48,6 @@ #include -#include -#include #include #include #include diff --git a/libraries/MySensors/MyMessage.h b/libraries/MySensors/MyMessage.h index c3ae7e3..34deb03 100644 --- a/libraries/MySensors/MyMessage.h +++ b/libraries/MySensors/MyMessage.h @@ -16,7 +16,7 @@ #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 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 From 6aa321cf2e94778409222a896d73fc8b27ce17a3 Mon Sep 17 00:00:00 2001 From: ToSa27 Date: Thu, 24 Jul 2014 13:31:00 +0200 Subject: [PATCH 2/6] Remote reboot capability --- libraries/MySensors/MyMessage.h | 3 ++- libraries/MySensors/MySensor.cpp | 4 ++++ libraries/MySensors/MySensor.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/MySensors/MyMessage.h b/libraries/MySensors/MyMessage.h index 34deb03..a1999b6 100644 --- a/libraries/MySensors/MyMessage.h +++ b/libraries/MySensors/MyMessage.h @@ -41,7 +41,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) diff --git a/libraries/MySensors/MySensor.cpp b/libraries/MySensors/MySensor.cpp index a0ddcf2..87fae97 100644 --- a/libraries/MySensors/MySensor.cpp +++ b/libraries/MySensors/MySensor.cpp @@ -326,6 +326,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 6e16071..5f81727 100644 --- a/libraries/MySensors/MySensor.h +++ b/libraries/MySensors/MySensor.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "utility/LowPower.h" #include "utility/RF24.h" From cdf4d6ab52554f9fe190887559df01f37a70351d Mon Sep 17 00:00:00 2001 From: ToSa27 Date: Thu, 24 Jul 2014 13:34:44 +0200 Subject: [PATCH 3/6] Binary message payload handling --- libraries/MySensors/MyGateway.cpp | 32 ++++++++++++++++++++++++++++--- libraries/MySensors/MyGateway.h | 2 ++ libraries/MySensors/MyMessage.cpp | 24 +++++++++++++++++++++++ libraries/MySensors/MyMessage.h | 6 ++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/libraries/MySensors/MyGateway.cpp b/libraries/MySensors/MyGateway.cpp index 9040bbc..0a929be 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++; @@ -161,7 +184,10 @@ void MyGateway::parseAndSend(char *commandBuffer) { msg.type = type; mSetCommand(msg,command); mSetAck(msg,ack==0?false:true); - msg.set(value); + if (command == C_STREAM) + msg.set(bvalue, blen); + else + msg.set(value); ok = sendRoute(msg); if (!ok) { errBlink(1); @@ -211,7 +237,7 @@ void MyGateway::serial(const char *fmt, ... ) { } void MyGateway::serial(MyMessage &msg) { - serial(PSTR("%d;%d;%d;%d;%s\n"),msg.sender, msg.sensor, mGetCommand(msg), msg.type, msg.getString(convBuf)); + serial(PSTR("%d;%d;%d;%d;%s\n"),msg.sender, msg.sensor, mGetCommand(msg), msg.type, (mGetCommand(msg) == C_STREAM) ? msg.getStream(convBuf) : msg.getString(convBuf)); } 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 96ae96e..39c3cc4 100644 --- a/libraries/MySensors/MyMessage.cpp +++ b/libraries/MySensors/MyMessage.cpp @@ -28,6 +28,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(); diff --git a/libraries/MySensors/MyMessage.h b/libraries/MySensors/MyMessage.h index a1999b6..d8df627 100644 --- a/libraries/MySensors/MyMessage.h +++ b/libraries/MySensors/MyMessage.h @@ -13,6 +13,8 @@ #define MyMessage_h #include +#include +#include #define PROTOCOL_VERSION 2 #define MAX_MESSAGE_LENGTH 32 @@ -92,6 +94,7 @@ typedef enum { // internal access for special fields +#define miGetCommand() BF_GET(command_ack_payload, 0, 3) #define miGetPayloadType() BF_GET(command_ack_payload, 4, 4) #define miGetLength() BF_GET(version_length, 3, 5) @@ -107,11 +110,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; From 1c475da8d0bb173a9049d7442744d48dd22caa2b Mon Sep 17 00:00:00 2001 From: ToSa27 Date: Thu, 24 Jul 2014 13:37:44 +0200 Subject: [PATCH 4/6] OTA Bootloader - including adjustments to library header files to allow usage across C (bootloader) and C++ (firmware sketches) - including definition of new message types for firmware config and firmware code --- Bootloader/.gitignore | 3 + Bootloader/Makefile | 66 ++++++++ Bootloader/MyOtaBootloader.c | 207 +++++++++++++++++++++++++ Bootloader/MyOtaBootloader.h | 67 ++++++++ Bootloader/MyOtaBootloaderHW.h | 154 +++++++++++++++++++ Bootloader/MyOtaBootloaderRF24.h | 253 +++++++++++++++++++++++++++++++ libraries/MySensors/MyMessage.h | 22 ++- libraries/MySensors/MySensor.h | 17 ++- 8 files changed, 781 insertions(+), 8 deletions(-) create mode 100644 Bootloader/.gitignore create mode 100644 Bootloader/Makefile create mode 100644 Bootloader/MyOtaBootloader.c create mode 100644 Bootloader/MyOtaBootloader.h create mode 100644 Bootloader/MyOtaBootloaderHW.h create mode 100644 Bootloader/MyOtaBootloaderRF24.h 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/libraries/MySensors/MyMessage.h b/libraries/MySensors/MyMessage.h index d8df627..ae52f46 100644 --- a/libraries/MySensors/MyMessage.h +++ b/libraries/MySensors/MyMessage.h @@ -12,9 +12,11 @@ #ifndef MyMessage_h #define MyMessage_h -#include +#ifdef __cplusplus +#include #include #include +#endif #define PROTOCOL_VERSION 2 #define MAX_MESSAGE_LENGTH 32 @@ -56,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 { @@ -101,7 +104,7 @@ typedef enum { #define miSetLength(_length) BF_SET(version_length, _length, 3, 5) #define miSetPayloadType(_pt) BF_SET(command_ack_payload, _pt, 4, 4) - +#ifdef __cplusplus class MyMessage { public: @@ -144,6 +147,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 @@ -167,6 +177,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.h b/libraries/MySensors/MySensor.h index 5f81727..b11d787 100644 --- a/libraries/MySensors/MySensor.h +++ b/libraries/MySensors/MySensor.h @@ -15,16 +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__) @@ -47,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 @@ -74,8 +81,7 @@ struct ControllerConfig { uint8_t isMetric; }; - - +#ifdef __cplusplus class MySensor : public RF24 { public: @@ -267,5 +273,6 @@ class MySensor : public RF24 void removeChildRoute(uint8_t childId); void internalSleep(int ms); }; +#endif #endif From cc5a9fe9a8829e5731a4e47234a6eb5dbf44da3d Mon Sep 17 00:00:00 2001 From: ToSa27 Date: Thu, 24 Jul 2014 13:38:55 +0200 Subject: [PATCH 5/6] Node JS controller initial commit --- NodeJsController/BlinkGreen.hex | 71 + NodeJsController/BlinkRed.hex | 71 + .../DallasTemperatureSensor.cpp.hex | 1220 +++++++++++++++++ NodeJsController/NodeJsController.js | 617 +++++++++ NodeJsController/Reboot.js | 45 + NodeJsController/package.json | 9 + 6 files changed, 2033 insertions(+) create mode 100644 NodeJsController/BlinkGreen.hex create mode 100644 NodeJsController/BlinkRed.hex create mode 100644 NodeJsController/DallasTemperatureSensor.cpp.hex create mode 100644 NodeJsController/NodeJsController.js create mode 100644 NodeJsController/Reboot.js create mode 100644 NodeJsController/package.json 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..dbd4fa5 --- /dev/null +++ b/NodeJsController/DallasTemperatureSensor.cpp.hex @@ -0,0 +1,1220 @@ +:100000000C94AE020C94231F0C94501F0C94D60237 +:100010000C94D6020C94D6020C9447140C94D6027D +:100020000C94D6020C94D6020C94D6020C94D602F0 +:100030000C94D6020C94D6020C94D6020C94D602E0 +:100040000C947D1F0C94D6020C9453220C94D6224F +: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 +:10055000F124ECA1E53D27003F09892211241FBEAB +:10056000CFEFD8E0DEBFCDBF11E0A0E0B1E0E8EC16 +:10057000FBE402C005900D92AC35B107D9F713E04A +:10058000ACE5B1E001C01D92A530B107E1F715E07F +:10059000CCE5D5E004C02297FE010E949325C83522 +:1005A000D107C9F70E94FC220C94E2250C940000AC +:1005B000EF92FF920F931F93F22FF02E47FD02C090 +:1005C000E4E001C0E4E1242F332727FD309537FF15 +:1005D00003C0309521953F4F4F2D512F0F2FEE2EF9 +:1005E0000E9455068F2D912F1F910F91FF90EF9034 +:1005F0000895FC0188279927E89421912032E9F396 +:10060000293010F02E30C8F32B3241F02D3239F45E +:10061000689404C00E94DA03820F911D2191205337 +:100620002A30C0F31EF4909581959F4F08951F9333 +:10063000FC0199278827BC01E89411911032E9F355 +:10064000193010F01E30C8F31B3251F01D3249F43E +:10065000689406C00E94C503610F711D811D911D24 +:10066000119110531A30B0F33EF490958095709527 +:1006700061957F4F8F4F9F4F1F910895FB01DC01C4 +:1006800001900D920020E1F70895FB01DC0141503B +:10069000504048F001900D920020C9F701C01D9212 +:1006A00041505040E0F70895A0E0B0E0EAE5F3E003 +:1006B0000C94B5257C01EB018A01690109C0CE01CA +:1006C0002196F6010995F70181937F0101501040B1 +:1006D00001151105A1F7CDB7DEB7E8E00C94D125DF +:1006E000FB019F01E8944230C4F04532B4F44A3033 +:1006F00029F497FB1EF4909581959F4F642F7727DF +:100700000E949725805D8A330CF0895D8193CB012F +:100710000097A1F716F45DE251931082C9010C9481 +:10072000A508FA01CF93FF93EF93223044F12532CD +:1007300034F5C22FE894CA3049F497FB3EF4909503 +:100740008095709561957F4F8F4F9F4F2C2F33274A +:1007500044275527FF93EF930E946F25EF91FF9158 +:10076000605D6A330CF0695D6193B901CA01605044 +:1007700070408040904051F716F4CDE2C193108252 +:100780008F919F91CF910C94A508592F482F372F07 +:10079000262F660F771F881F991F660F771F881FE8 +:1007A000991F620F731F841F951F660F771F881F85 +:1007B000991F08957AE0979F902D879F802D910D26 +:1007C00011240895FA01CF93FF93EF932230CCF0D8 +:1007D0002532BCF4C22F2C2F332744275527FF93F3 +:1007E000EF930E946F25EF91FF91605D6A330CF0EB +:1007F000695D6193B901CA016050704080409040CA +:1008000051F710828F919F91CF910C94A508FB0115 +:100810009F01423074F0453264F4642F77270E94C0 +:100820009725805D8A330CF0895D8193CB01009719 +:10083000A1F71082C9010C94A508AEE0B0E0E3E294 +:10084000F4E00C94B9250D891E898F89988D97FF46 +:1008500002C080E090E801979E838D831A8309830C +:100860008EE08C839E01255E3F4FCE010196698DFF +:100870007A8DA9010E9478044D815E8157FD0AC0DE +:100880002F813885421753070CF49A01020F131F6A +:10089000F80110822E96E4E00C94D525AEE0B0E08D +:1008A000E4E5F4E00C94B9258C0177FF02C060E028 +:1008B00070E8615070407E836D831A8309838EE0F7 +:1008C0008C83CE010196BA01A9010E9478042D8182 +:1008D0003E8137FD09C0EF81F8852E173F070CF4E4 +:1008E000F901E00FF11F10822E96E4E00C94D5255B +:1008F000ABE0B0E0EEE7F4E00C94AB253C012B015B +: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 +:100CA000CB012B96E2E10C94C725A9E0B0E0EBE57F +:100CB000F6E00C94AF256A01122FA02EBE2C2BE378 +: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 +:100F600020E030E0C9012996EEE00C94CB25283032 +: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 +:101280001F930CE511E0C80163E00E94B81D8AE6D7 +:1012900091E0B8010E940F198CE791E069E04AE003 +:1012A0000E94E91385E392E060E040E00E94330A87 +:1012B0001F910F910895CF92DF92EF92FF920F93BB +:1012C0001F93CF93DF938CE791E00E94790D8AE61C +:1012D00091E00E94041A83EFC82E81E0D82EC0E06E +:1012E000D0E056C08CE791E00E941B0B882331F0C0 +:1012F0008AE691E06C2F0E94271B05C08AE691E0E8 +:101300006C2F0E944E1B20E030E040E251E40E942E +:101310000C250E942924882777FD8095982F0E940C +:101320005C2420E030E040E251E40E94C1237B01D4 +:101330008C01F6016081718182819381A8019701FE +:101340000E94BD238823F9F0C801B70120E030E0F6 +:101350004EEF52EC0E94BD238823A9F085E392E072 +:101360006C2F0E94380AB801A70121E00E94470AA9 +:10137000BC018CE791E040E00E942112F601E0827E +:10138000F18202831383219684E090E0C80ED91E77 +:101390008091330290913402C817D90724F4C031E8 +:1013A000D10509F09FCF60914001709141018CE718 +:1013B00091E00E94800CDF91CF911F910F91FF90DF +:1013C000EF90DF90CF900895AF92BF92CF92EF92BF +:1013D000FF920F93CF93DF938AE691E00E945D1B0B +:1013E0008CE791E060E070E04FEF20E00FEFE3E08A +:1013F000EE2EF12C5CE4C52E32E0A32EB12C0E941F +:10140000B3128CE791E060E071E043E151E020E04D +:101410000E94B1118AE691E00E941D198093330267 +:1014200010923402C0E0D0E008C08CE791E06C2F4D +:1014300046E020E00E94FF112196809133029091B6 +:101440003402C817D9071CF4C031D10571F7DF91F8 +:10145000CF910F91FF90EF90CF90BF90AF900895F4 +:10146000FC0114820895FC0114826683458308956B +:10147000FC0166830895FC01808187708860808309 +:1014800081818F70806181836783CF010895CF92BE +:10149000DF92EF92FF920F931F937C01F7E0CF2E24 +:1014A000D12CC80ED91ECB01BA0142E086010E94A0 +:1014B000D802F60101900020E9F73197EC19FD09F7 +:1014C000EE0FEE0FEE0FD7018C918770E82BEC93A7 +:1014D00011968C9111978F7011968C93C7011F9163 +:1014E0000F91FF90EF90DF90CF900895CF93DF930F +:1014F000EC01DB010D900020E9F71197A61B4A2FA4 +:1015000050E09A01B3E0220F331FBA95E1F78881CA +:101510008770822B888389818F708983A93110F02D +:1015200049E150E0CE0107960E944503CE01DF91CC +:10153000CF910895FC01818182958F7090E0009792 +:1015400031F0019711F080E0089587810895CF016F +:1015500007960E94F9020895FC01818182958F709F +:1015600090E0009761F0059729F020E030E040E03E +:1015700050E00EC0278130854185528509C0CF01DA +:1015800007960E941703AC01CB01DA019C01AD0163 +:10159000B901CA010895CF93DF93FC01EB0181816A +:1015A00082958F7031F43796CB01BF010E943E03C4 +:1015B00036C06115710599F18330B9F0843028F493 +:1015C000813041F0823059F508C08430A9F085306F +:1015D00031F51CC0878190E002C087819085BE01F3 +:1015E0004AE050E00E9470031AC0878190854AE06B +:1015F00050E00E94070413C0678170858185928541 +:10160000AE012AE030E00E94910309C06781708535 +:1016100081859285AE012AE030E00E94E203CE018E +:10162000DF91CF9108959C01F999FECF32BD21BD84 +:10163000F89A80B50895FC0181890895EF92FF9290 +:101640000F931F93DF93CF93CDB7DEB7CC52D1402A +:101650000FB6F894DEBF0FBECDBFC95CDE4FE88089 +:10166000F980C753D140CB5CDE4FA881B981C55307 +:10167000D14054968C91882389F1EDB7FEB73A9703 +:101680000FB6F894FEBF0FBEEDBF31968E010F5F0F +:101690001F4FADB7BEB712961C930E9311978BE2F6 +:1016A00091E09383828388E690E09583848383E04E +:1016B00090E09783868389E090E0918780870E94FD +:1016C0001D04EDB7FEB73A960FB6F894FEBF0FBEF5 +:1016D000EDBF84E692E0B8010E945423FE01E75C6E +:1016E000FE4FCB5CDE4FA881B981C553D1405496E3 +:1016F0008C919E012F5F3F4F882359F0C9016CE305 +:1017000070E0A7019F010E944E048AE08CAF1DAEDD +:1017100007C0C9016BE271E0A7019F010E944E045E +:1017200084E692E0BE016F5F7F4F0E94542384E6FF +:1017300092E00E94E121C45DDE4F0FB6F894DEBF57 +:101740000FBECDBFCF91DF911F910F91FF90EF9012 +:101750000895CF93DF93EB010CC086E592E069E03A +:1017600070E040E050E020E030E00E94F913C05407 +:10177000DF418091440190914501892B89F08FE1EF +:10178000C034D80754F7B3C086E592E068E070E053 +:1017900040E050E020E030E00E94F913C05ADF4002 +:1017A0008091440190914501892B81F087E0C03DF3 +:1017B000D80764F086E592E067E070E040E050E032 +:1017C00020E030E00E94F913C05DD74080914401D1 +:1017D00090914501892B81F083E0C83ED80764F0E1 +:1017E00086E592E066E070E040E050E020E030E026 +:1017F0000E94F913C85ED340809144019091450145 +:10180000892B81F081E0C43FD80764F086E592E03F +:1018100065E070E040E050E020E030E00E94F91325 +:10182000C45FD1408091440190914501892B79F0AA +:10183000CA3FD10564F086E592E064E070E040E0E4 +:1018400050E020E030E00E94F913CA5FD040809160 +:10185000440190914501892B79F0CD37D10564F091 +:1018600086E592E063E070E040E050E020E030E0A8 +:101870000E94F913C857D0408091440190914501CE +:10188000892B71F0C034D1055CF086E592E062E00E +:1018900070E040E050E020E030E00E94F913EC9767 +:1018A0008091440190914501892B71F0C032D1059E +:1018B0005CF086E592E061E070E040E050E020E01E +:1018C00030E00E94F9136E97809144019091450198 +:1018D000892B99F060978CF086E592E060E070E0EB +:1018E00040E050E020E030E00E94F91306C08FE0B5 +:1018F000C03AD8070CF454CF47CFDF91CF91089569 +:10190000EF92FF920F931F938C017B0184E692E08C +:101910000E94E121C8010E941E1881E090E090938E +:10192000450180934401C801B7010E94A90B1F9192 +:101930000F91FF90EF9008955F926F927F928F9238 +:101940009F92AF92BF92CF92DF92EF92FF920F934E +:101950001F93CF93DF937C01562EEA01822E88815C +:10196000982E969496949694D7011E969C919B835C +:10197000887F82608883DE2CCF2CC7010E940318E9 +:10198000C7010E94331830E040E050E060E070E0B2 +:1019900080E090E0052DF1E03D3F08F4F0E0E1E06B +:1019A000423E08F4E0E031EEA32EAF0EE060F1E03D +:1019B000593A08F4F0E028EAB22EBE0EE1E0B8EAA7 +:1019C000BB1608F0E0E0FE2BA1E0693A08F4A0E0C5 +:1019D000BF2FB855E1E0B83A08F0E0E0AE2BF1E0F7 +:1019E000772309F4F0E0E1E0882309F4E0E08D2DAD +:1019F0009C2D1CEF95014B2F5A2F6F2F7E2F0E948D +:101A00004416892D90E04A9714F040E202C0492D17 +:101A1000495F8D2D9C2DBE01282D0E94F715682E43 +:101A20008D2D9C2D0E944E18BA80AB809C808E809C +:101A300019817D800881662029F497E1C92E91E003 +:101A4000D92E04C08CE1C82E81E0D82EB701695A86 +:101A50007F4FCE010E94CB0AEDB7FEB77A970FB643 +:101A6000F894FEBF0FBEEDBF3196ADB7BEB712966C +:101A7000FC92EE9211972DED30E033832283B482F5 +:101A80001582A682178250861186928613868486D6 +:101A90001586212F30E02770307037872687708AAF +:101AA000118A12951F70128B138A0695069506955A +:101AB000048B158AD78AC68A918F808F0E941E0B4D +:101AC000EDB7FEB77A960FB6F894FEBF0FBEEDBF26 +:101AD000862DDF91CF911F910F91FF90EF90DF90B6 +:101AE000CF90BF90AF909F908F907F906F905F90BE +:101AF00008954F925F926F927F928F929F92AF92D2 +:101B0000BF92CF92DF92EF92FF920F931F93DF93DA +:101B1000CF930F92CDB7DEB74C01582E492C8E01D2 +:101B20000F5F1F4FB8010E94E417882309F4D5C244 +:101B30008981873008F0D1C2C4010E94F414482F73 +:101B400065E1662E712C680C791CC401B3010E94FA +:101B5000EA15C4016981A80121E00E948614D4011C +:101B600055960C9106950695069510E0F401E00F48 +:101B7000F11F148EF401E788D08CC18CB38CF688E9 +:101B8000A28CB401695A7F4FC3010E94CB0A2DB7C2 +:101B90003EB7265130400FB6F8943EBF0FBE2DBF62 +:101BA000EDB7FEB73196ADB7BEB712969C928E9246 +:101BB000119720EB30E033832283E4821582D682B2 +:101BC0001782C0861186B28613862F2D30E02770CB +:101BD000307035872487A6861786F2945FE0F52259 +:101BE000F08A118A138B028B958B848B0E941E0BBB +:101BF000F401858987702DB73EB72A5E3F4F0FB637 +:101C0000F8943EBF0FBE2DBF8230B1F000D000D09F +:101C1000ADB7BEB712969C928E9211978FE990E065 +:101C200014969C938E9313970E941E0B80E00F9046 +:101C30000F900F900F9052C2F4012689022F077067 +:101C4000128DE788F08C318D9289992379F10330D8 +:101C500069F5173059F50E94C51F73708070907038 +:101C60000E941820D4011E968C911E9757968C9333 +:101C700057975996EC9259978FEF5B968C935B9799 +:101C800088E05A968C935A9756968C915697807FF7 +:101C9000836056968C935697C30150966C910E9420 +:101CA0003B0AAC01C4016E2D21E0F5C1F40186852B +:101CB000381709F0DBC123FF21C0D401D6967596F1 +:101CC00081E201900D928150E1F7D401D7968C9179 +:101CD000D797877FD7968C93D7971E968C911E9710 +:101CE000D8968C93D89757968C915797DA968C9371 +:101CF000B4016A5C7F4FC4010E944211F4018289E1 +:101D0000882319F18785F81601F12E2D30E081E73F +:101D100090E0880E991ED401ED91FC918FE89FEF21 +:101D2000880E991EE20FF31F80818F1571F0F082EB +:101D3000F999FECF1FBA2D5F3F4F32BD21BDF0BCD8 +:101D40000FB6F894FA9AF99A0FBE033009F081C1E0 +:101D5000183009F053C0D40154968C91882309F0AF +:101D60004DC0C3010E949A0A482F282F30E0F40189 +:101D7000808990E00197281739070CF0AEC14F5FBA +:101D8000408B27892787F999FECF1FBA81E090E021 +:101D900092BD81BD20BD0FB6F894FA9AF99A0FBE94 +:101DA000D40150963C91F999FECF1FBA82E090E0A1 +:101DB00092BD81BD30BD0FB6F894FA9AF99A0FBE64 +:101DC000EDB7FEB738970FB6F894FEBF0FBEEDBF64 +:101DD0003196ADB7BEB712969C928E9211978AE853 +:101DE00090E09383828324831582368317820E9436 +:101DF0001E0B80E0EDB7FEB73896A3C0EE2009F0C9 +:101E000028C1163009F4A3C0173038F4113009F492 +:101E10000FC1143009F061C112C01A3009F4B0C00A +:101E20001D3009F05AC128E088E190E00FB6F8941F +:101E3000A895809360000FBE20936000FFCFD4016F +:101E40001E968C918F3F09F048C1C3010E949A0AE7 +:101E5000F40186878F3FA9F400D000D0ADB7BEB79C +:101E600012969C928E92119784E890E014969C931F +:101E70008E9313970E941E0B0F900F900F900F9050 +:101E8000FFCF282F30E040E050E060E070E080E0DD +:101E900090E0E22E01E03D3F08F400E011E0423E18 +:101EA00008F410E00F511060E1E0593A08F4E0E066 +:101EB0001855F1E0183A08F0F0E0EF2BF1E0693A3C +:101EC00008F4F0E0BE2FB855E1E0B83A08F0E0E0E1 +:101ED000FE2BA1E0772309F4A0E0E1E0882309F4D8 +:101EE000E0E0852D942D61E04CEFF42E2B2F3F2F59 +:101EF0004A2F5E2F0E946517F4012685F999FECFBF +:101F00001FBA12BC11BC20BD0FB6F894FA9AF99A08 +:101F10000FBE00D000D000D0EDB7FEB73196ADB700 +:101F2000BEB712969C928E9211978DE790E09383A4 +:101F30008283248315820E941E0B80E0EDB7FEB7DA +:101F400036960FB6F894FEBF0FBEEDBFC7C0C301F3 +:101F50000E949A0A20E08D3409F421E0D4015196C0 +:101F60008C915197821709F4B8C051962C93F99926 +:101F7000FECF1FBA83E091E092BD81BD20BDA8C015 +:101F8000F4018289882309F4A8C0C3010E949A0A37 +:101F9000833409F0A2C000D000D0ADB7BEB712960E +:101FA0009C928E92119783E790E014969C938E9367 +:101FB00013970E941E0B20E030E00F900F900F90BF +:101FC0000F90D401AF58BF4F9FEFED91FC91119747 +:101FD000E20FF31F80818F3F81F09083F999FECF4C +:101FE0001FBA2D5F3F4F32BD21BD2350304090BD01 +:101FF0000FB6F894FA9AF99A0FBE2F5F3F4F22302E +:10200000310519F7F4018685878B118E8FEF838F49 +:102010008AE0828F8689807F8360868BC3016FE12F +:1020200071E00E94760ABC01C4010E94421155C0B1 +:1020300023E730E0820E931ED4010D911C9101150F +:10204000110509F44AC0C3010E94AC0AF8010995C0 +:1020500044C0E5E7F0E08E0E9F1ED401ED91FC91A7 +:10206000309711F0C301099581E038C09923A9F197 +:102070008981813091F584010F581F4FD801ED916E +:10208000FC91E30FF11D6081862F81508E3F30F46B +:10209000C401A30120E00E949C0C1FC0C401F401F4 +:1020A0006785A30120E00E949C0C6E2D70E0D80192 +:1020B000ED91FC91E60FF71F80818F1571F0F08292 +:1020C000F999FECF1FBA6D5F7F4F72BD61BDF0BC45 +:1020D0000FB6F894FA9AF99A0FBE80E00F90CF915C +:1020E000DF911F910F91FF90EF90DF90CF90BF9005 +:1020F000AF909F908F907F906F905F904F900895DA +:10210000EF92FF920F931F93CF93DF93EC010E9406 +:10211000C51F7B018C0103C0CE010E94790D0E9476 +:10212000C51F6E197F09800B910B605D7740804061 +:10213000904090F3DF91CF911F910F91FF90EF901E +:102140000895EF92FF920F931F938C0100591F4F38 +:10215000F8011082005710409FEFF801908B8685A0 +:10216000878B918F938F87E0828F8689807F8360B2 +:10217000868B75E1E72EF12CE00EF11EC7016FE1B1 +:1021800071E00E94760AC8016FEFA70121E00E946A +:102190009C0CC8010E9480101F910F91FF90EF903E +:1021A0000895EF92FF920F931F93CF93DF93EC016B +:1021B00000D000D0EDB7FEB79283818383E191E038 +:1021C000948383830E941E0B0F900F900F900F90AB +:1021D0008E85282F30E040E050E060E070E080E045 +:1021E00090E0E22E01E03D3F08F400E011E0423EC5 +:1021F00008F410E00F511060E1E0593A08F4E0E013 +:102200001855F1E0183A08F0F0E0EF2BF1E0693AE8 +:1022100008F4F0E0BE2FB855E1E0B83A08F0E0E08D +:10222000FE2BA1E0772309F4A0E0E1E0882309F484 +:10223000E0E0CE0161E02CEFF22E2B2F3F2F4A2F52 +:102240005E2F0E9465178E858F8B198E8FEF8B8F77 +:1022500083E08A8F8E89807F83608E8BCE01459646 +:102260006FE171E00E94760ABC01CE010E9442112A +:10227000CE010E948010DF91CF911F910F91FF90AE +:10228000EF9008951F93CF93DF93EC01DB0120E0E3 +:1022900011968C9111978770833009F421E08E8517 +:1022A0008F3F59F4222329F015968C91159783308E +:1022B00021F0CE010E94D1102CC08A89882331F1EF +:1022C00014969C911497CF58DF4FE881F981C1573C +:1022D000D040E90FF11D6081862F81508E3F30F490 +:1022E000992321F0CE01AD0120E00DC0222371F031 +:1022F00015968C911597843049F49F3F39F4CE019F +:102300006FEFAD0121E00E949C0C27C08C898823CF +:1023100011F080E022C0CE016F85AD0120E00E9467 +:102320009C0C182F882329F011E0C059DF4F188228 +:1023300013C08B89882351F0C059DF4F8881C05763 +:10234000D040863018F0CE010E94A110FE01E05965 +:10235000FF4F80818F5F8083812FDF91CF911F910D +:102360000895FF920F931F93CF93DF93EC018A019F +:10237000F22E61157105E1F08E858F8B198E8FEF2E +:102380008B8F8BE08A8F30E02170307053E0220F0A +:10239000331F5A95E1F78E89807F8360822B8E8B65 +:1023A000CE0145960E94760ABC01CE010E944211E0 +:1023B00001151105F1F08E858F8B198E8FEF8B8FA4 +:1023C0008CE08A8F2F2D30E02170307043E0220F97 +:1023D000331F4A95E1F78E89807F8360822B8E8B35 +:1023E000CE014596B8010E94760ABC01CE010E943A +:1023F0004211DF91CF911F910F91FF9008950F939C +:102400001F938C01FC018685878B118E638F428F11 +:1024100030E02170307063E0220F331F6A95E1F7DE +:102420008689807F822B868BC801459660E271E0A9 +:102430000E94760ABC01C8010E9442111F910F91AF +:102440000895DC01FB011E968C911E97828350E05B +:102450004170507083E0440F551F8A95E1F78181E8 +:10246000807F8160842B8183CD010E944211811184 +:1024700081E008950F931F938C0180E091E00E940A +:102480000B230F581F4FF8018083918363E070E0A6 +:1024900040E051E023E13BE00E9454031F910F9183 +:1024A0000895EF92FF920F931F93CF93DF93EC0168 +:1024B000E62EF42E8901C059DF4F1882C057D04054 +:1024C000CE010E948718CE010E946C14882389F4E3 +:1024D00000D000D0EDB7FEB7D283C18380E291E097 +:1024E000948383830E941E0B0F900F900F900F9088 +:1024F000FFCFCE0161E00E94E015CE0162E040E036 +:102500000E94FE16CE010E942A17CE016F2D0E9456 +:102510001116CE016E2D0E94E516CE01B8010E9463 +:10252000B416CE0165E04FE00E94D615CE0162E000 +:1025300070E00E949916CE010E944617CE0162E01B +:10254000EE24EA942CEFF22E01EE18EA28EA30E0AD +:1025500040E050E00E946517DF91CF911F910F91ED +:10256000FF90EF9008958F929F92AF92BF92CF927B +:10257000DF92EF92FF920F931F93CF93DF93EC01C3 +:102580004B01D42E122F84E692E040E052EC61E041 +:1025900070E026E00E9443211C8A1A8A112311F060 +:1025A00081E08A8BCB58DF4F99828882C557D04013 +:1025B0008A89882319F0CE010E943A12CE01B70110 +:1025C0004C2D95010E945112CE010E9660E070E0F4 +:1025D00043E050E023E13BE00E945403CE014196EA +:1025E00063E271E041E050E023E13BE00E945403EC +:1025F00089898F3F11F481E0898B0F3F19F00F8794 +:102600001B8A02C081E08B8B8FEFD812DE868B890C +:10261000882331F08F858F3F19F4CE010E94A110DD +:102620008E858F3F19F4CE010E94D1108A898823AC +:1026300019F420E331E002C027E331E0ADB7BEB7C3 +:1026400018970FB6F894BEBF0FBEADBFEDB7FEB77B +:1026500031961296DC93CE9311978DE291E093839D +:102660008283358324838E85868317820E941E0B86 +:10267000DC2ECD2E8DB79EB708960FB6F8949EBF70 +:102680000FBE8DBF8E85282F30E040E050E060E027 +:1026900070E080E090E0E22E01E03D3F08F400E0D1 +:1026A00011E0423E08F410E00F511060E1E0593AA9 +:1026B00008F4E0E01855F1E0183A08F0F0E0EF2BEC +:1026C000F1E0693A08F4F0E0BE2FB855E1E0B83A1D +:1026D00008F0E0E0FE2BA1E0772309F4A0E0E1E0C0 +:1026E000882309F4E0E08D2D9C2D60E04CEFF42E62 +:1026F0002B2F3F2F4A2F5E2F0E9465178E85282F84 +:1027000030E040E050E060E070E080E090E0E22EF9 +:1027100001E03D3F08F400E011E0423E08F410E023 +:102720000F511060E1E0593A08F4E0E01855F1E08B +:10273000183A08F0F0E0EF2BF1E0693A08F4F0E025 +:10274000BE2FB855E1E0B83A08F0E0E0FE2BA1E07A +:10275000772309F4A0E0E1E0882309F4E0E08D2D7F +:102760009C2D61E03CEFF32E2B2F3F2F4A2F5E2F45 +:102770000E9465178A89882311F441E101C042E172 +:10278000CE016FEF20E00E94FF118E858F8B198E96 +:102790008FEF8B8F86E08A8F8E89807F83608E8B10 +:1027A000CE0145966F850E943B0ABC01CE010E9476 +:1027B0004211CE010E948010DF91CF911F910F91A5 +:1027C000FF90EF90DF90CF90BF90AF909F908F9051 +:1027D00008950F931F938C010E945B14C8014596C6 +:1027E0000E94300AC801C6960E94300A1F910F91BC +:1027F00008954115510529F480917A008F778093CF +:102800007A006A307105B9F063FD02C0E8E001C0EA +:10281000E8E2862F8770E82B88E190E00FB6F89405 +:10282000A895809360000FBEE093600080916000E7 +:10283000806480936000232BA1F483B7817F846040 +:1028400083BFF89483B7816083BF85B7806685BFF7 +:102850008F7D85BF7894889583B78E7F83BF78946A +:102860000EC083B7817F846083BFF89483B7816093 +:1028700083BF7894889583B78E7F83BF7894452BE8 +:1028800029F480917A00806880937A0008951F92DD +:102890000F920FB60F9211248F9388E10FB6F89420 +:1028A00080936000109260000FBE8F910F900FBE5A +:1028B0000F901F901895FC01608341831282138250 +:1028C00080E2848315821682178210861186128612 +:1028D0001386148615860895FC0183810895FF925E +:1028E0000F931F938C01F62E81E00E94D91880E08F +:1028F0000E94E21884E00E94E718F80181816F2DA0 +:102900000E94BF201F910F91FF900895EF92FF92B8 +:102910000F931F93CF93DF93EC01162F042FF52E07 +:10292000E22E60E00E946F141770186A1EBD0DB48D +:1029300007FEFDCF802F9F2D9C01F9012E2D213206 +:1029400008F020E28EB508C080818EBD0DB407FE70 +:10295000FDCF31968EB521502223B1F7CE0161E033 +:102960000E946F14DF91CF911F910F91FF90EF9014 +:102970000895CF93DF93EC0160E00E946F1480E52F +:102980008EBD0DB407FEFDCF8EB583E78EBD0DB4B1 +:1029900007FEFDCF8EB5CE0161E00E946F14DF917E +:1029A000CF9108951F93CF93DF93EC01162F60E032 +:1029B0000E946F141EBD0DB407FEFDCF1EB5CE01E3 +:1029C00061E00E946F14812FDF91CF911F910895D4 +:1029D0006FEF0E94D214089561EE0E94D214089500 +:1029E00062EE0E94D21408951F93CF93DF93EC01FF +:1029F00060E00E946F1480E68EBD0DB407FEFDCF2F +:102A00008EB58FEF8EBD0DB407FEFDCF1EB5CE0186 +:102A100061E00E946F14113220F0CE010E94F01488 +:102A200010E0812FDF91CF911F910895EF92FF92D7 +:102A30000F931F93CF93DF93EC01F62EE72E9C812B +:102A4000142F941708F4192F8D81882311F000E0BA +:102A500002C0092F011BCE0160E00E946F1481E6C5 +:102A60008EBD0DB407FEFDCF8F2D9E2D9C01F9016B +:102A7000FEB49FEF07C09EBD0DB407FEFDCF8EB51F +:102A8000819311501123B9F707C08EBD0DB407FE15 +:102A9000FDCF9EB5015001C08FEF0023B1F7CE01ED +:102AA00061E00E946F148F2DDF91CF911F910F91E4 +:102AB000FF90EF900895DF92EF92FF920F931F9394 +:102AC000CF93DF93EC01E62ED72EF22E9C81142FAC +:102AD000941708F4192F8D81882311F000E002C0AB +:102AE000092F011BCE0160E00E946F14FEBC0DB4E3 +:102AF00007FEFDCF8E2D9D2D9C01F901FEB408C06F +:102B000080818EBD0DB407FEFDCF31968EB511507C +:102B10001123B1F706C01EBC0DB407FEFDCF8EB564 +:102B200001500023C1F7CE0161E00E946F148F2D88 +:102B3000DF91CF911F910F91FF90EF90DF9008955B +:102B4000CF93DF93EC01222311F420EA01C020EBA4 +:102B5000CE010E945B15888161E00E94BF208881C0 +:102B600060E00E94BF20DF91CF9108950F931F93E3 +:102B7000CF93DF93EC01162F042F60E00E946F14B7 +:102B80001F7110621EBD0DB407FEFDCF1EB50EBD38 +:102B90000DB407FEFDCF8EB5CE0161E00E946F142B +:102BA000812FDF91CF911F910F910895262F4F70A4 +:102BB0002295207F242B64E0422F0E94B6150895B1 +:102BC000662319F061E04FE302C061E040E00E943B +:102BD000B61508950F931F938C010E941615C80116 +:102BE00067E040E70E94B6151F910F910895CF93BB +:102BF000DF93EC010E94A015CE010E94E8148073BF +:102C0000D9F3CE0167E040E70E94B61584FD02C00B +:102C100081E004C0CE010E94EC1480E0DF91CF91EE +:102C20000895462F603808F04FE765E00E94B6151A +:102C30000895EF92FF920F931F93CF93DF937C0140 +:102C4000162FEA01022F60E00E946F141F711062BC +:102C50001EBD0DB407FEFDCF1EB508C088818EBD18 +:102C60000DB407FEFDCF21968EB501500023B1F7BC +:102C7000C70161E00E946F14812FDF91CF911F91F6 +:102C80000F91FF90EF900895EF92FF920F931F9393 +:102C9000DF93CF93CDB7DEB728970FB6F894DEBF9A +:102CA0000FBECDBF7C0109831A832B833C834D83E8 +:102CB0005E836F8378878E010F5F1F4F6AE0A801E4 +:102CC00025E00E941916C70160E1A80125E00E94D5 +:102CD0001916C70161E1F70144810E94B6152896D3 +:102CE0000FB6F894DEBF0FBECDBFCF91DF911F911D +:102CF0000F91FF90EF9008951F93CF93DF93EC0116 +:102D0000162F60E00E946F141F711EBD0DB407FEE8 +:102D1000FDCF8EB58FEF8EBD0DB407FEFDCF1EB576 +:102D2000CE0161E00E946F14812FDF91CF911F913E +:102D300008950F931F93CF93DF938C01EB0160E015 +:102D40000E947C16482F437F209729F0219711F489 +:102D5000486001C04C60C80160E00E94B615DF9178 +:102D6000CF911F910F910895FF920F931F93CF93CF +:102D7000DF93EC018B0166E00E947C161A82F7ED6E +:102D8000FF2EF8220230110511F480E206C0013056 +:102D9000110529F481E08A8388E0F82A01C01A82AB +:102DA000CE0166E04F2D0E94B615CE0166E00E946E +:102DB0007C168F1511F481E002C01A8280E0DF9149 +:102DC000CF911F910F91FF9008951F93CF93DF93A1 +:102DD000EC01162F66E00E947C16143010F04CE0D7 +:102DE00003C0412F440F4F5F887F482BCE0166E020 +:102DF0000E94B615DF91CF911F9108950F931F93F5 +:102E0000CF93DF93EC01162F042F6730F0F461E0CD +:102E10000E947C16282F002351F081E090E002C030 +:102E2000880F991F1A95E2F7422F482B0AC081E0BC +:102E300090E002C0880F991F1A95E2F7482F40953D +:102E40004223CE0161E00E94B615DF91CF911F9120 +:102E50000F9108950F931F938C010E94B914C8011C +:102E60006DE10E947C16482F4660C8016DE10E940A +:102E7000B615C8016CE10E947C16482F4360C8015A +:102E80006CE10E94B6151F910F9108950F931F9347 +:102E90008C010E94B914C8016DE10E947C16482F74 +:102EA0004460C8016DE10E94B615C8016CE10E9442 +:102EB0007C16482F4F63C8016CE10E94B61581E073 +:102EC000F80185831F910F910895BF92CF92DF92F1 +:102ED000EF92FF920F931F93DF93CF93CDB7DEB79F +:102EE00028970FB6F894DEBF0FBECDBF6C01B62E8B +:102EF000E982FA820B831C832D833E834F8358879C +:102F0000662389F4F601E6828A8187838B81808734 +:102F10008C8181878D8182878E8183878F81848751 +:102F20008885858707C0F6E0F61708F43DC081E084 +:102F3000681761F4EB2DF0E0EA5BFE4FE491C60107 +:102F40006E2FAE014F5F5F4F25E00BC0E62FF0E024 +:102F5000EA5BFE4FE491C6016E2FAE014F5F5F4FFB +:102F600021E00E9419160B2D10E0F801E45BFE4FE2 +:102F7000E491C6016E2FF60144810E94B615C60188 +:102F800062E00E947C16005C1E4FF801649121E013 +:102F900030E002C0220F331F6A95E2F7482F422B20 +:102FA000C60162E00E94B61528960FB6F894DEBFFF +:102FB0000FBECDBFCF91DF911F910F91FF90EF908A +:102FC000DF90CF90BF9008950F931F93CF93DF931F +:102FD000EC018B0167E10E947C1680FF02C080E05B +:102FE0000DC00115110549F0CE010E94E81490E0D2 +:102FF000959587958770F801808381E0DF91CF9167 +:103000001F910F910895CF93DF93EC0160E00E9430 +:103010007C1681FD10C0CE0160E00E947C16482F16 +:103020004260CE0160E00E94B61565E070E080E08D +:1030300090E00E941820DF91CF9108950F931F9385 +:103040008C01FC01808160E00E94BF20C80160E02B +:103050000E947C16482F4D7FC80160E00E94B61583 +:103060001F910F9108950F931F938C01FC01808194 +:1030700060E00E94BF20C8010E94EC14C8010E94B9 +:10308000F014C80160E00E947C16482F4E7FC801F2 +:1030900060E00E94B6151F910F910895CF93DF93C2 +:1030A000EC010E940318CE0160E00E947C16482FBC +:1030B0004160CE0160E00E94B615CE0167E040E7B6 +:1030C0000E94B6158E819F81892B9885892B9985C1 +:1030D000892B9A85892B9B85892B9C85892B9D859E +:1030E000892B41F0AE014A5F5F4FCE016AE025E0D7 +:1030F0000E941916CE010E94F014CE010E94EC1419 +:10310000888161E00E94BF20DF91CF910895CF9325 +:10311000DF93EC01888161E00E948020898161E079 +:103120000E9480200E94F818888160E00E94BF20E1 +:10313000CE0161E00E946F1465E070E080E090E0F5 +:103140000E941820CE0165E04FE00E94D615CE0106 +:1031500062E070E00E94B416882311F081E08B8356 +:10316000CE0160E070E00E94B416CE0162E070E033 +:103170000E949916CE0167E040E70E94B615CE0185 +:103180006CE40E941116CE010E94F014CE010E9440 +:10319000EC14CE010E940318CE0160E00E947C1660 +:1031A000482F4E7FCE0160E00E94B615DF91CF918F +:1031B0000895882319F48CB5806202C08CB58F7D88 +:1031C0008CBD08959CB5937F982B9CBD08952CB51C +:1031D000382F33702C7F322B3CBD2DB590E0959568 +:1031E00087959595879581702E7F822B8DBD08954B +:1031F0008AE061E00E94BF208AE061E00E948020B6 +:103200008CB580618CBD8CB580648CBD8DE061E037 +:103210000E9480208BE061E00E9480200895FC01E4 +:1032200087ED99E1918B808B758364831382108283 +:103230008FE190E0928381830895FC01838108955A +:103240006F927F928F929F92AF92BF92CF92DF92B6 +:10325000EF92FF920F931F93CF93DF93FB01EA014D +:10326000998180E0288130E0282B392BE081E232FF +:1032700031F0E83221F0E03109F084C04BC04C81DC +:103280004F3329F1403420F44F3109F07BC02FC077 +:103290004F3579F04F3709F075C0B901882777FDB0 +:1032A0008095982F0E945C2420E030E040E85DE3A8 +:1032B0002EC035952795B901882777FD8095982FE1 +:1032C0000E945C2420E030E040E05EE320C03595C1 +:1032D000279535952795B901882777FD8095982FF3 +:1032E0000E945C2420E030E040E85EE310C093E000 +:1032F000359527959A95E1F7B901882777FD80954F +:10330000982F0E945C2420E030E040E05FE30E94C0 +:103310000C2532C0EF8035952795B901882777FDB8 +:103320008095982F0E945C2420E030E040E85EE326 +:103330000E9458233B014C016E2D70E02E81621BD0 +:103340007109882777FD8095982F0E945C245B0186 +:103350006C01FF2400E010E0C801B7010E945A246C +:103360009B01AC01C601B5010E94C1239B01AC01C8 +:10337000C401B3010E9459239B01AC01832F942FF8 +:10338000752F00C0262F382F492F572FB901CA019A +:10339000DF91CF911F910F91FF90EF90DF90CF9031 +:1033A000BF90AF909F908F907F906F9008950895F9 +:1033B000EF92FF920F931F938C017B01FC0184819C +:1033C00095810E94D71CF80184819581B7010E94E4 +:1033D000B61CF8018481958164EB40E00E94711C69 +:1033E000F801848195810E94EC1BF82EF8018481FC +:1033F00095810E94D71C80E0FF2009F481E01F9195 +:103400000F91FF90EF9008950F931F938C01FC0193 +:10341000848195810E94D71CF801848195810E9446 +:10342000B11CF8018481958164E440810E94711C83 +:10343000F801818192818F33910551F08F3591058B +:1034400061F04F9779F46EE570E080E090E00EC097 +:103450006CEB70E080E090E009C067E771E080E02D +:1034600090E004C06EEE72E080E090E00E941820D0 +:103470001F910F910895CF92DF92EF92FF920F93D9 +:103480001F938C016B017A01FC01848195810E945C +:10349000D71CF80184819581B6010E94B61CF80101 +:1034A000848195816EEB40E00E94711CF80184815B +:1034B00095810E94201CF7018083F8018481958109 +:1034C0000E94201CF7018183F801848195810E946C +:1034D000201CF7018283F801848195810E94201CC1 +:1034E000F7018383F801848195810E94201CF701F4 +:1034F0008483F801848195810E94201CF7018583D3 +:10350000F801848195810E94201CF7018683F801CF +:10351000848195810E94201CF7018783F8018481B2 +:1035200095810E94201CF7018087F8018481958194 +:103530000E94D71C1F910F91FF90EF90DF90CF90CA +:1035400008950F931F938A010E943B1AC80168E0F7 +:103550000E94DB1B20E0F8019085891709F421E027 +:10356000822F1F910F910895CF92DF92EF92FF92D9 +:103570000F931F93DF93CF93CDB7DEB729970FB685 +:10358000F894DEBF0FBECDBF8C017B016E010894A5 +:10359000C11CD11CA6010E94A11A882329F460E055 +:1035A00070E08EEF92EC05C0C801B701A6010E9441 +:1035B000201929960FB6F894DEBF0FBECDBFCF916C +:1035C000DF911F910F91FF90EF90DF90CF900895C2 +:1035D0000F931F938B01CB0167E00E94DB1B20E060 +:1035E000F8019781891709F421E0822F1F910F912B +:1035F0000895EF92FF920F931F93CF93DF93EC0107 +:103600007B01042F8C819D810E94CE1B10E007C09E +:10361000CE01B7010E94E81A8823A9F00AC08C8164 +:103620009D81B7010E94221D882329F0101759F4AB +:10363000EFCF81E001C080E0DF91CF911F910F912A +:10364000FF90EF9008951F5F0117A8F3E8CFEF9266 +:10365000FF920F931F93DF93CF93CDB7DEB72897D9 +:103660000FB6F894DEBF0FBECDBF7C01462F8E0192 +:103670000F5F1F4FB8010E94F91AC701B8010E94DD +:10368000B41A28960FB6F894DEBF0FBECDBFCF9107 +:10369000DF911F910F91FF90EF9008950E94271BDB +:1036A00026E636E646EE5FE30E940C2520E030E099 +:1036B00040E052E40E94592308959F92AF92BF9236 +:1036C000CF92DF92EF92FF920F931F93DF93CF93EE +:1036D000CDB7DEB761970FB6F894DEBF0FBECDBF92 +:1036E0008C01FC01848195810E94CE1BF80113821C +:1036F0007E010894E11CF11CE9E0AE2EB12CAC0E69 +:10370000BD1E7FE7C72ED12C992493942DC0C801EC +:10371000B7010E94E81A882339F1F80180818823D3 +:1037200041F4C801B7010E94D819882311F0F801AB +:103730009082C801B701A5010E943B1A898180319E +:1037400021F4F801D282C1820BC08D85282F30E090 +:10375000F801818192818217930714F432832183C7 +:10376000F80183818F5F8383F80184819581B7019C +:103770000E94221D882359F661960FB6F894DEBF89 +:103780000FBECDBFCF91DF911F910F91FF90EF90B2 +:10379000DF90CF90BF90AF909F900895FC0113866B +:1037A0001586148687E090E012863197009711F015 +:1037B0000197FACF0895DC0180E00BC0E82FF0E01C +:1037C0008D9190E0E827F927ED5FFC4FE49161507F +:1037D0008E2F662399F70895DF92EF92FF920F9351 +:1037E0001F93FC01E08001811281F894F80181812E +:1037F0008E2981838281DE2CD0948D21828383E087 +:1038000090E00E94D31FF80181818D2181838AE09D +:1038100090E00E94D31FF8010081789485E390E046 +:103820000E94D31F80E010E0FF240E211F21012BF6 +:1038300009F081E01F910F91FF90EF90DF900895C4 +:10384000EF92FF920F931F93CF93DF937C0101E0E0 +:1038500010E0C0E0D0E0C7010E94EC1B8111102BEA +:10386000000F2196C830D105B1F7812FDF91CF919C +:103870001F910F91FF90EF9008951F93CF93DF93C7 +:10388000FC011081C181D281912F909560FF12C0FF +:10389000F8948A8189238A838981812B89838AE0AC +:1038A00090E00E94D31F8A81812B8A83789487E3DA +:1038B00090E011C0F8948A8189238A838981812BC1 +:1038C000898381E490E00E94D31F8A81812B8A83BF +:1038D000789485E090E00E94D31FDF91CF911F91F3 +:1038E0000895CF92DF92EF92FF920F931F93CF93A1 +:1038F000DF938C01E42EFF24F394C0E0D0E0C62EC9 +:10390000DD2460E08F2D90E08C219D21892B09F032 +:1039100061E0C8010E943D1CFF0C2196C830D10512 +:1039200081F7EE20A9F4F894D8011196ED91FC915D +:10393000129791818C918095982391831196ED91A6 +:10394000FC91129792818C91809598239283789420 +:10395000DF91CF911F910F91FF90EF90DF90CF906B +:1039600008956CEC40E00E94711C0895EF92FF9264 +:103970000F931F93CF93DF938C017B0165E540E0AC +:103980000E94711CC0E0D0E0F701EC0FFD1FC801E0 +:10399000608140E00E94711C2196C830D105A1F7DA +:1039A000DF91CF911F910F91FF90EF900895DF92DB +:1039B000EF92FF920F931F93CF93DF93FC0100814F +:1039C000C181D281F8948981D02ED0948D218983B0 +:1039D00078941DE7E02EFF24115059F182E090E029 +:1039E0000E94D31F888190E08E219F21892BA1F313 +:1039F000F8948A818D218A838981802B89837894A8 +:103A000084EF91E00E94D31FF89489818D218983EE +:103A100080E590E00E94D31F888110E090E0E822CA +:103A2000F922EF2809F411E0789484EA91E00E94E9 +:103A3000D31F812FDF91CF911F910F91FF90EF90B6 +:103A4000DF900895AF92BF92DF92EF92FF920F93B3 +:103A50001F93CF93DF93EC015B018D85882309F0E1 +:103A600061C0CE010E94D71C882329F41B861D86C5 +:103A70001C8690E06BC0CE0160EF40E00E94711C9C +:103A800001E0DD24EE24FF24F394CE010E94EC1B20 +:103A9000182FCE010E94EC1B113019F48130E1F493 +:103AA00039C0181709F58B85081770F460E0FE011E +:103AB000EE0DF11D838190E02F2D30E082239323C2 +:103AC000181619064CF003C060E0081729F00930F9 +:103AD00008F04CC00C874AC0FE01EE0DF11D838139 +:103AE0008F29838361E009C0612FFE01EE0DF11D76 +:103AF0009F2D9095838189238383CE010E943D1C55 +:103B00000F5FFF0C19F4E394FF24F39487E08E1504 +:103B100008F0BBCF013430F0DB86DD2011F581E009 +:103B20008D871FC01B861D861C8690E0DE0120E06D +:103B300030E0F501E20FF31F13968C911397808309 +:103B40002F5F3F4F11962830310599F7892FDF916C +:103B5000CF911F910F91FF90EF90DF90BF90AF90AA +:103B600008958B818823F1F291E0E0CFD02EBDCF74 +:103B7000FF920F931F938C01F62E862F60E00E9418 +:103B800080208F2D90E0FC01EB5CFB4FE491D8018D +:103B9000EC938F5D9B4FFC016491E62FF0E0EE0FFC +:103BA000FF1FE95EFB4F8591949112969C938E9333 +:103BB00011971B961C921B971D961C921D971C9685 +:103BC0001C92F80187E090E012863197009711F07F +:103BD0000197FACF1F910F91FF9008950F931F93B4 +:103BE000CF93DF93BC018230910510F462E070E066 +:103BF000E0910303F091040340E050E0A0E0B0E066 +:103C000024C08081918186179707D0F08617970787 +:103C100071F482819381109729F013969C938E936F +:103C200012972CC0909304038093030327C041157F +:103C3000510519F08417950718F48D01AC01EF01B7 +:103C4000DF01828193819C01F9013097D1F6411502 +:103C50005105F9F0CA01861B970B8430910580F459 +:103C60008A819B810115110521F0F80193838283DC +:103C700004C09093040380930303FE01329645C071 +:103C8000FE01E80FF91F619371930297998388836E +:103C90003CC08091010390910203892B41F48091F3 +:103CA0004801909149019093020380930103409150 +:103CB0004A0150914B014115510541F44DB75EB792 +:103CC0008091460190914701481B590B20910103B7 +:103CD0003091020324173507B0F4CA01821B930BFD +:103CE0008617970780F0AB014E5F5F4F84179507EB +:103CF00050F0420F531F5093020340930103F90108 +:103D00006193719302C0E0E0F0E0CF01DF91CF91C9 +:103D10001F910F910895CF93DF939C01009709F4B1 +:103D20008FC0EC0122971B821A826091030370916D +:103D300004036115710581F488819981820F931FB5 +:103D400020910103309102032817390739F5D093E8 +:103D50000203C093010374C0DB0140E050E0AC17E4 +:103D6000BD0708F1BB83AA83FE0121913191E20FC7 +:103D7000F31FAE17BF0779F48D919C911197280F0F +:103D8000391F2E5F3F4F3983288312968D919C9166 +:103D900013979B838A834115510571F4D0930403D3 +:103DA000C09303034DC012968D919C911397AD0162 +:103DB000009711F0DC01D3CFDA011396DC93CE9398 +:103DC0001297FA0121913191E20FF31FCE17DF070D +:103DD00069F488819981280F391F2E5F3F4FFA01BE +:103DE000318320838A819B8193838283E0E0F0E0AA +:103DF000DB0112968D919C911397009719F0BC01ED +:103E0000FD01F6CFAB014E5F5F4FDB018D919C91C1 +:103E1000840F951F20910103309102032817390761 +:103E200079F4309729F4109204031092030302C02E +:103E30001382128242505040509302034093010378 +:103E4000DF91CF9108951F920F920FB60F92112418 +:103E50002F933F934F935F936F937F938F939F9392 +:103E6000AF93BF93EF93FF938091570290915802C5 +:103E7000892B29F0E0915702F09158020995FF91A2 +:103E8000EF91BF91AF919F918F917F916F915F91D2 +:103E90004F913F912F910F900FBE0F901F9018954B +:103EA0001F920F920FB60F9211242F933F934F93AF +:103EB0005F936F937F938F939F93AF93BF93EF9392 +:103EC000FF938091590290915A02892B29F0E09139 +:103ED0005902F0915A020995FF91EF91BF91AF916C +:103EE0009F918F917F916F915F914F913F912F9112 +:103EF0000F900FBE0F901F9018951F920F920FB644 +:103F00000F9211242F933F938F939F93AF93BF935F +:103F100080915F0290916002A0916102B091620273 +:103F2000309163020196A11DB11D232F2D5F2D3706 +:103F300020F02D570196A11DB11D2093630280939F +:103F40005F0290936002A0936102B093620280913D +:103F50005B0290915C02A0915D02B0915E020196BD +:103F6000A11DB11D80935B0290935C02A0935D0242 +:103F7000B0935E02BF91AF919F918F913F912F912E +:103F80000F900FBE0F901F9018958FB7F894209147 +:103F90005F023091600240916102509162028FBFD6 +:103FA000B901CA010895019739F0880F991F880F48 +:103FB000991F02970197F1F70895789484B582606C +:103FC00084BD84B5816084BD85B5826085BD85B5BD +:103FD000816085BDEEE6F0E0808181608083E1E86C +:103FE000F0E01082808182608083808181608083A4 +:103FF000E0E8F0E0808181608083E1EBF0E08081A7 +:1040000084608083E0EBF0E0808181608083EAE778 +:10401000F0E0808184608083808182608083808101 +:10402000816080838081806880831092C1000895C0 +:10403000EF92FF920F931F93CF93DF937B018C013D +:104040003FB7F89480915B0290915C02A0915D0271 +:10405000B0915E0226B5A89B05C02F3F19F00196CE +:10406000A11DB11D3FBFBA2FA92F982F8827820FFE +:10407000911DA11DB11D52E0880F991FAA1FBB1FE2 +:104080005A95D1F7EC0130C00E9457233FB7F894FE +:1040900080915B0290915C02A0915D02B0915E0202 +:1040A00026B5A89B05C02F3F19F00196A11DB11D93 +:1040B0003FBFBA2FA92F982F8827820F911DA11DCE +:1040C000B11D32E0880F991FAA1FBB1F3A95D1F787 +:1040D0008C1B9D0B885E9340B8F20894E108F108B0 +:1040E00001091109C851DC4FE114F1040105110562 +:1040F00059F6DF91CF911F910F91FF90EF900895A6 +:10410000CF93DF93482F50E0CA018B5C9B4FFC019B +:1041100034914F5D5B4FFA018491882369F190E0FF +:10412000880F991FFC01ED5FFB4FA591B491FC0135 +:10413000E35FFB4FC591D491662351F42FB7F894F8 +:104140008C91932F909589238C93888189230BC020 +:10415000623061F42FB7F8948C91932F9095892356 +:104160008C938881832B88832FBF06C09FB7F894D8 +:104170008C91832B8C939FBFDF91CF910895482F13 +:1041800050E0CA01875B9B4FFC012491CA018B5C04 +:104190009B4FFC0194914F5D5B4FFA0134913323A7 +:1041A00009F440C0222351F1233071F0243028F467 +:1041B0002130A1F0223011F514C02630B1F02730A3 +:1041C000C1F02430D9F404C0809180008F7703C0FF +:1041D000809180008F7D8093800010C084B58F77A0 +:1041E00002C084B58F7D84BD09C08091B0008F77F7 +:1041F00003C08091B0008F7D8093B000E32FF0E08A +:10420000EE0FFF1FE35FFB4FA591B4912FB7F8941A +:10421000662321F48C919095892302C08C91892B7F +:104220008C932FBF0895DC015C968C915C97FD0107 +:10423000E80FF11DE35AFF4F20815C968C915C974B +:1042400090E001968F7390705C968C935C97569675 +:10425000ED91FC91579720835096ED91FC915197E9 +:104260008081806480835B969C915B975C968C9147 +:104270005C97981739F45296ED91FC915397808191 +:104280008F7D80830895DF92EF92FF920F931F93AB +:10429000CF93DF93EC017A018B01D22EE889F98963 +:1042A00082E08083403081EE580780E0680780E03C +:1042B0007807A1F060E079E08DE390E0A801970134 +:1042C0000E946F2521503040404050405695479500 +:1042D0003795279580E12030380798F0E889F989EB +:1042E000108260E874E88EE190E0A80197010E94D6 +:1042F0006F252150304040405040569547953795A6 +:104300002795EC85FD853083EE85FF852083188E0B +:10431000EC89FD89D082EA89FB8980818061808374 +:10432000EA89FB89808188608083EA89FB898081B2 +:1043300080688083EA89FB8980818F7D8083DF911B +:10434000CF911F910F91FF90EF90DF900895FC01A6 +:10435000218D828D30E0205C3F4F281B31092F7367 +:104360003070C9010895FC01918D828D981719F460 +:104370002FEF3FEF06C0828DE80FF11D858D282FAE +:1043800030E0C9010895DC0159969C9159975A96DD +:104390008C915A97981719F42FEF3FEF10C05A9647 +:1043A0008C915A97FD01E80FF11D958D5A968C91CD +:1043B0005A978F5F8F735A968C93292F30E0C901DB +:1043C0000895CF93DF93EC01888D882361F419C0A1 +:1043D0008C9185FF0AC0E889F989808185FF05C035 +:1043E000CE010E941321AA89BB898C9185FD05C04D +:1043F000E889F989808186FD04C00FB607FEE8CF01 +:10440000F4CFDF91CF9108950F931F93CF93DF9354 +:10441000EC01062F9B8D8C8D981791F5E889F98911 +:10442000808185FF2DC0EE89FF896083E889F98945 +:104430008081806480831DC00FB607FC08C0E889B6 +:10444000F989808185FF03C0CE010E9413218C8DE4 +:10445000181791F38B8DFE01E80FF11DE35AFF4F02 +:1044600000831B8FEA89FB8980818062808381E0E1 +:10447000888F81E090E0DF91CF911F910F91089597 +:104480001B8D1F5F1F73E3CF8CEC92E2892B51F0E1 +:1044900080E090E0892B31F00E94CC22882311F03B +:1044A0000E94000008951F920F920FB60F921124E0 +:1044B0002F938F939F93EF93FF93E0917402F0916A +:1044C0007502808182FD16C0E0917A02F0917B0234 +:1044D000208190917D029F5F9F7380917E0298174B +:1044E00071F0E0917D02F0E0EC59FD4F258F909343 +:1044F0007D0205C0E0917A02F0917B02E081FF919C +:10450000EF919F918F912F910F900FBE0F901F9061 +:104510001895109267021092660288EE93E0A0E070 +:10452000B0E08093680290936902A0936A02B0930E +:104530006B0280E591E0909365028093640285ECC4 +:1045400090E0909371028093700284EC90E09093DD +:1045500073028093720280EC90E0909375028093D6 +:10456000740281EC90E0909377028093760282EC63 +:1045700090E0909379028093780286EC90E090939B +:104580007B0280937A0210927D0210927E0210923A +:104590007F0210928002089584E692E00E94A72193 +:1045A00020E0892B09F021E0822F08951F920F92BD +:1045B0000FB60F9211242F933F934F935F936F93F6 +:1045C0007F938F939F93AF93BF93EF93FF9384E673 +:1045D00092E00E941321FF91EF91BF91AF919F91C3 +:1045E0008F917F916F915F914F913F912F910F909C +:1045F0000FBE0F901F901895CF93DF930E94DD1F81 +:104600000E94E409C4E4D2E20E945B092097E1F32E +:104610000E944422F9CF0E94EE1D0895CF92DF92AE +:10462000EF92FF920F931F93CF93DF937C016B0167 +:104630008A01C0E0D0E00FC0D6016D916D01D701B5 +:10464000ED91FC910190F081E02DC7010995C80F13 +:10465000D91F015010400115110571F7CE01DF91EE +:10466000CF911F910F91FF90EF90DF90CF90089521 +:10467000CF93DF93EC016115710519F420E030E070 +:104680000FC0DB010D900020E9F71197A61BB70BB7 +:10469000E881F9810280F381E02DAD0109959C014B +:1046A000C901DF91CF9108950E943823089508959C +:1046B0005058BB27AA270ED075C166D130F06BD1F8 +:1046C00020F031F49F3F11F41EF45BC10EF4E0952D +:1046D000E7FB51C1E92F77D180F3BA17620773075F +:1046E0008407950718F071F49EF58FC10EF4E095DC +:1046F0000B2EBA2FA02D0B01B90190010C01CA019C +:10470000A0011124FF27591B99F0593F50F4503E46 +:1047100068F11A16F040A22F232F342F4427585F38 +:10472000F3CF469537952795A795F0405395C9F750 +:104730007EF41F16BA0B620B730B840BBAF0915008 +:10474000A1F0FF0FBB1F661F771F881FC2F70EC0A7 +:10475000BA0F621F731F841F48F48795779567957A +:10476000B795F7959E3F08F0B3CF9395880F08F063 +:104770009927EE0F979587950895D9D008F481E091 +:1047800008950CD00FC107D140F0FED030F021F4D5 +:104790005F3F19F0F0C0511139C1F3C014D198F343 +:1047A0009923C9F35523B1F3951B550BBB27AA27B2 +:1047B00062177307840738F09F5F5F4F220F331F24 +:1047C000441FAA1FA9F333D00E2E3AF0E0E830D0F0 +:1047D00091505040E695001CCAF729D0FE2F27D0F3 +:1047E000660F771F881FBB1F261737074807AB07C1 +:1047F000B0E809F0BB0B802DBF01FF2793585F4F36 +:104800002AF09E3F510568F0B6C000C15F3FECF34F +:10481000983EDCF3869577956795B795F7959F5FFA +:10482000C9F7880F911D9695879597F90895E1E04E +:10483000660F771F881FBB1F621773078407BA07AD +:1048400020F0621B730B840BBA0BEE1F88F7E09508 +:10485000089504D06894B111D9C00895BCD088F0EF +:104860009F5790F0B92F9927B751A0F0D1F0660F5C +:10487000771F881F991F1AF0BA95C9F712C0B13077 +:1048800081F0C3D0B1E00895C0C0672F782F88278A +:10489000B85F39F0B93FCCF3869577956795B395B6 +:1048A000D9F73EF490958095709561957F4F8F4F25 +:1048B0009F4F0895E89409C097FB3EF4909580952A +:1048C000709561957F4F8F4F9F4F9923A9F0F92FD6 +:1048D00096E9BB279395F695879577956795B79554 +:1048E000F111F8CFFAF4BB0F11F460FF1BC06F5F3A +:1048F0007F4F8F4F9F4F16C0882311F096E911C04C +:10490000772321F09EE8872F762F05C0662371F06C +:1049100096E8862F70E060E02AF09A95660F771F80 +:10492000881FDAF7880F9695879597F90895990F5C +:104930000008550FAA0BE0E8FEEF16161706E80769 +:10494000F907C0F012161306E407F50798F0621B8A +:10495000730B840B950B39F40A2661F0232B242B5F +:10496000252B21F408950A2609F4A140A6958FEF7E +:10497000811D811D089597F99F6780E870E060E0D0 +:1049800008959FEF80EC089500240A9416161706E8 +:1049900018060906089500240A9412161306140630 +:1049A00005060895092E0394000C11F4882352F093 +:1049B000BB0F40F4BF2B11F460FF04C06F5F7F4F4B +:1049C0008F4F9F4F089557FD9058440F551F59F032 +:1049D0005F3F71F04795880F97FB991F61F09F3FEC +:1049E00079F087950895121613061406551FF2CF15 +:1049F0004695F1DF08C0161617061806991FF1CF65 +:104A000086957105610508940895E894BB2766278B +:104A10007727CB0197F908950BD0C4CFB5DF28F0E5 +:104A2000BADF18F0952309F0A6CFABCF1124EECF53 +:104A3000CADFA0F3959FD1F3950F50E0551F629FF9 +:104A4000F001729FBB27F00DB11D639FAA27F00DE7 +:104A5000B11DAA1F649F6627B00DA11D661F829F0E +:104A60002227B00DA11D621F739FB00DA11D621FF3 +:104A7000839FA00D611D221F749F3327A00D611D10 +:104A8000231F849F600D211D822F762F6A2F1124F2 +:104A90009F5750408AF0E1F088234AF0EE0FFF1F45 +:104AA000BB1F661F771F881F91505040A9F79E3F7C +:104AB000510570F060CFAACF5F3FECF3983EDCF376 +:104AC000869577956795B795F795E7959F5FC1F7B9 +:104AD000FE2B880F911D9695879597F90895A1E271 +:104AE0001A2EAA1BBB1BFD010DC0AA1FBB1FEE1F68 +:104AF000FF1FA217B307E407F50720F0A21BB30BB3 +:104B0000E40BF50B661F771F881F991F1A9469F72E +:104B100060957095809590959B01AC01BD01CF018A +:104B20000895EE0FFF1F0590F491E02D0994AA1B44 +:104B3000BB1B51E107C0AA1FBB1FA617B70710F088 +:104B4000A61BB70B881F991F5A95A9F780959095BA +:104B5000BC01CD0108952F923F924F925F926F92C8 +:104B60007F928F929F92AF92BF92CF92DF92EF92FD +:104B7000FF920F931F93CF93DF93CDB7DEB7CA1B7E +:104B8000DB0B0FB6F894DEBF0FBECDBF09942A88A9 +:104B9000398848885F846E847D848C849B84AA8451 +:104BA000B984C884DF80EE80FD800C811B81AA81DE +:104BB000B981CE0FD11D0FB6F894DEBF0FBECDBFA9 +:084BC000ED010895F894FFCF08 +:104BC80054656D70657261747572652053656E7396 +:104BD8006F7200312E30006661696C006F6B0000E7 +:104BE800312E346231202831383834386132290086 +:104BF80073656E736F7200726570656174657200BB +:104C0800307500000100800005030000000000006E +:0C4C180004220E23A721C321B321E121B7 +:00000001FF diff --git a/NodeJsController/NodeJsController.js b/NodeJsController/NodeJsController.js new file mode 100644 index 0000000..25a53c4 --- /dev/null +++ b/NodeJsController/NodeJsController.js @@ -0,0 +1,617 @@ +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 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 + } + }, { + 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); + if (!result) + console.log('No firmware found for type ' + fwtype); + 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 = 1; // I_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 rebootNode(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 == 4) { + 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: + saveProtocol(sender, payload, 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; + } + } +} + +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 < hexFiles.length; i++) + loadFirmware(i, 1, hexFiles[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..4a521e1 --- /dev/null +++ b/NodeJsController/Reboot.js @@ -0,0 +1,45 @@ +var NodeIdToReboot = 1; + +var gwType = 'Ethernet'; +var gwAddress = '10.0.1.99'; +var gwPort = 9999; + +var BROADCAST_ADDRESS = 255; +var NODE_SENSOR_ID = 255; + +function encode(destination, sensor, command, acknowledge, type, payload, binary) { + var msg = destination.toString(10) + ";" + sensor.toString(10) + ";" + command.toString(10) + ";" + acknowledge.toString(10) + ";" + type.toString(10) + ";"; + if (binary) { + 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 rebootNode(destination, gw) { + var sensor = NODE_SENSOR_ID; + var command = 3; // C_INTERNAL + var acknowledge = 0; // no ack + var type = 13; // I_REBOOT + var payload = ""; + var td = encode(destination, sensor, command, acknowledge, type, payload, false); + console.log('-> ' + td.toString()); + gw.write(td); +} + +var gw = require('net').Socket(); +gw.connect(gwPort, gwAddress); +gw.setEncoding('ascii'); +gw.on('connect', function() { + console.log('connected to ethernet gateway at ' + gwAddress + ":" + gwPort); + rebootNode(NodeIdToReboot, gw); + console.log('reboot request submitted for ' + NodeIdToReboot); +}).on('end', function() { + console.log('disconnected from gateway'); +}); 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" + } +} From 5968ddf21964dff4043e70df8bd65286c90b5127 Mon Sep 17 00:00:00 2001 From: ToSa27 Date: Sat, 26 Jul 2014 11:28:57 +0200 Subject: [PATCH 6/6] Send reboot msg after message retrieval to deal with sensors going to sleep minimal adjustment to the dallas temperature sensor as an example added scripts to drop the database and to set a reboot manually for debugging purposes --- .../DallasTemperatureSensor.cpp.hex | 1888 +++++++++-------- .../DallasTemperatureSensor.ino | 69 + NodeJsController/DropDb.js | 17 + NodeJsController/NodeJsController.js | 101 +- NodeJsController/Reboot.js | 63 +- 5 files changed, 1129 insertions(+), 1009 deletions(-) create mode 100644 NodeJsController/DallasTemperatureSensor/DallasTemperatureSensor.ino create mode 100644 NodeJsController/DropDb.js diff --git a/NodeJsController/DallasTemperatureSensor.cpp.hex b/NodeJsController/DallasTemperatureSensor.cpp.hex index dbd4fa5..a714a35 100644 --- a/NodeJsController/DallasTemperatureSensor.cpp.hex +++ b/NodeJsController/DallasTemperatureSensor.cpp.hex @@ -1,8 +1,8 @@ -:100000000C94AE020C94231F0C94501F0C94D60237 -:100010000C94D6020C94D6020C9447140C94D6027D +:100000000C94AE020C94311F0C945E1F0C94D6021B +:100010000C94D6020C94D6020C9455140C94D6026F :100020000C94D6020C94D6020C94D6020C94D602F0 :100030000C94D6020C94D6020C94D6020C94D602E0 -:100040000C947D1F0C94D6020C9453220C94D6224F +:100040000C948B1F0C94D6020C9461220C94E42225 :100050000C94D6020C94D6020C94D6020C94D602C0 :100060000C94D6020C94D602303B303B25643B25E1 :10007000643B0072643D636C6561720A0069643DB3 @@ -83,12 +83,12 @@ :10052000333333330F986E12831141EF8D211489C9 :100530003BE65516CFFEE6DB18D1844B381BF77C23 :100540001D901DA4BBE424203284725E228100C968 -:10055000F124ECA1E53D27003F09892211241FBEAB -:10056000CFEFD8E0DEBFCDBF11E0A0E0B1E0E8EC16 -:10057000FBE402C005900D92AC35B107D9F713E04A -:10058000ACE5B1E001C01D92A530B107E1F715E07F -:10059000CCE5D5E004C02297FE010E949325C83522 -:1005A000D107C9F70E94FC220C94E2250C940000AC +:10055000F124ECA1E53D27003F09972211241FBE9D +:10056000CFEFD8E0DEBFCDBF11E0A0E0B1E0E4EE18 +:10057000FBE402C005900D92A036B107D9F713E055 +:10058000A0E6B1E001C01D92A930B107E1F715E086 +:10059000CCE5D5E004C02297FE010E94A125C83514 +:1005A000D107C9F70E940A230C94F0250C9400008F :1005B000EF92FF920F931F93F22FF02E47FD02C090 :1005C000E4E001C0E4E1242F332727FD309537FF15 :1005D00003C0309521953F4F4F2D512F0F2FEE2EF9 @@ -105,17 +105,17 @@ :1006800001900D920020E1F70895FB01DC0141503B :10069000504048F001900D920020C9F701C01D9212 :1006A00041505040E0F70895A0E0B0E0EAE5F3E003 -:1006B0000C94B5257C01EB018A01690109C0CE01CA +:1006B0000C94C3257C01EB018A01690109C0CE01BC :1006C0002196F6010995F70181937F0101501040B1 -:1006D00001151105A1F7CDB7DEB7E8E00C94D125DF +:1006D00001151105A1F7CDB7DEB7E8E00C94DF25D1 :1006E000FB019F01E8944230C4F04532B4F44A3033 :1006F00029F497FB1EF4909581959F4F642F7727DF -:100700000E949725805D8A330CF0895D8193CB012F +:100700000E94A525805D8A330CF0895D8193CB0121 :100710000097A1F716F45DE251931082C9010C9481 :10072000A508FA01CF93FF93EF93223044F12532CD :1007300034F5C22FE894CA3049F497FB3EF4909503 :100740008095709561957F4F8F4F9F4F2C2F33274A -:1007500044275527FF93EF930E946F25EF91FF9158 +:1007500044275527FF93EF930E947D25EF91FF914A :10076000605D6A330CF0695D6193B901CA01605044 :1007700070408040904051F716F4CDE2C193108252 :100780008F919F91CF910C94A508592F482F372F07 @@ -124,24 +124,24 @@ :1007B000991F08957AE0979F902D879F802D910D26 :1007C00011240895FA01CF93FF93EF932230CCF0D8 :1007D0002532BCF4C22F2C2F332744275527FF93F3 -:1007E000EF930E946F25EF91FF91605D6A330CF0EB +:1007E000EF930E947D25EF91FF91605D6A330CF0DD :1007F000695D6193B901CA016050704080409040CA :1008000051F710828F919F91CF910C94A508FB0115 :100810009F01423074F0453264F4642F77270E94C0 -:100820009725805D8A330CF0895D8193CB01009719 +:10082000A525805D8A330CF0895D8193CB0100970B :10083000A1F71082C9010C94A508AEE0B0E0E3E294 -:10084000F4E00C94B9250D891E898F89988D97FF46 +:10084000F4E00C94C7250D891E898F89988D97FF38 :1008500002C080E090E801979E838D831A8309830C :100860008EE08C839E01255E3F4FCE010196698DFF :100870007A8DA9010E9478044D815E8157FD0AC0DE :100880002F813885421753070CF49A01020F131F6A -:10089000F80110822E96E4E00C94D525AEE0B0E08D -:1008A000E4E5F4E00C94B9258C0177FF02C060E028 +:10089000F80110822E96E4E00C94E325AEE0B0E07F +:1008A000E4E5F4E00C94C7258C0177FF02C060E01A :1008B00070E8615070407E836D831A8309838EE0F7 :1008C0008C83CE010196BA01A9010E9478042D8182 :1008D0003E8137FD09C0EF81F8852E173F070CF4E4 -:1008E000F901E00FF11F10822E96E4E00C94D5255B -:1008F000ABE0B0E0EEE7F4E00C94AB253C012B015B +:1008E000F901E00FF11F10822E96E4E00C94E3254D +:1008F000ABE0B0E0EEE7F4E00C94B9253C012B014D :100900005A01FC0117821682838181FD03C06FEFBB :100910007FEFC6C19AE0892E1E010894211C311C6C :10092000F3012381F20123FD859123FF81912F01A2 @@ -200,8 +200,8 @@ :100C7000DA94F101ED0DF11D808190E0B3010E9445 :100C8000B508DD20A9F706C080E290E0B3010E941C :100C9000B508EA94EE20C1F743CEF301668177816F -:100CA000CB012B96E2E10C94C725A9E0B0E0EBE57F -:100CB000F6E00C94AF256A01122FA02EBE2C2BE378 +:100CA000CB012B96E2E10C94D525A9E0B0E0EBE571 +:100CB000F6E00C94BD256A01122FA02EBE2C2BE36A :100CC000201718F42CE3922E02C0902E9394AE01BC :100CD0004F5F5F4F27E0092D0E94B707BC01898154 :100CE000E82EFF24C70189709070019711F4ADE2DE @@ -244,7 +244,7 @@ :100F300049F4B5E3BB1528F0BB1621F481149104E4 :100F400009F481E3F6018193D601812F90E202C07A :100F50009C93815011968823D9F7E10FF11D1082DF -:100F600020E030E0C9012996EEE00C94CB25283032 +:100F600020E030E0C9012996EEE00C94D925283024 :100F700008F027E03327DA01990F311D87FD9160D2 :100F800000966105710539F432602E5F3D9330E3C0 :100F90002A95E1F708959F3F30F08038710561058B @@ -294,927 +294,929 @@ :101250006795BA95C9F700976105710508959B01D7 :10126000AC010A2E06945795479537952795BA9560 :10127000C9F7620F731F841F951FA01D08950F9358 -:101280001F930CE511E0C80163E00E94B81D8AE6D7 -:1012900091E0B8010E940F198CE791E069E04AE003 -:1012A0000E94E91385E392E060E040E00E94330A87 +:101280001F9300E611E0C80163E00E94C61D8EE6D0 +:1012900091E0B8010E941D1980E891E069E04AE000 +:1012A0000E94F71389E392E060E040E00E94410A67 :1012B0001F910F910895CF92DF92EF92FF920F93BB -:1012C0001F93CF93DF938CE791E00E94790D8AE61C -:1012D00091E00E94041A83EFC82E81E0D82EC0E06E -:1012E000D0E056C08CE791E00E941B0B882331F0C0 -:1012F0008AE691E06C2F0E94271B05C08AE691E0E8 -:101300006C2F0E944E1B20E030E040E251E40E942E -:101310000C250E942924882777FD8095982F0E940C -:101320005C2420E030E040E251E40E94C1237B01D4 +:1012C0001F93CF93DF9380E891E00E94870D8EE615 +:1012D00091E00E94121A87EFC82E81E0D82EC0E05C +:1012E000D0E056C080E891E00E94290B882331F0BD +:1012F0008EE691E06C2F0E94351B05C08EE691E0D2 +:101300006C2F0E945C1B20E030E040E251E40E9420 +:101310001A250E943724882777FD8095982F0E94F0 +:101320006A2420E030E040E251E40E94CF237B01B8 :101330008C01F6016081718182819381A8019701FE -:101340000E94BD238823F9F0C801B70120E030E0F6 -:101350004EEF52EC0E94BD238823A9F085E392E072 -:101360006C2F0E94380AB801A70121E00E94470AA9 -:10137000BC018CE791E040E00E942112F601E0827E +:101340000E94CB238823F9F0C801B70120E030E0E8 +:101350004EEF52EC0E94CB238823A9F089E392E060 +:101360006C2F0E94460AB801A70121E00E94550A8D +:10137000BC0180E891E040E00E942F12F601E0827B :10138000F18202831383219684E090E0C80ED91E77 -:101390008091330290913402C817D90724F4C031E8 -:1013A000D10509F09FCF60914001709141018CE718 -:1013B00091E00E94800CDF91CF911F910F91FF90DF -:1013C000EF90DF90CF900895AF92BF92CF92EF92BF -:1013D000FF920F93CF93DF938AE691E00E945D1B0B -:1013E0008CE791E060E070E04FEF20E00FEFE3E08A -:1013F000EE2EF12C5CE4C52E32E0A32EB12C0E941F -:10140000B3128CE791E060E071E043E151E020E04D -:101410000E94B1118AE691E00E941D198093330267 -:1014200010923402C0E0D0E008C08CE791E06C2F4D -:1014300046E020E00E94FF112196809133029091B6 -:101440003402C817D9071CF4C031D10571F7DF91F8 -:10145000CF910F91FF90EF90CF90BF90AF900895F4 -:10146000FC0114820895FC0114826683458308956B -:10147000FC0166830895FC01808187708860808309 -:1014800081818F70806181836783CF010895CF92BE -:10149000DF92EF92FF920F931F937C01F7E0CF2E24 -:1014A000D12CC80ED91ECB01BA0142E086010E94A0 -:1014B000D802F60101900020E9F73197EC19FD09F7 -:1014C000EE0FEE0FEE0FD7018C918770E82BEC93A7 -:1014D00011968C9111978F7011968C93C7011F9163 -:1014E0000F91FF90EF90DF90CF900895CF93DF930F -:1014F000EC01DB010D900020E9F71197A61B4A2FA4 -:1015000050E09A01B3E0220F331FBA95E1F78881CA -:101510008770822B888389818F708983A93110F02D -:1015200049E150E0CE0107960E944503CE01DF91CC -:10153000CF910895FC01818182958F7090E0009792 -:1015400031F0019711F080E0089587810895CF016F -:1015500007960E94F9020895FC01818182958F709F -:1015600090E0009761F0059729F020E030E040E03E -:1015700050E00EC0278130854185528509C0CF01DA -:1015800007960E941703AC01CB01DA019C01AD0163 -:10159000B901CA010895CF93DF93FC01EB0181816A -:1015A00082958F7031F43796CB01BF010E943E03C4 -:1015B00036C06115710599F18330B9F0843028F493 -:1015C000813041F0823059F508C08430A9F085306F -:1015D00031F51CC0878190E002C087819085BE01F3 -:1015E0004AE050E00E9470031AC0878190854AE06B -:1015F00050E00E94070413C0678170858185928541 -:10160000AE012AE030E00E94910309C06781708535 -:1016100081859285AE012AE030E00E94E203CE018E -:10162000DF91CF9108959C01F999FECF32BD21BD84 -:10163000F89A80B50895FC0181890895EF92FF9290 -:101640000F931F93DF93CF93CDB7DEB7CC52D1402A -:101650000FB6F894DEBF0FBECDBFC95CDE4FE88089 -:10166000F980C753D140CB5CDE4FA881B981C55307 -:10167000D14054968C91882389F1EDB7FEB73A9703 -:101680000FB6F894FEBF0FBEEDBF31968E010F5F0F -:101690001F4FADB7BEB712961C930E9311978BE2F6 -:1016A00091E09383828388E690E09583848383E04E -:1016B00090E09783868389E090E0918780870E94FD -:1016C0001D04EDB7FEB73A960FB6F894FEBF0FBEF5 -:1016D000EDBF84E692E0B8010E945423FE01E75C6E -:1016E000FE4FCB5CDE4FA881B981C553D1405496E3 -:1016F0008C919E012F5F3F4F882359F0C9016CE305 -:1017000070E0A7019F010E944E048AE08CAF1DAEDD -:1017100007C0C9016BE271E0A7019F010E944E045E -:1017200084E692E0BE016F5F7F4F0E94542384E6FF -:1017300092E00E94E121C45DDE4F0FB6F894DEBF57 -:101740000FBECDBFCF91DF911F910F91FF90EF9012 -:101750000895CF93DF93EB010CC086E592E069E03A -:1017600070E040E050E020E030E00E94F913C05407 -:10177000DF418091440190914501892B89F08FE1EF -:10178000C034D80754F7B3C086E592E068E070E053 -:1017900040E050E020E030E00E94F913C05ADF4002 -:1017A0008091440190914501892B81F087E0C03DF3 -:1017B000D80764F086E592E067E070E040E050E032 -:1017C00020E030E00E94F913C05DD74080914401D1 -:1017D00090914501892B81F083E0C83ED80764F0E1 -:1017E00086E592E066E070E040E050E020E030E026 -:1017F0000E94F913C85ED340809144019091450145 -:10180000892B81F081E0C43FD80764F086E592E03F -:1018100065E070E040E050E020E030E00E94F91325 -:10182000C45FD1408091440190914501892B79F0AA -:10183000CA3FD10564F086E592E064E070E040E0E4 -:1018400050E020E030E00E94F913CA5FD040809160 -:10185000440190914501892B79F0CD37D10564F091 -:1018600086E592E063E070E040E050E020E030E0A8 -:101870000E94F913C857D0408091440190914501CE -:10188000892B71F0C034D1055CF086E592E062E00E -:1018900070E040E050E020E030E00E94F913EC9767 -:1018A0008091440190914501892B71F0C032D1059E -:1018B0005CF086E592E061E070E040E050E020E01E -:1018C00030E00E94F9136E97809144019091450198 -:1018D000892B99F060978CF086E592E060E070E0EB -:1018E00040E050E020E030E00E94F91306C08FE0B5 -:1018F000C03AD8070CF454CF47CFDF91CF91089569 -:10190000EF92FF920F931F938C017B0184E692E08C -:101910000E94E121C8010E941E1881E090E090938E -:10192000450180934401C801B7010E94A90B1F9192 -:101930000F91FF90EF9008955F926F927F928F9238 -:101940009F92AF92BF92CF92DF92EF92FF920F934E -:101950001F93CF93DF937C01562EEA01822E88815C -:10196000982E969496949694D7011E969C919B835C -:10197000887F82608883DE2CCF2CC7010E940318E9 -:10198000C7010E94331830E040E050E060E070E0B2 -:1019900080E090E0052DF1E03D3F08F4F0E0E1E06B -:1019A000423E08F4E0E031EEA32EAF0EE060F1E03D -:1019B000593A08F4F0E028EAB22EBE0EE1E0B8EAA7 -:1019C000BB1608F0E0E0FE2BA1E0693A08F4A0E0C5 -:1019D000BF2FB855E1E0B83A08F0E0E0AE2BF1E0F7 -:1019E000772309F4F0E0E1E0882309F4E0E08D2DAD -:1019F0009C2D1CEF95014B2F5A2F6F2F7E2F0E948D -:101A00004416892D90E04A9714F040E202C0492D17 -:101A1000495F8D2D9C2DBE01282D0E94F715682E43 -:101A20008D2D9C2D0E944E18BA80AB809C808E809C -:101A300019817D800881662029F497E1C92E91E003 -:101A4000D92E04C08CE1C82E81E0D82EB701695A86 -:101A50007F4FCE010E94CB0AEDB7FEB77A970FB643 -:101A6000F894FEBF0FBEEDBF3196ADB7BEB712966C -:101A7000FC92EE9211972DED30E033832283B482F5 -:101A80001582A682178250861186928613868486D6 -:101A90001586212F30E02770307037872687708AAF -:101AA000118A12951F70128B138A0695069506955A -:101AB000048B158AD78AC68A918F808F0E941E0B4D -:101AC000EDB7FEB77A960FB6F894FEBF0FBEEDBF26 -:101AD000862DDF91CF911F910F91FF90EF90DF90B6 -:101AE000CF90BF90AF909F908F907F906F905F90BE -:101AF00008954F925F926F927F928F929F92AF92D2 -:101B0000BF92CF92DF92EF92FF920F931F93DF93DA -:101B1000CF930F92CDB7DEB74C01582E492C8E01D2 -:101B20000F5F1F4FB8010E94E417882309F4D5C244 -:101B30008981873008F0D1C2C4010E94F414482F73 -:101B400065E1662E712C680C791CC401B3010E94FA -:101B5000EA15C4016981A80121E00E948614D4011C -:101B600055960C9106950695069510E0F401E00F48 -:101B7000F11F148EF401E788D08CC18CB38CF688E9 -:101B8000A28CB401695A7F4FC3010E94CB0A2DB7C2 -:101B90003EB7265130400FB6F8943EBF0FBE2DBF62 -:101BA000EDB7FEB73196ADB7BEB712969C928E9246 -:101BB000119720EB30E033832283E4821582D682B2 -:101BC0001782C0861186B28613862F2D30E02770CB -:101BD000307035872487A6861786F2945FE0F52259 -:101BE000F08A118A138B028B958B848B0E941E0BBB -:101BF000F401858987702DB73EB72A5E3F4F0FB637 -:101C0000F8943EBF0FBE2DBF8230B1F000D000D09F -:101C1000ADB7BEB712969C928E9211978FE990E065 -:101C200014969C938E9313970E941E0B80E00F9046 -:101C30000F900F900F9052C2F4012689022F077067 -:101C4000128DE788F08C318D9289992379F10330D8 -:101C500069F5173059F50E94C51F73708070907038 -:101C60000E941820D4011E968C911E9757968C9333 -:101C700057975996EC9259978FEF5B968C935B9799 -:101C800088E05A968C935A9756968C915697807FF7 -:101C9000836056968C935697C30150966C910E9420 -:101CA0003B0AAC01C4016E2D21E0F5C1F40186852B -:101CB000381709F0DBC123FF21C0D401D6967596F1 -:101CC00081E201900D928150E1F7D401D7968C9179 -:101CD000D797877FD7968C93D7971E968C911E9710 -:101CE000D8968C93D89757968C915797DA968C9371 -:101CF000B4016A5C7F4FC4010E944211F4018289E1 -:101D0000882319F18785F81601F12E2D30E081E73F -:101D100090E0880E991ED401ED91FC918FE89FEF21 -:101D2000880E991EE20FF31F80818F1571F0F082EB -:101D3000F999FECF1FBA2D5F3F4F32BD21BDF0BCD8 -:101D40000FB6F894FA9AF99A0FBE033009F081C1E0 -:101D5000183009F053C0D40154968C91882309F0AF -:101D60004DC0C3010E949A0A482F282F30E0F40189 -:101D7000808990E00197281739070CF0AEC14F5FBA -:101D8000408B27892787F999FECF1FBA81E090E021 -:101D900092BD81BD20BD0FB6F894FA9AF99A0FBE94 -:101DA000D40150963C91F999FECF1FBA82E090E0A1 -:101DB00092BD81BD30BD0FB6F894FA9AF99A0FBE64 -:101DC000EDB7FEB738970FB6F894FEBF0FBEEDBF64 -:101DD0003196ADB7BEB712969C928E9211978AE853 -:101DE00090E09383828324831582368317820E9436 -:101DF0001E0B80E0EDB7FEB73896A3C0EE2009F0C9 -:101E000028C1163009F4A3C0173038F4113009F492 -:101E10000FC1143009F061C112C01A3009F4B0C00A -:101E20001D3009F05AC128E088E190E00FB6F8941F -:101E3000A895809360000FBE20936000FFCFD4016F -:101E40001E968C918F3F09F048C1C3010E949A0AE7 -:101E5000F40186878F3FA9F400D000D0ADB7BEB79C -:101E600012969C928E92119784E890E014969C931F -:101E70008E9313970E941E0B0F900F900F900F9050 -:101E8000FFCF282F30E040E050E060E070E080E0DD -:101E900090E0E22E01E03D3F08F400E011E0423E18 -:101EA00008F410E00F511060E1E0593A08F4E0E066 -:101EB0001855F1E0183A08F0F0E0EF2BF1E0693A3C -:101EC00008F4F0E0BE2FB855E1E0B83A08F0E0E0E1 -:101ED000FE2BA1E0772309F4A0E0E1E0882309F4D8 -:101EE000E0E0852D942D61E04CEFF42E2B2F3F2F59 -:101EF0004A2F5E2F0E946517F4012685F999FECFBF -:101F00001FBA12BC11BC20BD0FB6F894FA9AF99A08 -:101F10000FBE00D000D000D0EDB7FEB73196ADB700 -:101F2000BEB712969C928E9211978DE790E09383A4 -:101F30008283248315820E941E0B80E0EDB7FEB7DA -:101F400036960FB6F894FEBF0FBEEDBFC7C0C301F3 -:101F50000E949A0A20E08D3409F421E0D4015196C0 -:101F60008C915197821709F4B8C051962C93F99926 -:101F7000FECF1FBA83E091E092BD81BD20BDA8C015 -:101F8000F4018289882309F4A8C0C3010E949A0A37 -:101F9000833409F0A2C000D000D0ADB7BEB712960E -:101FA0009C928E92119783E790E014969C938E9367 -:101FB00013970E941E0B20E030E00F900F900F90BF -:101FC0000F90D401AF58BF4F9FEFED91FC91119747 -:101FD000E20FF31F80818F3F81F09083F999FECF4C -:101FE0001FBA2D5F3F4F32BD21BD2350304090BD01 -:101FF0000FB6F894FA9AF99A0FBE2F5F3F4F22302E -:10200000310519F7F4018685878B118E8FEF838F49 -:102010008AE0828F8689807F8360868BC3016FE12F -:1020200071E00E94760ABC01C4010E94421155C0B1 -:1020300023E730E0820E931ED4010D911C9101150F -:10204000110509F44AC0C3010E94AC0AF8010995C0 -:1020500044C0E5E7F0E08E0E9F1ED401ED91FC91A7 -:10206000309711F0C301099581E038C09923A9F197 -:102070008981813091F584010F581F4FD801ED916E -:10208000FC91E30FF11D6081862F81508E3F30F46B -:10209000C401A30120E00E949C0C1FC0C401F401F4 -:1020A0006785A30120E00E949C0C6E2D70E0D80192 -:1020B000ED91FC91E60FF71F80818F1571F0F08292 -:1020C000F999FECF1FBA6D5F7F4F72BD61BDF0BC45 -:1020D0000FB6F894FA9AF99A0FBE80E00F90CF915C -:1020E000DF911F910F91FF90EF90DF90CF90BF9005 -:1020F000AF909F908F907F906F905F904F900895DA -:10210000EF92FF920F931F93CF93DF93EC010E9406 -:10211000C51F7B018C0103C0CE010E94790D0E9476 -:10212000C51F6E197F09800B910B605D7740804061 -:10213000904090F3DF91CF911F910F91FF90EF901E -:102140000895EF92FF920F931F938C0100591F4F38 -:10215000F8011082005710409FEFF801908B8685A0 -:10216000878B918F938F87E0828F8689807F8360B2 -:10217000868B75E1E72EF12CE00EF11EC7016FE1B1 -:1021800071E00E94760AC8016FEFA70121E00E946A -:102190009C0CC8010E9480101F910F91FF90EF903E -:1021A0000895EF92FF920F931F93CF93DF93EC016B -:1021B00000D000D0EDB7FEB79283818383E191E038 -:1021C000948383830E941E0B0F900F900F900F90AB -:1021D0008E85282F30E040E050E060E070E080E045 -:1021E00090E0E22E01E03D3F08F400E011E0423EC5 -:1021F00008F410E00F511060E1E0593A08F4E0E013 -:102200001855F1E0183A08F0F0E0EF2BF1E0693AE8 -:1022100008F4F0E0BE2FB855E1E0B83A08F0E0E08D -:10222000FE2BA1E0772309F4A0E0E1E0882309F484 -:10223000E0E0CE0161E02CEFF22E2B2F3F2F4A2F52 -:102240005E2F0E9465178E858F8B198E8FEF8B8F77 -:1022500083E08A8F8E89807F83608E8BCE01459646 -:102260006FE171E00E94760ABC01CE010E9442112A -:10227000CE010E948010DF91CF911F910F91FF90AE -:10228000EF9008951F93CF93DF93EC01DB0120E0E3 -:1022900011968C9111978770833009F421E08E8517 -:1022A0008F3F59F4222329F015968C91159783308E -:1022B00021F0CE010E94D1102CC08A89882331F1EF -:1022C00014969C911497CF58DF4FE881F981C1573C -:1022D000D040E90FF11D6081862F81508E3F30F490 -:1022E000992321F0CE01AD0120E00DC0222371F031 -:1022F00015968C911597843049F49F3F39F4CE019F -:102300006FEFAD0121E00E949C0C27C08C898823CF -:1023100011F080E022C0CE016F85AD0120E00E9467 -:102320009C0C182F882329F011E0C059DF4F188228 -:1023300013C08B89882351F0C059DF4F8881C05763 -:10234000D040863018F0CE010E94A110FE01E05965 -:10235000FF4F80818F5F8083812FDF91CF911F910D -:102360000895FF920F931F93CF93DF93EC018A019F -:10237000F22E61157105E1F08E858F8B198E8FEF2E -:102380008B8F8BE08A8F30E02170307053E0220F0A -:10239000331F5A95E1F78E89807F8360822B8E8B65 -:1023A000CE0145960E94760ABC01CE010E944211E0 -:1023B00001151105F1F08E858F8B198E8FEF8B8FA4 -:1023C0008CE08A8F2F2D30E02170307043E0220F97 -:1023D000331F4A95E1F78E89807F8360822B8E8B35 -:1023E000CE014596B8010E94760ABC01CE010E943A -:1023F0004211DF91CF911F910F91FF9008950F939C -:102400001F938C01FC018685878B118E638F428F11 -:1024100030E02170307063E0220F331F6A95E1F7DE -:102420008689807F822B868BC801459660E271E0A9 -:102430000E94760ABC01C8010E9442111F910F91AF -:102440000895DC01FB011E968C911E97828350E05B -:102450004170507083E0440F551F8A95E1F78181E8 -:10246000807F8160842B8183CD010E944211811184 -:1024700081E008950F931F938C0180E091E00E940A -:102480000B230F581F4FF8018083918363E070E0A6 -:1024900040E051E023E13BE00E9454031F910F9183 -:1024A0000895EF92FF920F931F93CF93DF93EC0168 -:1024B000E62EF42E8901C059DF4F1882C057D04054 -:1024C000CE010E948718CE010E946C14882389F4E3 -:1024D00000D000D0EDB7FEB7D283C18380E291E097 -:1024E000948383830E941E0B0F900F900F900F9088 -:1024F000FFCFCE0161E00E94E015CE0162E040E036 -:102500000E94FE16CE010E942A17CE016F2D0E9456 -:102510001116CE016E2D0E94E516CE01B8010E9463 -:10252000B416CE0165E04FE00E94D615CE0162E000 -:1025300070E00E949916CE010E944617CE0162E01B -:10254000EE24EA942CEFF22E01EE18EA28EA30E0AD -:1025500040E050E00E946517DF91CF911F910F91ED -:10256000FF90EF9008958F929F92AF92BF92CF927B -:10257000DF92EF92FF920F931F93CF93DF93EC01C3 -:102580004B01D42E122F84E692E040E052EC61E041 -:1025900070E026E00E9443211C8A1A8A112311F060 -:1025A00081E08A8BCB58DF4F99828882C557D04013 -:1025B0008A89882319F0CE010E943A12CE01B70110 -:1025C0004C2D95010E945112CE010E9660E070E0F4 -:1025D00043E050E023E13BE00E945403CE014196EA -:1025E00063E271E041E050E023E13BE00E945403EC -:1025F00089898F3F11F481E0898B0F3F19F00F8794 -:102600001B8A02C081E08B8B8FEFD812DE868B890C -:10261000882331F08F858F3F19F4CE010E94A110DD -:102620008E858F3F19F4CE010E94D1108A898823AC -:1026300019F420E331E002C027E331E0ADB7BEB7C3 -:1026400018970FB6F894BEBF0FBEADBFEDB7FEB77B -:1026500031961296DC93CE9311978DE291E093839D -:102660008283358324838E85868317820E941E0B86 -:10267000DC2ECD2E8DB79EB708960FB6F8949EBF70 -:102680000FBE8DBF8E85282F30E040E050E060E027 -:1026900070E080E090E0E22E01E03D3F08F400E0D1 -:1026A00011E0423E08F410E00F511060E1E0593AA9 -:1026B00008F4E0E01855F1E0183A08F0F0E0EF2BEC -:1026C000F1E0693A08F4F0E0BE2FB855E1E0B83A1D -:1026D00008F0E0E0FE2BA1E0772309F4A0E0E1E0C0 -:1026E000882309F4E0E08D2D9C2D60E04CEFF42E62 -:1026F0002B2F3F2F4A2F5E2F0E9465178E85282F84 -:1027000030E040E050E060E070E080E090E0E22EF9 -:1027100001E03D3F08F400E011E0423E08F410E023 -:102720000F511060E1E0593A08F4E0E01855F1E08B -:10273000183A08F0F0E0EF2BF1E0693A08F4F0E025 -:10274000BE2FB855E1E0B83A08F0E0E0FE2BA1E07A -:10275000772309F4A0E0E1E0882309F4E0E08D2D7F -:102760009C2D61E03CEFF32E2B2F3F2F4A2F5E2F45 -:102770000E9465178A89882311F441E101C042E172 -:10278000CE016FEF20E00E94FF118E858F8B198E96 -:102790008FEF8B8F86E08A8F8E89807F83608E8B10 -:1027A000CE0145966F850E943B0ABC01CE010E9476 -:1027B0004211CE010E948010DF91CF911F910F91A5 -:1027C000FF90EF90DF90CF90BF90AF909F908F9051 -:1027D00008950F931F938C010E945B14C8014596C6 -:1027E0000E94300AC801C6960E94300A1F910F91BC -:1027F00008954115510529F480917A008F778093CF -:102800007A006A307105B9F063FD02C0E8E001C0EA -:10281000E8E2862F8770E82B88E190E00FB6F89405 -:10282000A895809360000FBEE093600080916000E7 -:10283000806480936000232BA1F483B7817F846040 -:1028400083BFF89483B7816083BF85B7806685BFF7 -:102850008F7D85BF7894889583B78E7F83BF78946A -:102860000EC083B7817F846083BFF89483B7816093 -:1028700083BF7894889583B78E7F83BF7894452BE8 -:1028800029F480917A00806880937A0008951F92DD -:102890000F920FB60F9211248F9388E10FB6F89420 -:1028A00080936000109260000FBE8F910F900FBE5A -:1028B0000F901F901895FC01608341831282138250 -:1028C00080E2848315821682178210861186128612 -:1028D0001386148615860895FC0183810895FF925E -:1028E0000F931F938C01F62E81E00E94D91880E08F -:1028F0000E94E21884E00E94E718F80181816F2DA0 -:102900000E94BF201F910F91FF900895EF92FF92B8 -:102910000F931F93CF93DF93EC01162F042FF52E07 -:10292000E22E60E00E946F141770186A1EBD0DB48D -:1029300007FEFDCF802F9F2D9C01F9012E2D213206 -:1029400008F020E28EB508C080818EBD0DB407FE70 -:10295000FDCF31968EB521502223B1F7CE0161E033 -:102960000E946F14DF91CF911F910F91FF90EF9014 -:102970000895CF93DF93EC0160E00E946F1480E52F -:102980008EBD0DB407FEFDCF8EB583E78EBD0DB4B1 -:1029900007FEFDCF8EB5CE0161E00E946F14DF917E -:1029A000CF9108951F93CF93DF93EC01162F60E032 -:1029B0000E946F141EBD0DB407FEFDCF1EB5CE01E3 -:1029C00061E00E946F14812FDF91CF911F910895D4 -:1029D0006FEF0E94D214089561EE0E94D214089500 -:1029E00062EE0E94D21408951F93CF93DF93EC01FF -:1029F00060E00E946F1480E68EBD0DB407FEFDCF2F -:102A00008EB58FEF8EBD0DB407FEFDCF1EB5CE0186 -:102A100061E00E946F14113220F0CE010E94F01488 -:102A200010E0812FDF91CF911F910895EF92FF92D7 -:102A30000F931F93CF93DF93EC01F62EE72E9C812B -:102A4000142F941708F4192F8D81882311F000E0BA -:102A500002C0092F011BCE0160E00E946F1481E6C5 -:102A60008EBD0DB407FEFDCF8F2D9E2D9C01F9016B -:102A7000FEB49FEF07C09EBD0DB407FEFDCF8EB51F -:102A8000819311501123B9F707C08EBD0DB407FE15 -:102A9000FDCF9EB5015001C08FEF0023B1F7CE01ED -:102AA00061E00E946F148F2DDF91CF911F910F91E4 -:102AB000FF90EF900895DF92EF92FF920F931F9394 -:102AC000CF93DF93EC01E62ED72EF22E9C81142FAC -:102AD000941708F4192F8D81882311F000E002C0AB -:102AE000092F011BCE0160E00E946F14FEBC0DB4E3 -:102AF00007FEFDCF8E2D9D2D9C01F901FEB408C06F -:102B000080818EBD0DB407FEFDCF31968EB511507C -:102B10001123B1F706C01EBC0DB407FEFDCF8EB564 -:102B200001500023C1F7CE0161E00E946F148F2D88 -:102B3000DF91CF911F910F91FF90EF90DF9008955B -:102B4000CF93DF93EC01222311F420EA01C020EBA4 -:102B5000CE010E945B15888161E00E94BF208881C0 -:102B600060E00E94BF20DF91CF9108950F931F93E3 -:102B7000CF93DF93EC01162F042F60E00E946F14B7 -:102B80001F7110621EBD0DB407FEFDCF1EB50EBD38 -:102B90000DB407FEFDCF8EB5CE0161E00E946F142B -:102BA000812FDF91CF911F910F910895262F4F70A4 -:102BB0002295207F242B64E0422F0E94B6150895B1 -:102BC000662319F061E04FE302C061E040E00E943B -:102BD000B61508950F931F938C010E941615C80116 -:102BE00067E040E70E94B6151F910F910895CF93BB -:102BF000DF93EC010E94A015CE010E94E8148073BF -:102C0000D9F3CE0167E040E70E94B61584FD02C00B -:102C100081E004C0CE010E94EC1480E0DF91CF91EE -:102C20000895462F603808F04FE765E00E94B6151A -:102C30000895EF92FF920F931F93CF93DF937C0140 -:102C4000162FEA01022F60E00E946F141F711062BC -:102C50001EBD0DB407FEFDCF1EB508C088818EBD18 -:102C60000DB407FEFDCF21968EB501500023B1F7BC -:102C7000C70161E00E946F14812FDF91CF911F91F6 -:102C80000F91FF90EF900895EF92FF920F931F9393 -:102C9000DF93CF93CDB7DEB728970FB6F894DEBF9A -:102CA0000FBECDBF7C0109831A832B833C834D83E8 -:102CB0005E836F8378878E010F5F1F4F6AE0A801E4 -:102CC00025E00E941916C70160E1A80125E00E94D5 -:102CD0001916C70161E1F70144810E94B6152896D3 -:102CE0000FB6F894DEBF0FBECDBFCF91DF911F911D -:102CF0000F91FF90EF9008951F93CF93DF93EC0116 -:102D0000162F60E00E946F141F711EBD0DB407FEE8 -:102D1000FDCF8EB58FEF8EBD0DB407FEFDCF1EB576 -:102D2000CE0161E00E946F14812FDF91CF911F913E -:102D300008950F931F93CF93DF938C01EB0160E015 -:102D40000E947C16482F437F209729F0219711F489 -:102D5000486001C04C60C80160E00E94B615DF9178 -:102D6000CF911F910F910895FF920F931F93CF93CF -:102D7000DF93EC018B0166E00E947C161A82F7ED6E -:102D8000FF2EF8220230110511F480E206C0013056 -:102D9000110529F481E08A8388E0F82A01C01A82AB -:102DA000CE0166E04F2D0E94B615CE0166E00E946E -:102DB0007C168F1511F481E002C01A8280E0DF9149 -:102DC000CF911F910F91FF9008951F93CF93DF93A1 -:102DD000EC01162F66E00E947C16143010F04CE0D7 -:102DE00003C0412F440F4F5F887F482BCE0166E020 -:102DF0000E94B615DF91CF911F9108950F931F93F5 -:102E0000CF93DF93EC01162F042F6730F0F461E0CD -:102E10000E947C16282F002351F081E090E002C030 -:102E2000880F991F1A95E2F7422F482B0AC081E0BC -:102E300090E002C0880F991F1A95E2F7482F40953D -:102E40004223CE0161E00E94B615DF91CF911F9120 -:102E50000F9108950F931F938C010E94B914C8011C -:102E60006DE10E947C16482F4660C8016DE10E940A -:102E7000B615C8016CE10E947C16482F4360C8015A -:102E80006CE10E94B6151F910F9108950F931F9347 -:102E90008C010E94B914C8016DE10E947C16482F74 -:102EA0004460C8016DE10E94B615C8016CE10E9442 -:102EB0007C16482F4F63C8016CE10E94B61581E073 -:102EC000F80185831F910F910895BF92CF92DF92F1 -:102ED000EF92FF920F931F93DF93CF93CDB7DEB79F -:102EE00028970FB6F894DEBF0FBECDBF6C01B62E8B -:102EF000E982FA820B831C832D833E834F8358879C -:102F0000662389F4F601E6828A8187838B81808734 -:102F10008C8181878D8182878E8183878F81848751 -:102F20008885858707C0F6E0F61708F43DC081E084 -:102F3000681761F4EB2DF0E0EA5BFE4FE491C60107 -:102F40006E2FAE014F5F5F4F25E00BC0E62FF0E024 -:102F5000EA5BFE4FE491C6016E2FAE014F5F5F4FFB -:102F600021E00E9419160B2D10E0F801E45BFE4FE2 -:102F7000E491C6016E2FF60144810E94B615C60188 -:102F800062E00E947C16005C1E4FF801649121E013 -:102F900030E002C0220F331F6A95E2F7482F422B20 -:102FA000C60162E00E94B61528960FB6F894DEBFFF -:102FB0000FBECDBFCF91DF911F910F91FF90EF908A -:102FC000DF90CF90BF9008950F931F93CF93DF931F -:102FD000EC018B0167E10E947C1680FF02C080E05B -:102FE0000DC00115110549F0CE010E94E81490E0D2 -:102FF000959587958770F801808381E0DF91CF9167 -:103000001F910F910895CF93DF93EC0160E00E9430 -:103010007C1681FD10C0CE0160E00E947C16482F16 -:103020004260CE0160E00E94B61565E070E080E08D -:1030300090E00E941820DF91CF9108950F931F9385 -:103040008C01FC01808160E00E94BF20C80160E02B -:103050000E947C16482F4D7FC80160E00E94B61583 -:103060001F910F9108950F931F938C01FC01808194 -:1030700060E00E94BF20C8010E94EC14C8010E94B9 -:10308000F014C80160E00E947C16482F4E7FC801F2 -:1030900060E00E94B6151F910F910895CF93DF93C2 -:1030A000EC010E940318CE0160E00E947C16482FBC -:1030B0004160CE0160E00E94B615CE0167E040E7B6 -:1030C0000E94B6158E819F81892B9885892B9985C1 -:1030D000892B9A85892B9B85892B9C85892B9D859E -:1030E000892B41F0AE014A5F5F4FCE016AE025E0D7 -:1030F0000E941916CE010E94F014CE010E94EC1419 -:10310000888161E00E94BF20DF91CF910895CF9325 -:10311000DF93EC01888161E00E948020898161E079 -:103120000E9480200E94F818888160E00E94BF20E1 -:10313000CE0161E00E946F1465E070E080E090E0F5 -:103140000E941820CE0165E04FE00E94D615CE0106 -:1031500062E070E00E94B416882311F081E08B8356 -:10316000CE0160E070E00E94B416CE0162E070E033 -:103170000E949916CE0167E040E70E94B615CE0185 -:103180006CE40E941116CE010E94F014CE010E9440 -:10319000EC14CE010E940318CE0160E00E947C1660 -:1031A000482F4E7FCE0160E00E94B615DF91CF918F -:1031B0000895882319F48CB5806202C08CB58F7D88 -:1031C0008CBD08959CB5937F982B9CBD08952CB51C -:1031D000382F33702C7F322B3CBD2DB590E0959568 -:1031E00087959595879581702E7F822B8DBD08954B -:1031F0008AE061E00E94BF208AE061E00E948020B6 -:103200008CB580618CBD8CB580648CBD8DE061E037 -:103210000E9480208BE061E00E9480200895FC01E4 -:1032200087ED99E1918B808B758364831382108283 -:103230008FE190E0928381830895FC01838108955A -:103240006F927F928F929F92AF92BF92CF92DF92B6 -:10325000EF92FF920F931F93CF93DF93FB01EA014D -:10326000998180E0288130E0282B392BE081E232FF -:1032700031F0E83221F0E03109F084C04BC04C81DC -:103280004F3329F1403420F44F3109F07BC02FC077 -:103290004F3579F04F3709F075C0B901882777FDB0 -:1032A0008095982F0E945C2420E030E040E85DE3A8 -:1032B0002EC035952795B901882777FD8095982FE1 -:1032C0000E945C2420E030E040E05EE320C03595C1 -:1032D000279535952795B901882777FD8095982FF3 -:1032E0000E945C2420E030E040E85EE310C093E000 -:1032F000359527959A95E1F7B901882777FD80954F -:10330000982F0E945C2420E030E040E05FE30E94C0 -:103310000C2532C0EF8035952795B901882777FDB8 -:103320008095982F0E945C2420E030E040E85EE326 -:103330000E9458233B014C016E2D70E02E81621BD0 -:103340007109882777FD8095982F0E945C245B0186 -:103350006C01FF2400E010E0C801B7010E945A246C -:103360009B01AC01C601B5010E94C1239B01AC01C8 -:10337000C401B3010E9459239B01AC01832F942FF8 -:10338000752F00C0262F382F492F572FB901CA019A -:10339000DF91CF911F910F91FF90EF90DF90CF9031 -:1033A000BF90AF909F908F907F906F9008950895F9 -:1033B000EF92FF920F931F938C017B01FC0184819C -:1033C00095810E94D71CF80184819581B7010E94E4 -:1033D000B61CF8018481958164EB40E00E94711C69 -:1033E000F801848195810E94EC1BF82EF8018481FC -:1033F00095810E94D71C80E0FF2009F481E01F9195 -:103400000F91FF90EF9008950F931F938C01FC0193 -:10341000848195810E94D71CF801848195810E9446 -:10342000B11CF8018481958164E440810E94711C83 -:10343000F801818192818F33910551F08F3591058B -:1034400061F04F9779F46EE570E080E090E00EC097 -:103450006CEB70E080E090E009C067E771E080E02D -:1034600090E004C06EEE72E080E090E00E941820D0 -:103470001F910F910895CF92DF92EF92FF920F93D9 -:103480001F938C016B017A01FC01848195810E945C -:10349000D71CF80184819581B6010E94B61CF80101 -:1034A000848195816EEB40E00E94711CF80184815B -:1034B00095810E94201CF7018083F8018481958109 -:1034C0000E94201CF7018183F801848195810E946C -:1034D000201CF7018283F801848195810E94201CC1 -:1034E000F7018383F801848195810E94201CF701F4 -:1034F0008483F801848195810E94201CF7018583D3 -:10350000F801848195810E94201CF7018683F801CF -:10351000848195810E94201CF7018783F8018481B2 -:1035200095810E94201CF7018087F8018481958194 -:103530000E94D71C1F910F91FF90EF90DF90CF90CA -:1035400008950F931F938A010E943B1AC80168E0F7 -:103550000E94DB1B20E0F8019085891709F421E027 -:10356000822F1F910F910895CF92DF92EF92FF92D9 -:103570000F931F93DF93CF93CDB7DEB729970FB685 -:10358000F894DEBF0FBECDBF8C017B016E010894A5 -:10359000C11CD11CA6010E94A11A882329F460E055 -:1035A00070E08EEF92EC05C0C801B701A6010E9441 -:1035B000201929960FB6F894DEBF0FBECDBFCF916C -:1035C000DF911F910F91FF90EF90DF90CF900895C2 -:1035D0000F931F938B01CB0167E00E94DB1B20E060 -:1035E000F8019781891709F421E0822F1F910F912B -:1035F0000895EF92FF920F931F93CF93DF93EC0107 -:103600007B01042F8C819D810E94CE1B10E007C09E -:10361000CE01B7010E94E81A8823A9F00AC08C8164 -:103620009D81B7010E94221D882329F0101759F4AB -:10363000EFCF81E001C080E0DF91CF911F910F912A -:10364000FF90EF9008951F5F0117A8F3E8CFEF9266 -:10365000FF920F931F93DF93CF93CDB7DEB72897D9 -:103660000FB6F894DEBF0FBECDBF7C01462F8E0192 -:103670000F5F1F4FB8010E94F91AC701B8010E94DD -:10368000B41A28960FB6F894DEBF0FBECDBFCF9107 -:10369000DF911F910F91FF90EF9008950E94271BDB -:1036A00026E636E646EE5FE30E940C2520E030E099 -:1036B00040E052E40E94592308959F92AF92BF9236 -:1036C000CF92DF92EF92FF920F931F93DF93CF93EE -:1036D000CDB7DEB761970FB6F894DEBF0FBECDBF92 -:1036E0008C01FC01848195810E94CE1BF80113821C -:1036F0007E010894E11CF11CE9E0AE2EB12CAC0E69 -:10370000BD1E7FE7C72ED12C992493942DC0C801EC -:10371000B7010E94E81A882339F1F80180818823D3 -:1037200041F4C801B7010E94D819882311F0F801AB -:103730009082C801B701A5010E943B1A898180319E -:1037400021F4F801D282C1820BC08D85282F30E090 -:10375000F801818192818217930714F432832183C7 -:10376000F80183818F5F8383F80184819581B7019C -:103770000E94221D882359F661960FB6F894DEBF89 -:103780000FBECDBFCF91DF911F910F91FF90EF90B2 -:10379000DF90CF90BF90AF909F900895FC0113866B -:1037A0001586148687E090E012863197009711F015 -:1037B0000197FACF0895DC0180E00BC0E82FF0E01C -:1037C0008D9190E0E827F927ED5FFC4FE49161507F -:1037D0008E2F662399F70895DF92EF92FF920F9351 -:1037E0001F93FC01E08001811281F894F80181812E -:1037F0008E2981838281DE2CD0948D21828383E087 -:1038000090E00E94D31FF80181818D2181838AE09D -:1038100090E00E94D31FF8010081789485E390E046 -:103820000E94D31F80E010E0FF240E211F21012BF6 -:1038300009F081E01F910F91FF90EF90DF900895C4 -:10384000EF92FF920F931F93CF93DF937C0101E0E0 -:1038500010E0C0E0D0E0C7010E94EC1B8111102BEA -:10386000000F2196C830D105B1F7812FDF91CF919C -:103870001F910F91FF90EF9008951F93CF93DF93C7 -:10388000FC011081C181D281912F909560FF12C0FF -:10389000F8948A8189238A838981812B89838AE0AC -:1038A00090E00E94D31F8A81812B8A83789487E3DA -:1038B00090E011C0F8948A8189238A838981812BC1 -:1038C000898381E490E00E94D31F8A81812B8A83BF -:1038D000789485E090E00E94D31FDF91CF911F91F3 -:1038E0000895CF92DF92EF92FF920F931F93CF93A1 -:1038F000DF938C01E42EFF24F394C0E0D0E0C62EC9 -:10390000DD2460E08F2D90E08C219D21892B09F032 -:1039100061E0C8010E943D1CFF0C2196C830D10512 -:1039200081F7EE20A9F4F894D8011196ED91FC915D -:10393000129791818C918095982391831196ED91A6 -:10394000FC91129792818C91809598239283789420 -:10395000DF91CF911F910F91FF90EF90DF90CF906B -:1039600008956CEC40E00E94711C0895EF92FF9264 -:103970000F931F93CF93DF938C017B0165E540E0AC -:103980000E94711CC0E0D0E0F701EC0FFD1FC801E0 -:10399000608140E00E94711C2196C830D105A1F7DA -:1039A000DF91CF911F910F91FF90EF900895DF92DB -:1039B000EF92FF920F931F93CF93DF93FC0100814F -:1039C000C181D281F8948981D02ED0948D218983B0 -:1039D00078941DE7E02EFF24115059F182E090E029 -:1039E0000E94D31F888190E08E219F21892BA1F313 -:1039F000F8948A818D218A838981802B89837894A8 -:103A000084EF91E00E94D31FF89489818D218983EE -:103A100080E590E00E94D31F888110E090E0E822CA -:103A2000F922EF2809F411E0789484EA91E00E94E9 -:103A3000D31F812FDF91CF911F910F91FF90EF90B6 -:103A4000DF900895AF92BF92DF92EF92FF920F93B3 -:103A50001F93CF93DF93EC015B018D85882309F0E1 -:103A600061C0CE010E94D71C882329F41B861D86C5 -:103A70001C8690E06BC0CE0160EF40E00E94711C9C -:103A800001E0DD24EE24FF24F394CE010E94EC1B20 -:103A9000182FCE010E94EC1B113019F48130E1F493 -:103AA00039C0181709F58B85081770F460E0FE011E -:103AB000EE0DF11D838190E02F2D30E082239323C2 -:103AC000181619064CF003C060E0081729F00930F9 -:103AD00008F04CC00C874AC0FE01EE0DF11D838139 -:103AE0008F29838361E009C0612FFE01EE0DF11D76 -:103AF0009F2D9095838189238383CE010E943D1C55 -:103B00000F5FFF0C19F4E394FF24F39487E08E1504 -:103B100008F0BBCF013430F0DB86DD2011F581E009 -:103B20008D871FC01B861D861C8690E0DE0120E06D -:103B300030E0F501E20FF31F13968C911397808309 -:103B40002F5F3F4F11962830310599F7892FDF916C -:103B5000CF911F910F91FF90EF90DF90BF90AF90AA -:103B600008958B818823F1F291E0E0CFD02EBDCF74 -:103B7000FF920F931F938C01F62E862F60E00E9418 -:103B800080208F2D90E0FC01EB5CFB4FE491D8018D -:103B9000EC938F5D9B4FFC016491E62FF0E0EE0FFC -:103BA000FF1FE95EFB4F8591949112969C938E9333 -:103BB00011971B961C921B971D961C921D971C9685 -:103BC0001C92F80187E090E012863197009711F07F -:103BD0000197FACF1F910F91FF9008950F931F93B4 -:103BE000CF93DF93BC018230910510F462E070E066 -:103BF000E0910303F091040340E050E0A0E0B0E066 -:103C000024C08081918186179707D0F08617970787 -:103C100071F482819381109729F013969C938E936F -:103C200012972CC0909304038093030327C041157F -:103C3000510519F08417950718F48D01AC01EF01B7 -:103C4000DF01828193819C01F9013097D1F6411502 -:103C50005105F9F0CA01861B970B8430910580F459 -:103C60008A819B810115110521F0F80193838283DC -:103C700004C09093040380930303FE01329645C071 -:103C8000FE01E80FF91F619371930297998388836E -:103C90003CC08091010390910203892B41F48091F3 -:103CA0004801909149019093020380930103409150 -:103CB0004A0150914B014115510541F44DB75EB792 -:103CC0008091460190914701481B590B20910103B7 -:103CD0003091020324173507B0F4CA01821B930BFD -:103CE0008617970780F0AB014E5F5F4F84179507EB -:103CF00050F0420F531F5093020340930103F90108 -:103D00006193719302C0E0E0F0E0CF01DF91CF91C9 -:103D10001F910F910895CF93DF939C01009709F4B1 -:103D20008FC0EC0122971B821A826091030370916D -:103D300004036115710581F488819981820F931FB5 -:103D400020910103309102032817390739F5D093E8 -:103D50000203C093010374C0DB0140E050E0AC17E4 -:103D6000BD0708F1BB83AA83FE0121913191E20FC7 -:103D7000F31FAE17BF0779F48D919C911197280F0F -:103D8000391F2E5F3F4F3983288312968D919C9166 -:103D900013979B838A834115510571F4D0930403D3 -:103DA000C09303034DC012968D919C911397AD0162 -:103DB000009711F0DC01D3CFDA011396DC93CE9398 -:103DC0001297FA0121913191E20FF31FCE17DF070D -:103DD00069F488819981280F391F2E5F3F4FFA01BE -:103DE000318320838A819B8193838283E0E0F0E0AA -:103DF000DB0112968D919C911397009719F0BC01ED -:103E0000FD01F6CFAB014E5F5F4FDB018D919C91C1 -:103E1000840F951F20910103309102032817390761 -:103E200079F4309729F4109204031092030302C02E -:103E30001382128242505040509302034093010378 -:103E4000DF91CF9108951F920F920FB60F92112418 -:103E50002F933F934F935F936F937F938F939F9392 -:103E6000AF93BF93EF93FF938091570290915802C5 -:103E7000892B29F0E0915702F09158020995FF91A2 -:103E8000EF91BF91AF919F918F917F916F915F91D2 -:103E90004F913F912F910F900FBE0F901F9018954B -:103EA0001F920F920FB60F9211242F933F934F93AF -:103EB0005F936F937F938F939F93AF93BF93EF9392 -:103EC000FF938091590290915A02892B29F0E09139 -:103ED0005902F0915A020995FF91EF91BF91AF916C -:103EE0009F918F917F916F915F914F913F912F9112 -:103EF0000F900FBE0F901F9018951F920F920FB644 -:103F00000F9211242F933F938F939F93AF93BF935F -:103F100080915F0290916002A0916102B091620273 -:103F2000309163020196A11DB11D232F2D5F2D3706 -:103F300020F02D570196A11DB11D2093630280939F -:103F40005F0290936002A0936102B093620280913D -:103F50005B0290915C02A0915D02B0915E020196BD -:103F6000A11DB11D80935B0290935C02A0935D0242 -:103F7000B0935E02BF91AF919F918F913F912F912E -:103F80000F900FBE0F901F9018958FB7F894209147 -:103F90005F023091600240916102509162028FBFD6 -:103FA000B901CA010895019739F0880F991F880F48 -:103FB000991F02970197F1F70895789484B582606C -:103FC00084BD84B5816084BD85B5826085BD85B5BD -:103FD000816085BDEEE6F0E0808181608083E1E86C -:103FE000F0E01082808182608083808181608083A4 -:103FF000E0E8F0E0808181608083E1EBF0E08081A7 -:1040000084608083E0EBF0E0808181608083EAE778 -:10401000F0E0808184608083808182608083808101 -:10402000816080838081806880831092C1000895C0 -:10403000EF92FF920F931F93CF93DF937B018C013D -:104040003FB7F89480915B0290915C02A0915D0271 -:10405000B0915E0226B5A89B05C02F3F19F00196CE -:10406000A11DB11D3FBFBA2FA92F982F8827820FFE -:10407000911DA11DB11D52E0880F991FAA1FBB1FE2 -:104080005A95D1F7EC0130C00E9457233FB7F894FE -:1040900080915B0290915C02A0915D02B0915E0202 -:1040A00026B5A89B05C02F3F19F00196A11DB11D93 -:1040B0003FBFBA2FA92F982F8827820F911DA11DCE -:1040C000B11D32E0880F991FAA1FBB1F3A95D1F787 -:1040D0008C1B9D0B885E9340B8F20894E108F108B0 -:1040E00001091109C851DC4FE114F1040105110562 -:1040F00059F6DF91CF911F910F91FF90EF900895A6 -:10410000CF93DF93482F50E0CA018B5C9B4FFC019B -:1041100034914F5D5B4FFA018491882369F190E0FF -:10412000880F991FFC01ED5FFB4FA591B491FC0135 -:10413000E35FFB4FC591D491662351F42FB7F894F8 -:104140008C91932F909589238C93888189230BC020 -:10415000623061F42FB7F8948C91932F9095892356 -:104160008C938881832B88832FBF06C09FB7F894D8 -:104170008C91832B8C939FBFDF91CF910895482F13 -:1041800050E0CA01875B9B4FFC012491CA018B5C04 -:104190009B4FFC0194914F5D5B4FFA0134913323A7 -:1041A00009F440C0222351F1233071F0243028F467 -:1041B0002130A1F0223011F514C02630B1F02730A3 -:1041C000C1F02430D9F404C0809180008F7703C0FF -:1041D000809180008F7D8093800010C084B58F77A0 -:1041E00002C084B58F7D84BD09C08091B0008F77F7 -:1041F00003C08091B0008F7D8093B000E32FF0E08A -:10420000EE0FFF1FE35FFB4FA591B4912FB7F8941A -:10421000662321F48C919095892302C08C91892B7F -:104220008C932FBF0895DC015C968C915C97FD0107 -:10423000E80FF11DE35AFF4F20815C968C915C974B -:1042400090E001968F7390705C968C935C97569675 -:10425000ED91FC91579720835096ED91FC915197E9 -:104260008081806480835B969C915B975C968C9147 -:104270005C97981739F45296ED91FC915397808191 -:104280008F7D80830895DF92EF92FF920F931F93AB -:10429000CF93DF93EC017A018B01D22EE889F98963 -:1042A00082E08083403081EE580780E0680780E03C -:1042B0007807A1F060E079E08DE390E0A801970134 -:1042C0000E946F2521503040404050405695479500 -:1042D0003795279580E12030380798F0E889F989EB -:1042E000108260E874E88EE190E0A80197010E94D6 -:1042F0006F252150304040405040569547953795A6 -:104300002795EC85FD853083EE85FF852083188E0B -:10431000EC89FD89D082EA89FB8980818061808374 -:10432000EA89FB89808188608083EA89FB898081B2 -:1043300080688083EA89FB8980818F7D8083DF911B -:10434000CF911F910F91FF90EF90DF900895FC01A6 -:10435000218D828D30E0205C3F4F281B31092F7367 -:104360003070C9010895FC01918D828D981719F460 -:104370002FEF3FEF06C0828DE80FF11D858D282FAE -:1043800030E0C9010895DC0159969C9159975A96DD -:104390008C915A97981719F42FEF3FEF10C05A9647 -:1043A0008C915A97FD01E80FF11D958D5A968C91CD -:1043B0005A978F5F8F735A968C93292F30E0C901DB -:1043C0000895CF93DF93EC01888D882361F419C0A1 -:1043D0008C9185FF0AC0E889F989808185FF05C035 -:1043E000CE010E941321AA89BB898C9185FD05C04D -:1043F000E889F989808186FD04C00FB607FEE8CF01 -:10440000F4CFDF91CF9108950F931F93CF93DF9354 -:10441000EC01062F9B8D8C8D981791F5E889F98911 -:10442000808185FF2DC0EE89FF896083E889F98945 -:104430008081806480831DC00FB607FC08C0E889B6 -:10444000F989808185FF03C0CE010E9413218C8DE4 -:10445000181791F38B8DFE01E80FF11DE35AFF4F02 -:1044600000831B8FEA89FB8980818062808381E0E1 -:10447000888F81E090E0DF91CF911F910F91089597 -:104480001B8D1F5F1F73E3CF8CEC92E2892B51F0E1 -:1044900080E090E0892B31F00E94CC22882311F03B -:1044A0000E94000008951F920F920FB60F921124E0 -:1044B0002F938F939F93EF93FF93E0917402F0916A -:1044C0007502808182FD16C0E0917A02F0917B0234 -:1044D000208190917D029F5F9F7380917E0298174B -:1044E00071F0E0917D02F0E0EC59FD4F258F909343 -:1044F0007D0205C0E0917A02F0917B02E081FF919C -:10450000EF919F918F912F910F900FBE0F901F9061 -:104510001895109267021092660288EE93E0A0E070 -:10452000B0E08093680290936902A0936A02B0930E -:104530006B0280E591E0909365028093640285ECC4 -:1045400090E0909371028093700284EC90E09093DD -:1045500073028093720280EC90E0909375028093D6 -:10456000740281EC90E0909377028093760282EC63 -:1045700090E0909379028093780286EC90E090939B -:104580007B0280937A0210927D0210927E0210923A -:104590007F0210928002089584E692E00E94A72193 -:1045A00020E0892B09F021E0822F08951F920F92BD -:1045B0000FB60F9211242F933F934F935F936F93F6 -:1045C0007F938F939F93AF93BF93EF93FF9384E673 -:1045D00092E00E941321FF91EF91BF91AF919F91C3 -:1045E0008F917F916F915F914F913F912F910F909C -:1045F0000FBE0F901F901895CF93DF930E94DD1F81 -:104600000E94E409C4E4D2E20E945B092097E1F32E -:104610000E944422F9CF0E94EE1D0895CF92DF92AE -:10462000EF92FF920F931F93CF93DF937C016B0167 -:104630008A01C0E0D0E00FC0D6016D916D01D701B5 -:10464000ED91FC910190F081E02DC7010995C80F13 -:10465000D91F015010400115110571F7CE01DF91EE -:10466000CF911F910F91FF90EF90DF90CF90089521 -:10467000CF93DF93EC016115710519F420E030E070 -:104680000FC0DB010D900020E9F71197A61BB70BB7 -:10469000E881F9810280F381E02DAD0109959C014B -:1046A000C901DF91CF9108950E943823089508959C -:1046B0005058BB27AA270ED075C166D130F06BD1F8 -:1046C00020F031F49F3F11F41EF45BC10EF4E0952D -:1046D000E7FB51C1E92F77D180F3BA17620773075F -:1046E0008407950718F071F49EF58FC10EF4E095DC -:1046F0000B2EBA2FA02D0B01B90190010C01CA019C -:10470000A0011124FF27591B99F0593F50F4503E46 -:1047100068F11A16F040A22F232F342F4427585F38 -:10472000F3CF469537952795A795F0405395C9F750 -:104730007EF41F16BA0B620B730B840BBAF0915008 -:10474000A1F0FF0FBB1F661F771F881FC2F70EC0A7 -:10475000BA0F621F731F841F48F48795779567957A -:10476000B795F7959E3F08F0B3CF9395880F08F063 -:104770009927EE0F979587950895D9D008F481E091 -:1047800008950CD00FC107D140F0FED030F021F4D5 -:104790005F3F19F0F0C0511139C1F3C014D198F343 -:1047A0009923C9F35523B1F3951B550BBB27AA27B2 -:1047B00062177307840738F09F5F5F4F220F331F24 -:1047C000441FAA1FA9F333D00E2E3AF0E0E830D0F0 -:1047D00091505040E695001CCAF729D0FE2F27D0F3 -:1047E000660F771F881FBB1F261737074807AB07C1 -:1047F000B0E809F0BB0B802DBF01FF2793585F4F36 -:104800002AF09E3F510568F0B6C000C15F3FECF34F -:10481000983EDCF3869577956795B795F7959F5FFA -:10482000C9F7880F911D9695879597F90895E1E04E -:10483000660F771F881FBB1F621773078407BA07AD -:1048400020F0621B730B840BBA0BEE1F88F7E09508 -:10485000089504D06894B111D9C00895BCD088F0EF -:104860009F5790F0B92F9927B751A0F0D1F0660F5C -:10487000771F881F991F1AF0BA95C9F712C0B13077 -:1048800081F0C3D0B1E00895C0C0672F782F88278A -:10489000B85F39F0B93FCCF3869577956795B395B6 -:1048A000D9F73EF490958095709561957F4F8F4F25 -:1048B0009F4F0895E89409C097FB3EF4909580952A -:1048C000709561957F4F8F4F9F4F9923A9F0F92FD6 -:1048D00096E9BB279395F695879577956795B79554 -:1048E000F111F8CFFAF4BB0F11F460FF1BC06F5F3A -:1048F0007F4F8F4F9F4F16C0882311F096E911C04C -:10490000772321F09EE8872F762F05C0662371F06C -:1049100096E8862F70E060E02AF09A95660F771F80 -:10492000881FDAF7880F9695879597F90895990F5C -:104930000008550FAA0BE0E8FEEF16161706E80769 -:10494000F907C0F012161306E407F50798F0621B8A -:10495000730B840B950B39F40A2661F0232B242B5F -:10496000252B21F408950A2609F4A140A6958FEF7E -:10497000811D811D089597F99F6780E870E060E0D0 -:1049800008959FEF80EC089500240A9416161706E8 -:1049900018060906089500240A9412161306140630 -:1049A00005060895092E0394000C11F4882352F093 -:1049B000BB0F40F4BF2B11F460FF04C06F5F7F4F4B -:1049C0008F4F9F4F089557FD9058440F551F59F032 -:1049D0005F3F71F04795880F97FB991F61F09F3FEC -:1049E00079F087950895121613061406551FF2CF15 -:1049F0004695F1DF08C0161617061806991FF1CF65 -:104A000086957105610508940895E894BB2766278B -:104A10007727CB0197F908950BD0C4CFB5DF28F0E5 -:104A2000BADF18F0952309F0A6CFABCF1124EECF53 -:104A3000CADFA0F3959FD1F3950F50E0551F629FF9 -:104A4000F001729FBB27F00DB11D639FAA27F00DE7 -:104A5000B11DAA1F649F6627B00DA11D661F829F0E -:104A60002227B00DA11D621F739FB00DA11D621FF3 -:104A7000839FA00D611D221F749F3327A00D611D10 -:104A8000231F849F600D211D822F762F6A2F1124F2 -:104A90009F5750408AF0E1F088234AF0EE0FFF1F45 -:104AA000BB1F661F771F881F91505040A9F79E3F7C -:104AB000510570F060CFAACF5F3FECF3983EDCF376 -:104AC000869577956795B795F795E7959F5FC1F7B9 -:104AD000FE2B880F911D9695879597F90895A1E271 -:104AE0001A2EAA1BBB1BFD010DC0AA1FBB1FEE1F68 -:104AF000FF1FA217B307E407F50720F0A21BB30BB3 -:104B0000E40BF50B661F771F881F991F1A9469F72E -:104B100060957095809590959B01AC01BD01CF018A -:104B20000895EE0FFF1F0590F491E02D0994AA1B44 -:104B3000BB1B51E107C0AA1FBB1FA617B70710F088 -:104B4000A61BB70B881F991F5A95A9F780959095BA -:104B5000BC01CD0108952F923F924F925F926F92C8 -:104B60007F928F929F92AF92BF92CF92DF92EF92FD -:104B7000FF920F931F93CF93DF93CDB7DEB7CA1B7E -:104B8000DB0B0FB6F894DEBF0FBECDBF09942A88A9 -:104B9000398848885F846E847D848C849B84AA8451 -:104BA000B984C884DF80EE80FD800C811B81AA81DE -:104BB000B981CE0FD11D0FB6F894DEBF0FBECDBFA9 -:084BC000ED010895F894FFCF08 -:104BC80054656D70657261747572652053656E7396 -:104BD8006F7200312E30006661696C006F6B0000E7 -:104BE800312E346231202831383834386132290086 -:104BF80073656E736F7200726570656174657200BB -:104C0800307500000100800005030000000000006E -:0C4C180004220E23A721C321B321E121B7 +: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 index 25a53c4..2a127fa 100644 --- a/NodeJsController/NodeJsController.js +++ b/NodeJsController/NodeJsController.js @@ -264,6 +264,21 @@ function saveProtocol(sender, payload, db) { }); } +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) { @@ -389,7 +404,8 @@ function sendFirmwareConfigResponse(destination, fwtype, fwversion, db, gw) { }, { $set: { 'type': fwtype, - 'version': fwversion + 'version': fwversion, + 'reboot': 0 } }, { upsert: true @@ -416,20 +432,22 @@ function sendFirmwareConfigResponse(destination, fwtype, fwversion, db, gw) { }, function(err, result) { if (err) console.log('Error finding firmware for type ' + fwtype); - if (!result) + else if (!result) console.log('No firmware found for type ' + fwtype); - 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 = 1; // I_FIRMWARE_CONFIG_RESPONSE - var td = encode(destination, sensor, command, acknowledge, type, payload); - console.log('-> ' + td.toString()); - gw.write(td); + 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); + } }); }); } @@ -459,15 +477,43 @@ function sendFirmwareResponse(destination, fwtype, fwversion, fwblock, db, gw) { }); } -function rebootNode(destination, gw) { +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); + 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) { @@ -481,7 +527,7 @@ function rfReceived(data, db, gw) { var type = +datas[3]; var rawpayload = datas[4].trim(); var payload; - if (command == 4) { + if (command == C_STREAM) { payload = []; for (var i = 0; i < rawpayload.length; i+=2) payload.push(parseInt(rawpayload.substring(i, i + 2), 16)); @@ -491,7 +537,9 @@ function rfReceived(data, db, gw) { // decision on appropriate response switch (command) { case C_PRESENTATION: - saveProtocol(sender, payload, db); + if (sensor == NODE_SENSOR_ID) + saveProtocol(sender, payload, db); + saveSensor(sender, sensor, type, db); break; case C_SET: saveValue(sender, sensor, type, payload, db); @@ -560,6 +608,7 @@ function rfReceived(data, db, gw) { } break; } + checkRebootRequest(sender, db, gw); } } @@ -574,8 +623,8 @@ dbc.connect('mongodb://' + dbAddress + ':' + dbPort + '/' + dbName, function(err 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 < hexFiles.length; i++) - loadFirmware(i, 1, hexFiles[i], db); + for (var i = 0; i < fwHexFiles.length; i++) + loadFirmware(i, 1, fwHexFiles[i], db); var gw; if (gwType == 'Ethernet') { diff --git a/NodeJsController/Reboot.js b/NodeJsController/Reboot.js index 4a521e1..2afb2b9 100644 --- a/NodeJsController/Reboot.js +++ b/NodeJsController/Reboot.js @@ -1,45 +1,28 @@ var NodeIdToReboot = 1; -var gwType = 'Ethernet'; -var gwAddress = '10.0.1.99'; -var gwPort = 9999; +const dbAddress = '127.0.0.1'; +const dbPort = 27017; +const dbName = 'MySensorsDb'; -var BROADCAST_ADDRESS = 255; -var NODE_SENSOR_ID = 255; - -function encode(destination, sensor, command, acknowledge, type, payload, binary) { - var msg = destination.toString(10) + ";" + sensor.toString(10) + ";" + command.toString(10) + ";" + acknowledge.toString(10) + ";" + type.toString(10) + ";"; - if (binary) { - for (var i = 0; i < payload.length; i++) { - if (payload[i] < 16) - msg += "0"; - msg += payload[i].toString(16); - } - } else { - msg += payload; +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"); + }); + }); } - msg += '\n'; - return msg.toString(); -} - -function rebootNode(destination, gw) { - var sensor = NODE_SENSOR_ID; - var command = 3; // C_INTERNAL - var acknowledge = 0; // no ack - var type = 13; // I_REBOOT - var payload = ""; - var td = encode(destination, sensor, command, acknowledge, type, payload, false); - console.log('-> ' + td.toString()); - gw.write(td); -} - -var gw = require('net').Socket(); -gw.connect(gwPort, gwAddress); -gw.setEncoding('ascii'); -gw.on('connect', function() { - console.log('connected to ethernet gateway at ' + gwAddress + ":" + gwPort); - rebootNode(NodeIdToReboot, gw); - console.log('reboot request submitted for ' + NodeIdToReboot); -}).on('end', function() { - console.log('disconnected from gateway'); }); +