diff --git a/libraries/MySensors/MySensor.h b/libraries/MySensors/MySensor.h index eb0dc2d..04f2611 100644 --- a/libraries/MySensors/MySensor.h +++ b/libraries/MySensors/MySensor.h @@ -43,6 +43,8 @@ // Remove PSTR macros from debug prints #undef PSTR #define PSTR(x) (x) + //#undef F + //#define F(x) (x) #include "core/MyHwESP8266.cpp" // For ESP8266, we always enable gateway feature #define MY_GATEWAY_ESP8266 @@ -86,11 +88,20 @@ // GATEWAY - TRANSPORT #if defined(MY_GATEWAY_MQTT_CLIENT) // GATEWAY - COMMON FUNCTIONS - #include "core/MyGatewayTransport.cpp" - #if !defined(MY_GATEWAY_ESP8266) - // We only support MQTT on W5100 (and ESP8266) at the moment - + // We only support MQTT Client using W5100 and ESP8266 at the moment + #if !defined(MY_CONTROLLER_IP_ADDRESS) + #error You must specify MY_CONTROLLER_IP_ADDRESS (MQTT broker address) #endif + #if !defined(MY_MQTT_TOPIC_PREFIX) + #error You must specify a topic prefix MY_MQTT_TOPIC_PREFIX for this MQTT client + #endif + #if !defined(MY_MQTT_CLIENT_ID) + #error You must define a unique MY_MQTT_CLIENT_ID for this MQTT client + #endif + + #include "drivers/pubsubclient/src/PubSubClient.cpp" + #include "core/MyGatewayTransport.cpp" + #include "core/MyGatewayTransportMQTTClient.cpp" #elif defined(MY_GATEWAY_FEATURE) // GATEWAY - COMMON FUNCTIONS #include "core/MyGatewayTransport.cpp" diff --git a/libraries/MySensors/core/MyGatewayTransport.cpp b/libraries/MySensors/core/MyGatewayTransport.cpp index abd0879..3134d7c 100644 --- a/libraries/MySensors/core/MyGatewayTransport.cpp +++ b/libraries/MySensors/core/MyGatewayTransport.cpp @@ -23,7 +23,6 @@ extern boolean transportSendRoute(MyMessage &message); inline void gatewayTransportProcess() { if (gatewayTransportAvailable()) { - MyMessage &_msg = gatewayTransportReceive(); if (_msg.destination == GATEWAY_ADDRESS) { // Check if sender requests an ack back. diff --git a/libraries/MySensors/core/MyGatewayTransportMQTT.cpp b/libraries/MySensors/core/MyGatewayTransportMQTT.cpp deleted file mode 100644 index b292f7b..0000000 --- a/libraries/MySensors/core/MyGatewayTransportMQTT.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - * The MySensors Arduino library handles the wireless radio link and protocol - * between your home built sensors/actuators and HA controller of choice. - * The sensors forms a self healing radio network with optional repeaters. Each - * repeater and gateway builds a routing tables in EEPROM which keeps track of the - * network topology allowing messages to be routed to nodes. - * - * Created by Henrik Ekblad - * Copyright (C) 2013-2015 Sensnology AB - * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors - * - * Documentation: http://www.mysensors.org - * Support Forum: http://forum.mysensors.org - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ - - -#include "MyConfig.h" -#include "MyProtocol.h" -#include "MyGatewayTransport.h" -#include "MyMessage.h" -#include "MyProtocol.h" - - -char _serialInputString[MY_GATEWAY_MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface -int _serialInputPos; -MyMessage _serialMsg; - - -bool gatewayTransportSend(MyMessage &message) { - Serial.print(protocolFormat(message)); - // Serial print is always successful - return true; -} - -bool gatewayTransportInit() { - gatewayTransportSend(buildGw(_msg, I_GATEWAY_READY).set("Gateway startup complete.")); - return true; -} - - -bool gatewayTransportAvailable() { - bool available = false; - - while (Serial.available()) { - // get the new byte: - char inChar = (char) Serial.read(); - // if the incoming character is a newline, set a flag - // so the main loop can do something about it: - if (_serialInputPos < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1 && !available) { - if (inChar == '\n') { - _serialInputString[_serialInputPos] = 0; - available = true; - } else { - // add it to the inputString: - _serialInputString[_serialInputPos] = inChar; - _serialInputPos++; - } - } else { - // Incoming message too long. Throw away - _serialInputPos = 0; - } - } - if (available) { - // Parse message and return parse result - available = protocolParse(_serialMsg, _serialInputString); - _serialInputPos = 0; - } - return available; -} - -MyMessage & gatewayTransportReceive() { - // Return the last parsed message - return _serialMsg; -} diff --git a/libraries/MySensors/core/MyGatewayTransportMQTTClient.cpp b/libraries/MySensors/core/MyGatewayTransportMQTTClient.cpp new file mode 100644 index 0000000..b948b96 --- /dev/null +++ b/libraries/MySensors/core/MyGatewayTransportMQTTClient.cpp @@ -0,0 +1,184 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + + +#include "MyConfig.h" +#include "MyProtocol.h" +#include "MyGatewayTransport.h" +#include "MyMessage.h" + +// Topic structure: MY_MQTT_TOPIC_PREFIX/NODE-ID/SENSOR-ID/CMD-TYPE/ACK-FLAG/SUB-TYPE + + + +IPAddress _brokerIp(MY_CONTROLLER_IP_ADDRESS); + +#if defined(MY_GATEWAY_ESP8266) + #define EthernetClient WiFiClient + IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS); + IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS); +#else + byte _clientMAC[] = { MY_MAC_ADDRESS }; +#endif + +#if defined(MY_IP_ADDRESS) + IPAddress _clientIp(MY_IP_ADDRESS); +#endif + +EthernetClient _ethClient; +PubSubClient _client(_ethClient); +bool _available = false; +char _convBuffer[MAX_PAYLOAD*2+1]; +char _fmtBuffer[MY_GATEWAY_MAX_SEND_LENGTH]; +MyMessage _mqttMsg; + + + +bool gatewayTransportSend(MyMessage &message) { + if (!_client.connected()) + return false; + snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR(MY_MQTT_TOPIC_PREFIX "/%d/%d/%d/%d/%d"), message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type); + debug(PSTR("Sending message on topic: %s\n"), _fmtBuffer); + return _client.publish(_fmtBuffer, message.getString(_convBuffer)); +} + + + +void incomingMQTT(char* topic, byte* payload, + unsigned int length) +{ + debug(PSTR("Message arrived on topic: %s\n"), topic); + char *str, *p; + uint8_t i = 0; + for (str = strtok_r(topic, "/", &p); str && i < 5; + str = strtok_r(NULL, "/", &p)) { + switch (i) { + case 0: { + // Topic prefix + if (strcmp_P(str, MY_MQTT_TOPIC_PREFIX) != 0) { + // Message not for us or malformed! + return; + } + break; + } + case 1: { + // Node id + _mqttMsg.destination = atoi(str); + break; + } + case 2: { + // Sensor id + _mqttMsg.sensor = atoi(str); + break; + } + case 3: { + // Command type + mSetCommand(_mqttMsg, atoi(str)); + break; + } + case 4: { + // Ack flag + mSetRequestAck(_mqttMsg, atoi(str)?1:0); + break; + } + case 5: { + // Sub type + _mqttMsg.type = atoi(str); + // Add payload + char* ca; + ca = (char *) payload; + ca += length; + *ca = '\0'; + _mqttMsg.set((const char*) payload); + _available = true; + } + } + i++; + } +} + + +bool reconnectMQTT() { + debug(PSTR("Attempting MQTT connection...\n")); + // Attempt to connect + if (_client.connect(MY_MQTT_CLIENT_ID + #if defined(MY_MQTT_USER) && defined(MY_MQTT_PASSWORD) + , MY_MQTT_USER, MY_MQTT_PASSWORD + #endif + )) { + debug(PSTR("MQTT connected\n")); + // Once connected, publish an announcement... + //_client.publish("outTopic","hello world"); + // ... and resubscribe + _client.subscribe(MY_MQTT_TOPIC_PREFIX "/+/+/+/+/+"); + return true; + } + return false; +} + +bool gatewayTransportInit() { + _client.setServer(_brokerIp, MY_PORT); + _client.setCallback(incomingMQTT); + + #if defined(MY_GATEWAY_ESP8266) + (void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD); + #ifdef MY_IP_ADDRESS + WiFi.config(_clientIp, _gatewayIp, _subnetIp); + #endif + while (WiFi.status() != WL_CONNECTED) + { + delay(500); + Serial.print("."); + yield(); + } + Serial.print(F("IP: ")); + Serial.println(WiFi.localIP()); + #else + #ifdef MY_IP_ADDRESS + Ethernet.begin(_clientMAC, _clientIp); + Serial.print(F("IP: ")); + Serial.println(Ethernet.localIP()); + #else + // Get IP address from DHCP + Ethernet.begin(_clientMAC); + Serial.print(F("IP: ")); + Serial.println(Ethernet.localIP()); + #endif /* IP_ADDRESS_DHCP */ + // give the Ethernet interface a second to initialize + // TODO: use HW delay + wait(1000); + #endif + return true; +} + + +bool gatewayTransportAvailable() { + if (!_client.connected()) { + reconnectMQTT(); + return false; + } + _client.loop(); + return _available; +} + +MyMessage & gatewayTransportReceive() { + // Return the last parsed message + _available = false; + return _mqttMsg; +} diff --git a/libraries/MySensors/core/MySensorCore.cpp b/libraries/MySensors/core/MySensorCore.cpp index 55f88fb..a67383b 100644 --- a/libraries/MySensors/core/MySensorCore.cpp +++ b/libraries/MySensors/core/MySensorCore.cpp @@ -293,9 +293,7 @@ void wait(unsigned long ms) { unsigned long enter = hwMillis(); while (hwMillis() - enter < ms) { _process(); - #if defined(ARDUINO_ARCH_ESP8266) - yield(); - #endif + yield(); } } diff --git a/libraries/MySensors/core/MyTransport.cpp b/libraries/MySensors/core/MyTransport.cpp index eb4b23a..499a6f5 100644 --- a/libraries/MySensors/core/MyTransport.cpp +++ b/libraries/MySensors/core/MyTransport.cpp @@ -78,19 +78,25 @@ inline void transportProcess() { (void)len; //until somebody makes use of 'len' ledBlinkRx(1); + uint8_t command = mGetCommand(_msg); + uint8_t type = _msg.type; + uint8_t sender = _msg.sender; + uint8_t last = _msg.last; + uint8_t destination = _msg.destination; + #ifdef MY_SIGNING_FEATURE // Before processing message, reject unsigned messages if signing is required and check signature (if it is signed and addressed to us) // Note that we do not care at all about any signature found if we do not require signing, nor do we care about ACKs (they are never signed) #ifdef MY_SIGNING_REQUEST_SIGNATURES - if ((!MY_IS_GATEWAY || DO_SIGN(msg.sender)) && - msg.destination == nc.nodeId && - mGetLength(msg) && - !mGetAck(msg) && - (mGetCommand(msg) != C_INTERNAL || - (msg.type != I_GET_NONCE_RESPONSE && msg.type != I_GET_NONCE && msg.type != I_REQUEST_SIGNING && - msg.type != I_ID_REQUEST && msg.type != I_ID_RESPONSE && - msg.type != I_FIND_PARENT && msg.type != I_FIND_PARENT_RESPONSE))) { + if ((!MY_IS_GATEWAY || DO_SIGN(sender)) && + destination == nc.nodeId && + mGetLength(_msg) && + !mGetAck(_msg) && + (mGetCommand(_msg) != C_INTERNAL || + (type != I_GET_NONCE_RESPONSE && type != I_GET_NONCE && type != I_REQUEST_SIGNING && + type != I_ID_REQUEST && type != I_ID_RESPONSE && + type != I_FIND_PARENT && type != I_FIND_PARENT_RESPONSE))) { if (!mGetSigned(_msg)) { // Got unsigned message that should have been signed debug(PSTR("no sign\n")); @@ -106,10 +112,11 @@ inline void transportProcess() { #endif #endif + // Add string termination, good if we later would want to print it. _msg.data[mGetLength(_msg)] = '\0'; debug(PSTR("read: %d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d,sg=%d:%s\n"), - _msg.sender, _msg.last, _msg.destination, _msg.sensor, mGetCommand(_msg), _msg.type, mGetPayloadType(_msg), mGetLength(_msg), mGetSigned(_msg), _msg.getString(_convBuf)); + sender, last, destination, _msg.sensor, mGetCommand(_msg), type, mGetPayloadType(_msg), mGetLength(_msg), mGetSigned(_msg), _msg.getString(_convBuf)); mSetSigned(_msg,0); // Clear the sign-flag now as verification (and debug printing) is completed if(!(mGetVersion(_msg) == PROTOCOL_VERSION)) { @@ -118,13 +125,6 @@ inline void transportProcess() { return; } - uint8_t command = mGetCommand(_msg); - uint8_t type = _msg.type; - uint8_t sender = _msg.sender; - #if defined(MY_REPEATER_FEATURE) - uint8_t last = _msg.last; - #endif - uint8_t destination = _msg.destination; if (destination == _nc.nodeId) { // This message is addressed to this node @@ -142,7 +142,7 @@ inline void transportProcess() { mSetRequestAck(_msgTmp,false); // Reply without ack flag (otherwise we would end up in an eternal loop) mSetAck(_msgTmp,true); _msgTmp.sender = _nc.nodeId; - _msgTmp.destination = _msg.sender; + _msgTmp.destination = sender; _sendRoute(_msgTmp); } @@ -159,7 +159,7 @@ inline void transportProcess() { if (isValidDistance(distance) && (distance < _nc.distance)) { // Found a neighbor closer to GW than previously found _nc.distance = distance; - _nc.parentNodeId = _msg.sender; + _nc.parentNodeId = sender; hwWriteConfig(EEPROM_PARENT_NODE_ID_ADDRESS, _nc.parentNodeId); hwWriteConfig(EEPROM_DISTANCE_ADDRESS, _nc.distance); debug(PSTR("parent=%d, d=%d\n"), _nc.parentNodeId, _nc.distance); @@ -170,16 +170,16 @@ inline void transportProcess() { #ifdef MY_SIGNING_FEATURE } else if (type == I_GET_NONCE) { if (signerGetNonce(_msg)) { - _sendRoute(build(_msg, _nc.nodeId, _msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_GET_NONCE_RESPONSE, false)); + _sendRoute(build(_msg, _nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_GET_NONCE_RESPONSE, false)); } return; // Nonce exchange is an internal MySensor protocol message, no need to inform caller about this } else if (type == I_REQUEST_SIGNING) { if (_msg.getBool()) { // We received an indicator that the sender require us to sign all messages we send to it - SET_SIGN(_msg.sender); + SET_SIGN(sender); } else { // We received an indicator that the sender does not require us to sign all messages we send to it - CLEAR_SIGN(_msg.sender); + CLEAR_SIGN(sender); } // Save updated table hwWriteConfigBlock((void*)_doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS, sizeof(_doSign)); @@ -189,12 +189,12 @@ inline void transportProcess() { // to sign it's messages #if defined (MY_GATEWAY_FEATURE) #ifdef MY_SIGNING_REQUEST_SIGNATURES - if (DO_SIGN(_msg.sender)) - _sendRoute(build(_msg, _nc.nodeId, _msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false).set(true)); + if (DO_SIGN(sender)) + _sendRoute(build(_msg, _nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false).set(true)); else - _sendRoute(build(_msg, _nc.nodeId, _msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false).set(false)); + _sendRoute(build(_msg, _nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false).set(false)); #else - _sendRoute(build(_msg, _nc.nodeId, _msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false).set(false)); + _sendRoute(build(_msg, _nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false).set(false)); #endif #endif return; // Signing request is an internal MySensor protocol message, no need to inform caller about this @@ -359,8 +359,6 @@ boolean transportSendWrite(uint8_t to, MyMessage &message) { boolean transportSendRoute(MyMessage &message) { - uint8_t sender = message.sender; - uint8_t dest = message.destination; #if defined(MY_REPEATER_FEATURE) uint8_t last = message.last; #endif @@ -383,12 +381,13 @@ boolean transportSendRoute(MyMessage &message) { mSetVersion(message, PROTOCOL_VERSION); #ifdef MY_SIGNING_FEATURE + uint8_t type = message.type; // If destination is known to require signed messages and we are the sender, sign this message unless it is an ACK or a handshake message if (DO_SIGN(message.destination) && message.sender == _nc.nodeId && !mGetAck(message) && mGetLength(message) && (mGetCommand(message) != C_INTERNAL || - (message.type != I_GET_NONCE && message.type != I_GET_NONCE_RESPONSE && message.type != I_REQUEST_SIGNING && - message.type != I_ID_REQUEST && message.type != I_ID_RESPONSE && - message.type != I_FIND_PARENT && message.type != I_FIND_PARENT_RESPONSE))) { + (type != I_GET_NONCE && type != I_GET_NONCE_RESPONSE && type != I_REQUEST_SIGNING && + type != I_ID_REQUEST && type != I_ID_RESPONSE && + type != I_FIND_PARENT && type != I_FIND_PARENT_RESPONSE))) { bool signing = SIGN_WAITING_FOR_NONCE; // Send nonce-request if (!_sendRoute(build(_msgTmp, _nc.nodeId, message.destination, message.sensor, C_INTERNAL, I_GET_NONCE, false).set(""))) { @@ -427,6 +426,8 @@ boolean transportSendRoute(MyMessage &message) { // None repeating node... We can only send to our parent ok = transportSendWrite(_nc.parentNodeId, message); #else + uint8_t sender = message.sender; + uint8_t dest = message.destination; if (dest == GATEWAY_ADDRESS) { // Store this address in routing table (if repeater) hwWriteConfig(EEPROM_ROUTES_ADDRESS+sender, last); diff --git a/libraries/MySensors/drivers/RF24/RF24.cpp b/libraries/MySensors/drivers/RF24/RF24.cpp index 0250ff2..d8a6775 100644 --- a/libraries/MySensors/drivers/RF24/RF24.cpp +++ b/libraries/MySensors/drivers/RF24/RF24.cpp @@ -14,6 +14,7 @@ static const char space_str_P[] PROGMEM = " "; /****************************************************************************/ +#ifdef MY_DEBUG_VERBOSE static void print_hex( uint8_t v, const bool prefix0x = false ) { if (prefix0x) @@ -22,6 +23,7 @@ static void print_hex( uint8_t v, const bool prefix0x = false ) Serial.print(v >> 4, HEX); Serial.print(v & 0x0F, HEX); } +#endif void RF24::csn(bool mode) { @@ -143,7 +145,7 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; -#ifdef MY_DEBUG +#ifdef MY_DEBUG_VERBOSE Serial.print(F("write_register(")); print_hex(reg, true); Serial.print(F(",")); print_hex(value, true); Serial.println(F(")")); #endif @@ -299,7 +301,7 @@ uint8_t RF24::get_status(void) /****************************************************************************/ void RF24::print_feature(void) { -#ifdef MY_DEBUG +#ifdef MY_DEBUG_VERBOSE Serial.print(F("FEATURE=")); print_hex(read_register(FEATURE), true); Serial.println(space_str_P); @@ -658,7 +660,7 @@ void RF24::powerUp(void) #if defined (FAILURE_HANDLING) void RF24::errNotify(){ #ifdef MY_DEBUG - Serial.println(F("HARDWARE FAIL")); + Serial.println(F("RF24 HARDWARE FAIL")); #endif failureDetected = 1; } diff --git a/libraries/MySensors/drivers/pubsubclient/src/PubSubClient.cpp b/libraries/MySensors/drivers/pubsubclient/src/PubSubClient.cpp index 1a50236..29f70fc 100644 --- a/libraries/MySensors/drivers/pubsubclient/src/PubSubClient.cpp +++ b/libraries/MySensors/drivers/pubsubclient/src/PubSubClient.cpp @@ -451,7 +451,7 @@ boolean PubSubClient::subscribe(const char* topic) { } boolean PubSubClient::subscribe(const char* topic, uint8_t qos) { - if (qos < 0 || qos > 1) { + if (qos > 1) { return false; } if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) { diff --git a/libraries/MySensors/examples/GatewayEsp8266/GatewayEsp8266.ino b/libraries/MySensors/examples/GatewayESP8266/GatewayESP8266.ino similarity index 96% rename from libraries/MySensors/examples/GatewayEsp8266/GatewayEsp8266.ino rename to libraries/MySensors/examples/GatewayESP8266/GatewayESP8266.ino index 231d30c..098ef07 100644 --- a/libraries/MySensors/examples/GatewayEsp8266/GatewayEsp8266.ino +++ b/libraries/MySensors/examples/GatewayESP8266/GatewayESP8266.ino @@ -70,7 +70,7 @@ // Enable debug prints to serial monitor #define MY_DEBUG -// Use a bit lower baudrate here than default +// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h #define MY_BAUD_RATE 9600 // Enables and select radio type (if attached) @@ -87,10 +87,10 @@ //#define MY_USE_UDP // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) -//#define MY_IP_ADDRESS 192,168,98,87 +//#define MY_IP_ADDRESS 192,168,178,87 // If using static ip you need to define Gateway and Subnet address as well -#define MY_IP_GATEWAY_ADDRESS 192,168,98,1 +#define MY_IP_GATEWAY_ADDRESS 192,168,178,1 #define MY_IP_SUBNET_ADDRESS 255,255,255,0 // The port to keep open on node server mode diff --git a/libraries/MySensors/examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino b/libraries/MySensors/examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino new file mode 100644 index 0000000..4c99eb3 --- /dev/null +++ b/libraries/MySensors/examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino @@ -0,0 +1,139 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + * + * REVISION HISTORY + * Version 1.0 - Henrik Ekblad + * + * DESCRIPTION + * The ESP8266 MQTT gateway sends radio network (or locally attached sensors) data to your MQTT broker. + * The node also listens to MY_MQTT_TOPIC_PREFIX and sends out those messages to the radio network + * + * LED purposes: + * - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h + * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved + * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly + * - ERR (red) - fast blink on error during transmission error or recieve crc error + * + * See http://www.mysensors.org/build/esp8266_gateway for wiring instructions. + * nRF24L01+ ESP8266 + * VCC VCC + * CE GPIO4 + * CSN/CS GPIO15 + * SCK GPIO14 + * MISO GPIO12 + * MOSI GPIO13 + * + * Not all ESP8266 modules have all pins available on their external interface. + * This code has been tested on an ESP-12 module. + * The ESP8266 requires a certain pin configuration to download code, and another one to run code: + * - Connect REST (reset) via 10K pullup resistor to VCC, and via switch to GND ('reset switch') + * - Connect GPIO15 via 10K pulldown resistor to GND + * - Connect CH_PD via 10K resistor to VCC + * - Connect GPIO2 via 10K resistor to VCC + * - Connect GPIO0 via 10K resistor to VCC, and via switch to GND ('bootload switch') + * + * Inclusion mode button: + * - Connect GPIO5 via switch to GND ('inclusion switch') + * + * Hardware SHA204 signing is currently not supported! + * + * Make sure to fill in your ssid and WiFi password below for ssid & pass. + */ + +#include +#include + +// Enable debug prints to serial monitor +#define MY_DEBUG + +// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h +#define MY_BAUD_RATE 9600 + +// Enables and select radio type (if attached) +#define MY_RADIO_NRF24 +//#define MY_RADIO_RFM69 + +#define MY_GATEWAY_MQTT_CLIENT + +// Set this nodes topic prefix +#define MY_MQTT_TOPIC_PREFIX "mygateway" + +// Set MQTT client id +#define MY_MQTT_CLIENT_ID "mysensors-1" + +// Enable these if your MQTT broker requires usenrame/password +//#define MY_MQTT_USER "username" +//#define MY_MQTT_PASSWORD "password" + +// Set WIFI SSID and password +#define MY_ESP8266_SSID "MySSID" +#define MY_ESP8266_PASSWORD "MyVerySecretPassword" + +// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) +#define MY_IP_ADDRESS 192,168,178,87 + +// If using static ip you need to define Gateway and Subnet address as well +#define MY_IP_GATEWAY_ADDRESS 192,168,178,1 +#define MY_IP_SUBNET_ADDRESS 255,255,255,0 + + +// MQTT broker ip address. +#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68 + +// The MQTT broker port to to open +#define MY_PORT 1883 + + /* +// Flash leds on rx/tx/err +#define MY_LEDS_BLINKING_FEATURE +// Set blinking period +#define MY_DEFAULT_LED_BLINK_PERIOD 300 + +// Enable inclusion mode +#define MY_INCLUSION_MODE_FEATURE +// Enable Inclusion mode button on gateway +#define MY_INCLUSION_BUTTON_FEATURE +// Set inclusion mode duration (in seconds) +#define MY_INCLUSION_MODE_DURATION 60 +// Digital pin used for inclusion mode button +#define MY_INCLUSION_MODE_BUTTON_PIN 3 + +#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin +#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin +#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED +*/ + +#include +#include + +void setup() { +} + +void presentation() { + // Present locally attached sensors here +} + + +void loop() { + // Send locally attech sensors data here +} + + + diff --git a/libraries/MySensors/examples/GatewayMQTTClient/GatewayMQTTClient.ino b/libraries/MySensors/examples/GatewayMQTTClient/GatewayMQTTClient.ino deleted file mode 100644 index 9c5b60b..0000000 --- a/libraries/MySensors/examples/GatewayMQTTClient/GatewayMQTTClient.ino +++ /dev/null @@ -1,614 +0,0 @@ -/* MyMQTT Client Gateway 0.1b - Created by Norbert Truchsess - Based on MyMQTT-broker gateway created by Daniel Wiegert - Based on MySensors Ethernet Gateway by Henrik Ekblad - http://www.mysensors.org - - Changes by Thomas Krebs - - Add signing support from MySensors 1.5 and update for MySensors 1.5; - - Restructured code back to a C like implementation following the existing MQTTGateway - Requires MySensors lib 1.5 - - * Change below; TCP_IP, TCP_PORT, TCP_MAC - This will listen on your selected TCP_IP:TCP_PORT below, Please change TCP_MAC your liking also. - *1 -> NOTE: Keep first byte at x2, x6, xA or xE (replace x with any hex value) for using Local Ranges. - *2 You can use standard pin set-up as MySensors recommends or if you own a IBOARD you may change - the radio-pins below if you hardware mod your iBoard. see [URL BELOW] for more details. - http://forum.mysensors.org/topic/224/iboard-cheap-single-board-ethernet-arduino-with-radio/5 - * Don't forget to look at the definitions in libraries\MySensors\MyMQTT.h! - define TCPDUMP and connect serial interface if you have problems, please write on - http://forum.mysensors.org/ and explain your problem, include serial output. Don't forget to - turn on DEBUG in libraries\MySensors\MyConfig.h also. - MQTT_FIRST_SENSORID is for 'DHCP' server in MyMQTT. You may limit the ID's with FIRST and LAST definition. - If you want your manually configured below 20 set MQTT_FIRST_SENSORID to 20. - To disable: set MQTT_FIRST_SENSORID to 255. - MQTT_BROKER_PREFIX is the leading prefix for your nodes. This can be only one char if like. - MQTT_SEND_SUBSCRIPTION is if you want the MyMQTT to send a empty payload message to your nodes. - This can be useful if you want to send latest state back to the MQTT client. Just check if incoming - message has any length or not. - Example: if (msg.type==V_LIGHT && strlen(msg.getString())>0) otherwise the code might do strange things. - * Address-layout is : [MQTT_BROKER_PREFIX]/[NodeID]/[SensorID]/V_[SensorType][/set | /get] - NodeID and SensorID is uint8 (0-255) number. - Segment after SensorID is translation of the sensor type, look inside MyMQTT.cpp for the definitions. - User can change this to their needs. We have also left some space for custom types. - Special: (sensor 255 reserved for special commands) - - The last seqment is a command to to be send down to the sensor. The gateway is subscribed to topics which have - a command present! This is to avoid that a publish by the gateway will end up in the gateway via it subsription. - You can receive a node sketch name with MyMQTT/20/255/V_Sketch_name (or version with _version) - - So far tested in openhab and MyMQTT for Android (Not my creation) - - http://www.openhab.org/ - * How to set-up Openhab and MQTTGateway: - http://forum.mysensors.org/topic/303/mqtt-broker-gateway - - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "MyMQTTClient.h" - -#ifdef MY_SIGNING_FEATURE -#include -#include -#include -#endif - -//#define DSRTC -#ifdef DSRTC -#include -#include // a basic DS1307 library that returns time as a time_t -#endif - -/* - * To configure MQTTClientGateway.ino to use an ENC28J60 based board include - * 'UIPEthernet.h' (SPI.h required for MySensors anyway). The UIPEthernet-library can be downloaded - * from: https://github.com/ntruchsess/arduino_uip - */ - -//#include -/* - * To execute MQTTClientGateway.ino on Yun uncomment Bridge.h and YunClient.h. - * Do not include Ethernet.h or SPI.h in this case. - * On Yun there's no need to configure local_ip and mac in the sketch - * as this is configured on the linux-side of Yun. - */ - -//#include -//#include -// * Use this for IBOARD modded to use standard MISO/MOSI/SCK, see note *1 above! -/* - #define RADIO_CE_PIN 3 // radio chip enable - #define RADIO_SPI_SS_PIN 8 // radio SPI serial select - #define RADIO_ERROR_LED_PIN A2 // Error led pin - #define RADIO_RX_LED_PIN A1 // Receive led pin - #define RADIO_TX_LED_PIN A0 // the PCB, on board LED*/ - -// * Use this for default configured pro mini / nano etc : -// - -//#define RADIO_CE_PIN 5 // radio chip enable -//#define RADIO_SPI_SS_PIN 6 // radio SPI serial select -//#define RADIO_ERROR_LED_PIN 7 // Error led pin -//#define RADIO_RX_LED_PIN 8 // Receive led pin -//#define RADIO_TX_LED_PIN 9 // the PCB, on board LED*/ - -// CE_PIN and SPI_SS_PIN for Mega -#define RADIO_CE_PIN 48 // radio chip enable -#define RADIO_SPI_SS_PIN 49 // radio SPI serial select -#define RADIO_ERROR_LED_PIN A2 // Error led pin -#define RADIO_RX_LED_PIN A1 // Receive led pin -#define RADIO_TX_LED_PIN A0 // the PCB, on board LED*/ - -//replace with ip of server you want to connect to, comment out if using 'remote_host' -uint8_t remote_ip[] = { 192, 168, 178, 74 }; // Mosquitto broker - -//replace with hostname of server you want to connect to, comment out if using 'remote_ip' -//char* remote_ip = "server.local"; -//replace with the port that your server is listening on -#define remote_port 1883 -//replace with arduinos ip-address. Comment out if Ethernet-startup should use dhcp. Is ignored on Yun -uint8_t local_ip[] = {192, 168, 178, 11}; -//replace with ethernet shield mac. It's mandatory every device is assigned a unique mac. Is ignored on Yun -uint8_t mac[] = { 0xA2, 0xAE, 0xAD, 0xA0, 0xA0, 0xA2 }; - -#if defined remote_ip && defined remote_host -#error "cannot define both remote_ip and remote_host at the same time!" -#endif - -#ifdef _YUN_CLIENT_H_ -YunClient ethClient; -#else -EthernetClient ethClient; -#endif - -//////////////////////////////////////////////////////////////// -// NRFRF24L01 radio driver (set low transmit power by default) -MyTransportNRF24 transport(RADIO_CE_PIN, RADIO_SPI_SS_PIN, RF24_PA_LEVEL_GW); -//MyTransportRFM69 transport; - -// Message signing driver (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h) -//MySigningNone signer; -//MySigningAtsha204Soft signer(true); -//MySigningAtsha204 signer; - -// Hardware profile -MyHwATMega328 hw; - -MyMessage msg; -char convBuf[MAX_PAYLOAD * 2 + 1]; -uint8_t buffsize; -char buffer[MQTT_MAX_PACKET_SIZE]; -char user[sizeof(MQTT_USER)]; // introduced the bufs to get rid of compiler warnings -char pwd[sizeof(MQTT_PWD)]; // see above -char connID[sizeof(MQTT_CONN_ID)]; // see above -char mqttTopicMask[sizeof(MQTT_TOPIC_MASK)]; // see above - -//////////////////////////////////////////////////////////////// - -volatile uint8_t countRx; -volatile uint8_t countTx; -volatile uint8_t countErr; - - -//////////////////////////////////////////////////////////////// - -void processMQTTMessages(char* topic, byte* payload, unsigned int length); -PubSubClient client(remote_ip, remote_port, processMQTTMessages, ethClient); - -//////////////////////////////////////////////////////////////// - - -// Declare and initialize MySensor instance -// Construct MyMQTTClient (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h, if signing -// feature not to be used, uncomment) -// To use LEDs blinking, uncomment WITH_LEDS_BLINKING in MyConfig.h -MySensor gw(transport, hw -#ifdef MY_SIGNING_FEATURE - , signer -#endif -#ifdef WITH_LEDS_BLINKING - , RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN -#endif - ); - -/* - * setup - */ -void setup() -{ - strcpy(connID,MQTT_CONN_ID); - strcpy(mqttTopicMask,MQTT_TOPIC_MASK); - - countRx = 0; - countTx = 0; - countErr = 0; - - Ethernet.begin(mac, local_ip); - //Bridge.begin(); - delay(1000); // Wait for Ethernet to get configured. - - begin(); -} - -/* - * loop - */ -void loop() -{ - if (!client.connected()) - { - boolean ret; -#ifdef MQTT_AUTH_REQUIRED - strcpy(user, MQTT_USER); - strcpy(pwd, MQTT_PWD); - ret = client.connect(connID, user,pwd); -#else - ret = client.connect(connID); -#endif - if (ret) { - Serial.println("Connected to MQTT broker"); - } else { - Serial.println("Connection to MQTT broker failed"); - } - client.subscribe(mqttTopicMask); - } - client.loop(); - gw.process(); -} - -/* - * processRadioMessage - * - * Receives radio message, parses it and forwards it to the MQTT broker - */ -void processRadioMessage(const MyMessage &message) -{ - rxBlink(1); - sendMQTT(message); -} - -/* - * sendMQTT - * Handles processing of radio messages and eventually publishes it to the MQTT broker - */ -void sendMQTT(const MyMessage &inMsg) -{ - MyMessage msg = inMsg; - buffsize = 0; - if (!client.connected()) - return; //We have no connections - return - if (msg.isAck()) - { -#ifdef DEBUG - Serial.println("msg is ack!"); -#endif - if (msg.sender == 255 && mGetCommand(msg) == C_INTERNAL - && msg.type == I_ID_REQUEST) - { - // TODO: sending ACK request on id_response fucks node up. doesn't work. - // The idea was to confirm id and save to EEPROM_LATEST_NODE_ADDRESS. - } - } - else - { - // we have to check every message if its a newly assigned id or not. - // Ack on I_ID_RESPONSE does not work, and checking on C_PRESENTATION isn't reliable. - uint8_t newNodeID = gw.loadState(EEPROM_LATEST_NODE_ADDRESS) + 1; - if (newNodeID <= MQTT_FIRST_SENSORID) - newNodeID = MQTT_FIRST_SENSORID; - if (msg.sender == newNodeID) - { - gw.saveState(EEPROM_LATEST_NODE_ADDRESS, newNodeID); - } - if (mGetCommand(msg) == C_INTERNAL) - { - if (msg.type == I_CONFIG) - { - txBlink(1); - if (!gw.sendRoute( - build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, - I_CONFIG, 0).set("M"))) - errBlink(1); - } - else if (msg.type == I_TIME) - { -#ifdef DEBUG - Serial.println("I_TIME requested!"); -#endif - txBlink(1); - if (!gw.sendRoute( - build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, - I_TIME, 0).set(now()))) - errBlink(1); - } - else if (msg.type == I_ID_REQUEST && msg.sender == 255) - { - uint8_t newNodeID = gw.loadState(EEPROM_LATEST_NODE_ADDRESS) + 1; - if (newNodeID <= MQTT_FIRST_SENSORID) - newNodeID = MQTT_FIRST_SENSORID; - if (newNodeID >= MQTT_LAST_SENSORID) - return; // Sorry no more id's left :( - txBlink(1); - if (!gw.sendRoute( - build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, - I_ID_RESPONSE, 0).set(newNodeID))) - errBlink(1); - } - else if (msg.type == I_BATTERY_LEVEL) - { - strcpy_P(buffer, mqtt_prefix); - buffsize += strlen_P(mqtt_prefix); - buffsize += sprintf(&buffer[buffsize], "/%i/255/BATTERY_LEVEL", msg.sender ); - msg.getString(convBuf); -#ifdef DEBUG - Serial.print("publish: "); - Serial.print((char*) buffer); - Serial.print(" "); - Serial.println((char*) convBuf); -#endif - client.publish(buffer, convBuf); - } - else if (msg.type == I_SKETCH_NAME) - { - strcpy_P(buffer, mqtt_prefix); - buffsize += strlen_P(mqtt_prefix); - buffsize += sprintf(&buffer[buffsize], "/%i/255/SKETCH_NAME", msg.sender ); - msg.getString(convBuf); -#ifdef DEBUG - Serial.print("publish: "); - Serial.print((char*) buffer); - Serial.print(" "); - Serial.println((char*) convBuf); -#endif - client.publish(buffer, convBuf); - } - else if (msg.type == I_SKETCH_VERSION) - { - strcpy_P(buffer, mqtt_prefix); - buffsize += strlen_P(mqtt_prefix); - buffsize += sprintf(&buffer[buffsize], "/%i/255/SKETCH_VERSION", msg.sender ); - msg.getString(convBuf); -#ifdef DEBUG - Serial.print("publish: "); - Serial.print((char*) buffer); - Serial.print(" "); - Serial.println((char*) convBuf); -#endif - client.publish(buffer, convBuf); - } - - } - else if (mGetCommand(msg) != 0) - { - if (mGetCommand(msg) == 3) - msg.type = msg.type + (S_FIRSTCUSTOM - 10); //Special message - - if (msg.type > VAR_TOTAL) - msg.type = VAR_TOTAL; // If type > defined types set to unknown. - strcpy_P(buffer, mqtt_prefix); - buffsize += strlen_P(mqtt_prefix); - buffsize += sprintf(&buffer[buffsize], "/%i/%i/V_%s", msg.sender, - msg.sensor, getType(convBuf, &VAR_Type[msg.type])); - msg.getString(convBuf); -#ifdef DEBUG - Serial.print("publish: "); - Serial.print((char*) buffer); - Serial.print(" "); - Serial.println((char*) convBuf); -#endif - client.publish(buffer, convBuf); - } - } -} - -/* - * build - * Constructs a radio message - */ -inline MyMessage& build(MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, - uint8_t command, uint8_t type, bool enableAck) -{ - msg.destination = destination; - msg.sender = sender; - msg.sensor = sensor; - msg.type = type; - mSetCommand(msg, command); - mSetRequestAck(msg, enableAck); - mSetAck(msg, false); - return msg; -} - -/* - * getType - */ -char *getType(char *b, const char **index) -{ - char *q = b; - char *p = (char *) pgm_read_word(index); - while (*q++ = pgm_read_byte(p++)) - ; - *q = 0; - return b; -} - -/* - * begin - * wraps MySensors begin method; setup of RTC and led timers interrupt - */ -void begin() -{ -#ifdef DEBUG - Serial.begin(BAUD_RATE); -#endif -#ifdef DSRTC - // Attach RTC - setSyncProvider(RTC.get); // the function to get the time from the RTC - setSyncInterval(60); -#endif - - gw.begin(processRadioMessage, 0, true, 0); - - MsTimer2::set(200, ledTimersInterrupt); - MsTimer2::start(); - -#ifdef DEBUG - Serial.print(getType(convBuf, &VAR_Type[S_FIRSTCUSTOM])); -#endif -} - -/* - * processMQTTMessages - * message handler for the PubSubClient - */ -void processMQTTMessages(char* topic, byte* payload, unsigned int length) -{ - processMQTTMessage(topic, payload, length); -} - -/* - * processMQTTMessage - * processes MQTT messages, parses the topic, extracts radio address out of topic and sends them - * to the respective radio - */ -void processMQTTMessage(char* topic, byte* payload, - unsigned int length) -{ - char *str, *p; - uint8_t i = 0; - buffer[0] = 0; - buffsize = 0; - int8_t cmd = -1; - - for (str = strtok_r(topic, "/", &p); str && i < 5; - str = strtok_r(NULL, "/", &p)) - { - switch (i) - { - case 0: - { - if (strcmp_P(str, mqtt_prefix) != 0) - { //look for MQTT_PREFIX - return; //Message not for us or malformatted! - } - break; - } - case 1: - { - msg.destination = atoi(str); //NodeID - break; - } - case 2: - { - msg.sensor = atoi(str); //SensorID - break; - } - case 3: - { - char match = 0; //SensorType - //strcpy(str,(char*)&str[2]); //Strip VAR_ - - for (uint8_t j = 0; - strcpy_P(convBuf, (char*) pgm_read_word(&(VAR_Type[j]))); j++) - { - if (strcmp((char*) &str[2], convBuf) == 0) - { //Strip VAR_ and compare - match = j; - break; - } - if (j >= VAR_TOTAL) - { // No match found! - match = VAR_TOTAL; // last item. - break; - } - } - msg.type = match; - break; - } - case 4: - { - // support the command get and set; get will be mapped to a C_REQ and set to C_SET - if (strcmp(str,MQTT_CMD_SET) == 0) - { - cmd = C_SET; - } - else if (strcmp(str,MQTT_CMD_GET) == 0) { - cmd = C_REQ; - } - else { -#ifdef DEBUG - Serial.print("Received unsupported command - ignore: "); - Serial.println(str); -#endif - } - } - } - i++; - } //Check if packge has payload - - if (cmd != -1) { - char* ca; - ca = (char *)payload; - ca += length; - *ca = '\0'; - - msg.set((const char*)payload); //Payload - - txBlink(1); - // inject time - if ((msg.destination == 0) && (msg.sensor == 199)) { - unsigned long epoch = atol((char*)payload); - if (epoch > 10000) { -#ifdef DSRTC - RTC.set(epoch); // this sets the RTC to the time from controller - which we do want periodically -#endif - setTime(epoch); - } -#ifdef DEBUG - Serial.print("Time received "); - Serial.println(epoch); -#endif - } - // - if (!gw.sendRoute( - build(msg, GATEWAY_ADDRESS, msg.destination, msg.sensor, C_SET, msg.type, - 0))) - errBlink(1); - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Led handling -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/* - * ledTimersIntterupt - */ -void ledTimersInterrupt() { - if (countRx && countRx != 255) { - // switch led on - digitalWrite(RADIO_RX_LED_PIN, LOW); - } else if (!countRx) { - // switching off - digitalWrite(RADIO_RX_LED_PIN, HIGH); - } - if (countRx != 255) { - countRx--; - } - - if (countTx && countTx != 255) { - // switch led on - digitalWrite(RADIO_TX_LED_PIN, LOW); - } else if (!countTx) { - // switching off - digitalWrite(RADIO_TX_LED_PIN, HIGH); - } - if (countTx != 255) { - countTx--; - } - - if (countErr && countErr != 255) { - // switch led on - digitalWrite(RADIO_ERROR_LED_PIN, LOW); - } else if (!countErr) { - // switching off - digitalWrite(RADIO_ERROR_LED_PIN, HIGH); - } - if (countErr != 255) { - countErr--; - } -} - - -void rxBlink(uint8_t cnt) -{ - if (countRx == 255) - { - countRx = cnt; - } -} - -void txBlink(uint8_t cnt) -{ - if (countTx == 255) - { - countTx = cnt; - } -} - -void errBlink(uint8_t cnt) -{ - if (countErr == 255) - { - countErr = cnt; - } -} - - diff --git a/libraries/MySensors/examples/GatewayMQTTClient/MyMQTTClient.h b/libraries/MySensors/examples/GatewayMQTTClient/MyMQTTClient.h deleted file mode 100644 index d347825..0000000 --- a/libraries/MySensors/examples/GatewayMQTTClient/MyMQTTClient.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -The MySensors library adds a new layer on top of the RF24 library. -It handles radio network routing, relaying and ids. -Created by Henrik Ekblad -Modified by Daniel Wiegert -Modified by Norbert Truchsess -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 2 as published by the Free Software Foundation. -*/ - - -#ifndef MyMQTTClient_h -#define MyMQTTClient_h - -////////////////////////////////////////////////////////////////// - -#ifdef DEBUG -#define TCPDUMP // Dump TCP packages. -#endif -#define MQTT_FIRST_SENSORID 20 // If you want manually configured nodes below this value. 255 = Disable -#define MQTT_LAST_SENSORID 254 // 254 is max! 255 reserved. -#define MQTT_PREFIX "MyMQTT" // First prefix in MQTT tree, keep short! -#define MQTT_TOPIC_MASK "MyMQTT/+/+/+/+" // Topic mask the client will subscribe to. This ensures that it will not receive any sensor data send by sensors - // the following topic structure is assumed: MyMQTT//// -#define MQTT_SEND_SUBSCRIPTION 1 // Send empty payload (request) to node upon MQTT client subscribe request. -#define MQTT_CMD_SET "set" // command (see MQTT_TOPIC_MASK); mapped to C_SET command type of sensor network -#define MQTT_CMD_GET "get" // command (see MQTT_TOPIC_MASK); mapped to C_REQ command type of sensor network - - -#define MQTT_AUTH_REQUIRED // if your broker has anonymous access uncomment -#define MQTT_USER "user" // username on MQTT broker -#define MQTT_PWD "pwd" // password for MQTT username above -#define MQTT_CONN_ID "MySensors" // passed as id to the MQTT broker - - -// NOTE above : Beware to check if there is any length on payload in your incommingMessage code: -// Example: if (msg.type==V_LIGHT && strlen(msg.getString())>0) otherwise the code might do strange things. - -////////////////////////////////////////////////////////////////// - - -char VAR_0[] PROGMEM = "TEMP"; //V_TEMP -char VAR_1[] PROGMEM = "HUM"; //V_HUM -char VAR_2[] PROGMEM = "LIGHT"; //V_LIGHT -char VAR_3[] PROGMEM = "DIMMER"; //V_DIMMER -char VAR_4[] PROGMEM = "PRESSURE"; //V_PRESSURE -char VAR_5[] PROGMEM = "FORECAST"; //V_FORECAST -char VAR_6[] PROGMEM = "RAIN"; //V_RAIN -char VAR_7[] PROGMEM = "RAINRATE"; //V_RAINRATE -char VAR_8[] PROGMEM = "WIND"; //V_WIND -char VAR_9[] PROGMEM = "GUST"; //V_GUST -char VAR_10[] PROGMEM = "DIRECTON"; //V_DIRECTON -char VAR_11[] PROGMEM = "UV"; //V_UV -char VAR_12[] PROGMEM = "WEIGHT"; //V_WEIGHT -char VAR_13[] PROGMEM = "DISTANCE"; //V_DISTANCE -char VAR_14[] PROGMEM = "IMPEDANCE"; //V_IMPEDANCE -char VAR_15[] PROGMEM = "ARMED"; //V_ARMED -char VAR_16[] PROGMEM = "TRIPPED"; //V_TRIPPED -char VAR_17[] PROGMEM = "WATT"; //V_WATT -char VAR_18[] PROGMEM = "KWH"; //V_KWH -char VAR_19[] PROGMEM = "SCENE_ON"; //V_SCENE_ON -char VAR_20[] PROGMEM = "SCENE_OFF"; //V_SCENE_OFF -char VAR_21[] PROGMEM = "HEATER"; //V_HEATER -char VAR_22[] PROGMEM = "HEATER_SW"; //V_HEATER_SW -char VAR_23[] PROGMEM = "LIGHT_LEVEL"; //V_LIGHT_LEVEL -char VAR_24[] PROGMEM = "VAR1"; //V_VAR1 -char VAR_25[] PROGMEM = "VAR2"; //V_VAR2 -char VAR_26[] PROGMEM = "VAR3"; //V_VAR3 -char VAR_27[] PROGMEM = "VAR4"; //V_VAR4 -char VAR_28[] PROGMEM = "VAR5"; //V_VAR5 -char VAR_29[] PROGMEM = "UP"; //V_UP -char VAR_30[] PROGMEM = "DOWN"; //V_DOWN -char VAR_31[] PROGMEM = "STOP"; //V_STOP -char VAR_32[] PROGMEM = "IR_SEND"; //V_IR_SEND -char VAR_33[] PROGMEM = "IR_RECEIVE"; //V_IR_RECEIVE -char VAR_34[] PROGMEM = "FLOW"; //V_FLOW -char VAR_35[] PROGMEM = "VOLUME"; //V_VOLUME -char VAR_36[] PROGMEM = "LOCK_STATUS"; //V_LOCK_STATUS -char VAR_37[] PROGMEM = "LEVEL"; // S_DUST, S_LIGHT_LEVEL, ... -char VAR_38[] PROGMEM = "VOLTAGE"; //V_VOLTAGE -char VAR_39[] PROGMEM = "CURRENT"; //V_CURRENT -char VAR_40[] PROGMEM = "RGB"; //V_RGB -char VAR_41[] PROGMEM = ""; // -char VAR_42[] PROGMEM = ""; // -char VAR_43[] PROGMEM = ""; // -char VAR_44[] PROGMEM = ""; // -char VAR_45[] PROGMEM = ""; // -char VAR_46[] PROGMEM = ""; // -char VAR_47[] PROGMEM = ""; // -char VAR_48[] PROGMEM = ""; // -char VAR_49[] PROGMEM = ""; // -char VAR_50[] PROGMEM = ""; // -char VAR_51[] PROGMEM = ""; // -char VAR_52[] PROGMEM = ""; // -char VAR_53[] PROGMEM = ""; // -char VAR_54[] PROGMEM = ""; // -char VAR_55[] PROGMEM = ""; // -char VAR_56[] PROGMEM = ""; // -char VAR_57[] PROGMEM = ""; // -char VAR_58[] PROGMEM = ""; // -char VAR_59[] PROGMEM = ""; // -char VAR_60[] PROGMEM = "Started!\n"; //Custom for MQTTGateway -char VAR_61[] PROGMEM = "SKETCH_NAME"; //Custom for MQTTGateway -char VAR_62[] PROGMEM = "SKETCH_VERSION"; //Custom for MQTTGateway -char VAR_63[] PROGMEM = "UNKNOWN"; //Custom for MQTTGateway - -////////////////////////////////////////////////////////////////// - -PROGMEM const char *VAR_Type[] = -{ VAR_0, VAR_1, VAR_2, VAR_3, VAR_4, VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11, VAR_12, VAR_13, - VAR_14, VAR_15, VAR_16, VAR_17, VAR_18, VAR_19, VAR_20, VAR_21, VAR_22, VAR_23, VAR_24, VAR_25, - VAR_26, VAR_27, VAR_28, VAR_29, VAR_30, VAR_31, VAR_32, VAR_33, VAR_34, VAR_35, VAR_36, VAR_37, - VAR_38, VAR_39, VAR_40, VAR_41, VAR_42, VAR_43, VAR_44, VAR_45, VAR_46, VAR_47, VAR_48, VAR_49, - VAR_50, VAR_51, VAR_52, VAR_53, VAR_54, VAR_55, VAR_56, VAR_57, VAR_58, VAR_59, VAR_60, VAR_61, - VAR_62, VAR_63 -}; - -char mqtt_prefix[] PROGMEM = MQTT_PREFIX; - -#define S_FIRSTCUSTOM 60 -#define TYPEMAXLEN 20 -#define VAR_TOTAL (sizeof(VAR_Type)/sizeof(char *))-1 - - -#define EEPROM_LATEST_NODE_ADDRESS ((uint8_t)EEPROM_LOCAL_CONFIG_ADDRESS) - -//#define DSRTC // RTC Dallas support -> disable debug and use isp programmer to free memory -#endif diff --git a/libraries/MySensors/examples/GatewayW5100MQTTClient/GatewayW5100MQTTClient.ino b/libraries/MySensors/examples/GatewayW5100MQTTClient/GatewayW5100MQTTClient.ino new file mode 100644 index 0000000..462dc0d --- /dev/null +++ b/libraries/MySensors/examples/GatewayW5100MQTTClient/GatewayW5100MQTTClient.ino @@ -0,0 +1,132 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + * + * REVISION HISTORY + * Version 1.0 - Henrik Ekblad + * + * DESCRIPTION + * The W5100 MQTT gateway sends radio network (or locally attached sensors) data to your MQTT broker. + * The node also listens to MY_MQTT_TOPIC_PREFIX and sends out those messages to the radio network + * + * LED purposes: + * - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h + * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved + * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly + * - ERR (red) - fast blink on error during transmission error or recieve crc error + * + * See http://www.mysensors.org/build/esp8266_gateway for wiring instructions. + * nRF24L01+ ESP8266 + * VCC VCC + * CE GPIO4 + * CSN/CS GPIO15 + * SCK GPIO14 + * MISO GPIO12 + * MOSI GPIO13 + * + * Not all ESP8266 modules have all pins available on their external interface. + * This code has been tested on an ESP-12 module. + * The ESP8266 requires a certain pin configuration to download code, and another one to run code: + * - Connect REST (reset) via 10K pullup resistor to VCC, and via switch to GND ('reset switch') + * - Connect GPIO15 via 10K pulldown resistor to GND + * - Connect CH_PD via 10K resistor to VCC + * - Connect GPIO2 via 10K resistor to VCC + * - Connect GPIO0 via 10K resistor to VCC, and via switch to GND ('bootload switch') + * + * Inclusion mode button: + * - Connect GPIO5 via switch to GND ('inclusion switch') + * + * Hardware SHA204 signing is currently not supported! + * + * Make sure to fill in your ssid and WiFi password below for ssid & pass. + */ + +#include +#include + +// Enable debug prints to serial monitor +#define MY_DEBUG + +// Enables and select radio type (if attached) +#define MY_RADIO_NRF24 +//#define MY_RADIO_RFM69 + +#define MY_GATEWAY_MQTT_CLIENT + +// Set this nodes topic prefix +#define MY_MQTT_TOPIC_PREFIX "mygateway" + +// Set MQTT client id +#define MY_MQTT_CLIENT_ID "mysensors-1" + +// Enable these if your MQTT broker requires usenrame/password +//#define MY_MQTT_USER "username" +//#define MY_MQTT_PASSWORD "password" + +// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) +#define MY_IP_ADDRESS 192,168,178,87 + +// If using static ip you need to define Gateway and Subnet address as well +#define MY_IP_GATEWAY_ADDRESS 192,168,178,1 +#define MY_IP_SUBNET_ADDRESS 255,255,255,0 + + +// MQTT broker ip address. +#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68 + +// The MQTT broker port to to open +#define MY_PORT 1883 + + /* +// Flash leds on rx/tx/err +#define MY_LEDS_BLINKING_FEATURE +// Set blinking period +#define MY_DEFAULT_LED_BLINK_PERIOD 300 + +// Enable inclusion mode +#define MY_INCLUSION_MODE_FEATURE +// Enable Inclusion mode button on gateway +#define MY_INCLUSION_BUTTON_FEATURE +// Set inclusion mode duration (in seconds) +#define MY_INCLUSION_MODE_DURATION 60 +// Digital pin used for inclusion mode button +#define MY_INCLUSION_MODE_BUTTON_PIN 3 + +#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin +#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin +#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED +*/ + +#include +#include + +void setup() { +} + +void presentation() { + // Present locally attached sensors here +} + + +void loop() { + // Send locally attech sensors data here +} + + + diff --git a/libraries/UIPEthernet_/Dhcp.cpp b/libraries/UIPEthernet_/Dhcp.cpp deleted file mode 100644 index d34e8e2..0000000 --- a/libraries/UIPEthernet_/Dhcp.cpp +++ /dev/null @@ -1,478 +0,0 @@ -// DHCP Library v0.3 - April 25, 2009 -// Author: Jordan Terrell - blog.jordanterrell.com - -#include -#include -#include "Dhcp.h" -#include "Arduino.h" -#include "utility/util.h" - -int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) -{ - _dhcpLeaseTime=0; - _dhcpT1=0; - _dhcpT2=0; - _lastCheck=0; - _timeout = timeout; - _responseTimeout = responseTimeout; - - // zero out _dhcpMacAddr - memset(_dhcpMacAddr, 0, 6); - reset_DHCP_lease(); - - memcpy((void*)_dhcpMacAddr, (void*)mac, 6); - _dhcp_state = STATE_DHCP_START; - return request_DHCP_lease(); -} - -void DhcpClass::reset_DHCP_lease(){ - // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp - memset(_dhcpLocalIp, 0, 20); -} - -//return:0 on error, 1 if request is sent and response is received -int DhcpClass::request_DHCP_lease(){ - - uint8_t messageType = 0; - - - - // Pick an initial transaction ID - _dhcpTransactionId = random(1UL, 2000UL); - _dhcpInitialTransactionId = _dhcpTransactionId; - - _dhcpUdpSocket.stop(); - if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0) - { - // Couldn't get a socket - return 0; - } - - presend_DHCP(); - - int result = 0; - - unsigned long startTime = millis(); - - while(_dhcp_state != STATE_DHCP_LEASED) - { - if(_dhcp_state == STATE_DHCP_START) - { - _dhcpTransactionId++; - - send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000)); - _dhcp_state = STATE_DHCP_DISCOVER; - } - else if(_dhcp_state == STATE_DHCP_REREQUEST){ - _dhcpTransactionId++; - send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000)); - _dhcp_state = STATE_DHCP_REQUEST; - } - else if(_dhcp_state == STATE_DHCP_DISCOVER) - { - uint32_t respId; - messageType = parseDHCPResponse(_responseTimeout, respId); - if(messageType == DHCP_OFFER) - { - // We'll use the transaction ID that the offer came with, - // rather than the one we were up to - _dhcpTransactionId = respId; - send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000)); - _dhcp_state = STATE_DHCP_REQUEST; - } - } - else if(_dhcp_state == STATE_DHCP_REQUEST) - { - uint32_t respId; - messageType = parseDHCPResponse(_responseTimeout, respId); - if(messageType == DHCP_ACK) - { - _dhcp_state = STATE_DHCP_LEASED; - result = 1; - //use default lease time if we didn't get it - if(_dhcpLeaseTime == 0){ - _dhcpLeaseTime = DEFAULT_LEASE; - } - //calculate T1 & T2 if we didn't get it - if(_dhcpT1 == 0){ - //T1 should be 50% of _dhcpLeaseTime - _dhcpT1 = _dhcpLeaseTime >> 1; - } - if(_dhcpT2 == 0){ - //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime - _dhcpT2 = _dhcpT1 << 1; - } - _renewInSec = _dhcpT1; - _rebindInSec = _dhcpT2; - } - else if(messageType == DHCP_NAK) - _dhcp_state = STATE_DHCP_START; - } - - if(messageType == 255) - { - messageType = 0; - _dhcp_state = STATE_DHCP_START; - } - - if(result != 1 && ((millis() - startTime) > _timeout)) - break; - } - - // We're done with the socket now - _dhcpUdpSocket.stop(); - _dhcpTransactionId++; - - return result; -} - -void DhcpClass::presend_DHCP() -{ -} - -void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) -{ - uint8_t buffer[32]; - memset(buffer, 0, 32); - IPAddress dest_addr( 255, 255, 255, 255 ); // Broadcast address - - if (-1 == _dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT)) - { - // FIXME Need to return errors - return; - } - - buffer[0] = DHCP_BOOTREQUEST; // op - buffer[1] = DHCP_HTYPE10MB; // htype - buffer[2] = DHCP_HLENETHERNET; // hlen - buffer[3] = DHCP_HOPS; // hops - - // xid - unsigned long xid = htonl(_dhcpTransactionId); - memcpy(buffer + 4, &(xid), 4); - - // 8, 9 - seconds elapsed - buffer[8] = ((secondsElapsed & 0xff00) >> 8); - buffer[9] = (secondsElapsed & 0x00ff); - - // flags - unsigned short flags = htons(DHCP_FLAGSBROADCAST); - memcpy(buffer + 10, &(flags), 2); - - // ciaddr: already zeroed - // yiaddr: already zeroed - // siaddr: already zeroed - // giaddr: already zeroed - - //put data in W5100 transmit buffer - _dhcpUdpSocket.write(buffer, 28); - - memset(buffer, 0, 32); // clear local buffer - - memcpy(buffer, _dhcpMacAddr, 6); // chaddr - - //put data in W5100 transmit buffer - _dhcpUdpSocket.write(buffer, 16); - - memset(buffer, 0, 32); // clear local buffer - - // leave zeroed out for sname && file - // put in W5100 transmit buffer x 6 (192 bytes) - - for(int i = 0; i < 6; i++) { - _dhcpUdpSocket.write(buffer, 32); - } - - // OPT - Magic Cookie - buffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF); - buffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF); - buffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF); - buffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF); - - // OPT - message type - buffer[4] = dhcpMessageType; - buffer[5] = 0x01; - buffer[6] = messageType; //DHCP_REQUEST; - - // OPT - client identifier - buffer[7] = dhcpClientIdentifier; - buffer[8] = 0x07; - buffer[9] = 0x01; - memcpy(buffer + 10, _dhcpMacAddr, 6); - - // OPT - host name - buffer[16] = hostName; - buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address - strcpy((char*)&(buffer[18]), HOST_NAME); - - printByte((char*)&(buffer[24]), _dhcpMacAddr[3]); - printByte((char*)&(buffer[26]), _dhcpMacAddr[4]); - printByte((char*)&(buffer[28]), _dhcpMacAddr[5]); - - //put data in W5100 transmit buffer - _dhcpUdpSocket.write(buffer, 30); - - if(messageType == DHCP_REQUEST) - { - buffer[0] = dhcpRequestedIPaddr; - buffer[1] = 0x04; - buffer[2] = _dhcpLocalIp[0]; - buffer[3] = _dhcpLocalIp[1]; - buffer[4] = _dhcpLocalIp[2]; - buffer[5] = _dhcpLocalIp[3]; - - buffer[6] = dhcpServerIdentifier; - buffer[7] = 0x04; - buffer[8] = _dhcpDhcpServerIp[0]; - buffer[9] = _dhcpDhcpServerIp[1]; - buffer[10] = _dhcpDhcpServerIp[2]; - buffer[11] = _dhcpDhcpServerIp[3]; - - //put data in W5100 transmit buffer - _dhcpUdpSocket.write(buffer, 12); - } - - buffer[0] = dhcpParamRequest; - buffer[1] = 0x06; - buffer[2] = subnetMask; - buffer[3] = routersOnSubnet; - buffer[4] = dns; - buffer[5] = domainName; - buffer[6] = dhcpT1value; - buffer[7] = dhcpT2value; - buffer[8] = endOption; - - //put data in W5100 transmit buffer - _dhcpUdpSocket.write(buffer, 9); - - _dhcpUdpSocket.endPacket(); -} - -uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId) -{ - uint8_t type = 0; - uint8_t opt_len = 0; - - unsigned long startTime = millis(); - - while(_dhcpUdpSocket.parsePacket() <= 0) - { - if((millis() - startTime) > responseTimeout) - { - return 255; - } - delay(50); - } - // start reading in the packet - RIP_MSG_FIXED fixedMsg; - _dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED)); - - if(fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT) - { - transactionId = ntohl(fixedMsg.xid); - if(memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 || (transactionId < _dhcpInitialTransactionId) || (transactionId > _dhcpTransactionId)) - { - // Need to read the rest of the packet here regardless - _dhcpUdpSocket.flush(); - return 0; - } - - memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4); - - // Skip to the option part - // Doing this a byte at a time so we don't have to put a big buffer - // on the stack (as we don't have lots of memory lying around) - for (int i =0; i < (240 - (int)sizeof(RIP_MSG_FIXED)); i++) - { - _dhcpUdpSocket.read(); // we don't care about the returned byte - } - - while (_dhcpUdpSocket.available() > 0) - { - switch (_dhcpUdpSocket.read()) - { - case endOption : - break; - - case padOption : - break; - - case dhcpMessageType : - opt_len = _dhcpUdpSocket.read(); - type = _dhcpUdpSocket.read(); - break; - - case subnetMask : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read(_dhcpSubnetMask, 4); - break; - - case routersOnSubnet : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read(_dhcpGatewayIp, 4); - for (int i = 0; i < opt_len-4; i++) - { - _dhcpUdpSocket.read(); - } - break; - - case dns : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read(_dhcpDnsServerIp, 4); - for (int i = 0; i < opt_len-4; i++) - { - _dhcpUdpSocket.read(); - } - break; - - case dhcpServerIdentifier : - opt_len = _dhcpUdpSocket.read(); - if( *((uint32_t*)_dhcpDhcpServerIp) == 0 || - IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() ) - { - _dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp)); - } - else - { - // Skip over the rest of this option - while (opt_len--) - { - _dhcpUdpSocket.read(); - } - } - break; - - case dhcpT1value : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1)); - _dhcpT1 = ntohl(_dhcpT1); - break; - - case dhcpT2value : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2)); - _dhcpT2 = ntohl(_dhcpT2); - break; - - case dhcpIPaddrLeaseTime : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime)); - _dhcpLeaseTime = ntohl(_dhcpLeaseTime); - _renewInSec = _dhcpLeaseTime; - break; - - default : - opt_len = _dhcpUdpSocket.read(); - // Skip over the rest of this option - while (opt_len--) - { - _dhcpUdpSocket.read(); - } - break; - } - } - } - - // Need to skip to end of the packet regardless here - _dhcpUdpSocket.flush(); - - return type; -} - - -/* - returns: - 0/DHCP_CHECK_NONE: nothing happened - 1/DHCP_CHECK_RENEW_FAIL: renew failed - 2/DHCP_CHECK_RENEW_OK: renew success - 3/DHCP_CHECK_REBIND_FAIL: rebind fail - 4/DHCP_CHECK_REBIND_OK: rebind success -*/ -int DhcpClass::checkLease(){ - //this uses a signed / unsigned trick to deal with millis overflow - unsigned long now = millis(); - signed long snow = (long)now; - int rc=DHCP_CHECK_NONE; - if (_lastCheck != 0){ - signed long factor; - //calc how many ms past the timeout we are - factor = snow - (long)_secTimeout; - //if on or passed the timeout, reduce the counters - if ( factor >= 0 ){ - //next timeout should be now plus 1000 ms minus parts of second in factor - _secTimeout = snow + 1000 - factor % 1000; - //how many seconds late are we, minimum 1 - factor = factor / 1000 +1; - - //reduce the counters by that mouch - //if we can assume that the cycle time (factor) is fairly constant - //and if the remainder is less than cycle time * 2 - //do it early instead of late - if(_renewInSec < factor*2 ) - _renewInSec = 0; - else - _renewInSec -= factor; - - if(_rebindInSec < factor*2 ) - _rebindInSec = 0; - else - _rebindInSec -= factor; - } - - //if we have a lease but should renew, do it - if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){ - _dhcp_state = STATE_DHCP_REREQUEST; - rc = 1 + request_DHCP_lease(); - } - - //if we have a lease or is renewing but should bind, do it - if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){ - //this should basically restart completely - _dhcp_state = STATE_DHCP_START; - reset_DHCP_lease(); - rc = 3 + request_DHCP_lease(); - } - } - else{ - _secTimeout = snow + 1000; - } - - _lastCheck = now; - return rc; -} - -IPAddress DhcpClass::getLocalIp() -{ - return IPAddress(_dhcpLocalIp); -} - -IPAddress DhcpClass::getSubnetMask() -{ - return IPAddress(_dhcpSubnetMask); -} - -IPAddress DhcpClass::getGatewayIp() -{ - return IPAddress(_dhcpGatewayIp); -} - -IPAddress DhcpClass::getDhcpServerIp() -{ - return IPAddress(_dhcpDhcpServerIp); -} - -IPAddress DhcpClass::getDnsServerIp() -{ - return IPAddress(_dhcpDnsServerIp); -} - -void DhcpClass::printByte(char * buf, uint8_t n ) { - char *str = &buf[1]; - buf[0]='0'; - do { - unsigned long m = n; - n /= 16; - char c = m - 16 * n; - *str-- = c < 10 ? c + '0' : c + 'A' - 10; - } while(n); -} diff --git a/libraries/UIPEthernet_/Dhcp.h b/libraries/UIPEthernet_/Dhcp.h deleted file mode 100644 index 01405d7..0000000 --- a/libraries/UIPEthernet_/Dhcp.h +++ /dev/null @@ -1,178 +0,0 @@ -// DHCP Library v0.3 - April 25, 2009 -// Author: Jordan Terrell - blog.jordanterrell.com - -#ifndef Dhcp_h -#define Dhcp_h - -#include "UIPUdp.h" - -/* DHCP state machine. */ -#define STATE_DHCP_START 0 -#define STATE_DHCP_DISCOVER 1 -#define STATE_DHCP_REQUEST 2 -#define STATE_DHCP_LEASED 3 -#define STATE_DHCP_REREQUEST 4 -#define STATE_DHCP_RELEASE 5 - -#define DHCP_FLAGSBROADCAST 0x8000 - -/* UDP port numbers for DHCP */ -#define DHCP_SERVER_PORT 67 /* from server to client */ -#define DHCP_CLIENT_PORT 68 /* from client to server */ - -/* DHCP message OP code */ -#define DHCP_BOOTREQUEST 1 -#define DHCP_BOOTREPLY 2 - -/* DHCP message type */ -#define DHCP_DISCOVER 1 -#define DHCP_OFFER 2 -#define DHCP_REQUEST 3 -#define DHCP_DECLINE 4 -#define DHCP_ACK 5 -#define DHCP_NAK 6 -#define DHCP_RELEASE 7 -#define DHCP_INFORM 8 - -#define DHCP_HTYPE10MB 1 -#define DHCP_HTYPE100MB 2 - -#define DHCP_HLENETHERNET 6 -#define DHCP_HOPS 0 -#define DHCP_SECS 0 - -#define MAGIC_COOKIE 0x63825363 -#define MAX_DHCP_OPT 16 - -#define HOST_NAME "ENC28J" -#define DEFAULT_LEASE (900) //default lease time in seconds - -#define DHCP_CHECK_NONE (0) -#define DHCP_CHECK_RENEW_FAIL (1) -#define DHCP_CHECK_RENEW_OK (2) -#define DHCP_CHECK_REBIND_FAIL (3) -#define DHCP_CHECK_REBIND_OK (4) - -enum -{ - padOption = 0, - subnetMask = 1, - timerOffset = 2, - routersOnSubnet = 3, - /* timeServer = 4, - nameServer = 5,*/ - dns = 6, - /*logServer = 7, - cookieServer = 8, - lprServer = 9, - impressServer = 10, - resourceLocationServer = 11,*/ - hostName = 12, - /*bootFileSize = 13, - meritDumpFile = 14,*/ - domainName = 15, - /*swapServer = 16, - rootPath = 17, - extentionsPath = 18, - IPforwarding = 19, - nonLocalSourceRouting = 20, - policyFilter = 21, - maxDgramReasmSize = 22, - defaultIPTTL = 23, - pathMTUagingTimeout = 24, - pathMTUplateauTable = 25, - ifMTU = 26, - allSubnetsLocal = 27, - broadcastAddr = 28, - performMaskDiscovery = 29, - maskSupplier = 30, - performRouterDiscovery = 31, - routerSolicitationAddr = 32, - staticRoute = 33, - trailerEncapsulation = 34, - arpCacheTimeout = 35, - ethernetEncapsulation = 36, - tcpDefaultTTL = 37, - tcpKeepaliveInterval = 38, - tcpKeepaliveGarbage = 39, - nisDomainName = 40, - nisServers = 41, - ntpServers = 42, - vendorSpecificInfo = 43, - netBIOSnameServer = 44, - netBIOSdgramDistServer = 45, - netBIOSnodeType = 46, - netBIOSscope = 47, - xFontServer = 48, - xDisplayManager = 49,*/ - dhcpRequestedIPaddr = 50, - dhcpIPaddrLeaseTime = 51, - /*dhcpOptionOverload = 52,*/ - dhcpMessageType = 53, - dhcpServerIdentifier = 54, - dhcpParamRequest = 55, - /*dhcpMsg = 56, - dhcpMaxMsgSize = 57,*/ - dhcpT1value = 58, - dhcpT2value = 59, - /*dhcpClassIdentifier = 60,*/ - dhcpClientIdentifier = 61, - endOption = 255 -}; - -typedef struct _RIP_MSG_FIXED -{ - uint8_t op; - uint8_t htype; - uint8_t hlen; - uint8_t hops; - uint32_t xid; - uint16_t secs; - uint16_t flags; - uint8_t ciaddr[4]; - uint8_t yiaddr[4]; - uint8_t siaddr[4]; - uint8_t giaddr[4]; - uint8_t chaddr[6]; -}RIP_MSG_FIXED; - -class DhcpClass { -private: - uint32_t _dhcpInitialTransactionId; - uint32_t _dhcpTransactionId; - uint8_t _dhcpMacAddr[6]; - uint8_t _dhcpLocalIp[4]; - uint8_t _dhcpSubnetMask[4]; - uint8_t _dhcpGatewayIp[4]; - uint8_t _dhcpDhcpServerIp[4]; - uint8_t _dhcpDnsServerIp[4]; - uint32_t _dhcpLeaseTime; - uint32_t _dhcpT1, _dhcpT2; - signed long _renewInSec; - signed long _rebindInSec; - signed long _lastCheck; - unsigned long _timeout; - unsigned long _responseTimeout; - unsigned long _secTimeout; - uint8_t _dhcp_state; - UIPUDP _dhcpUdpSocket; - - int request_DHCP_lease(); - void reset_DHCP_lease(); - void presend_DHCP(); - void send_DHCP_MESSAGE(uint8_t, uint16_t); - void printByte(char *, uint8_t); - - uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId); -public: - IPAddress getLocalIp(); - IPAddress getSubnetMask(); - IPAddress getGatewayIp(); - IPAddress getDhcpServerIp(); - IPAddress getDnsServerIp(); - - int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); - int checkLease(); -}; - -#endif diff --git a/libraries/UIPEthernet_/Dns.cpp b/libraries/UIPEthernet_/Dns.cpp deleted file mode 100644 index 2b97fb7..0000000 --- a/libraries/UIPEthernet_/Dns.cpp +++ /dev/null @@ -1,422 +0,0 @@ -// Arduino DNS client for Enc28J60-based Ethernet shield -// (c) Copyright 2009-2010 MCQN Ltd. -// Released under Apache License, version 2.0 - -#include "Udp.h" -#include "utility/util.h" - -#include "Dns.h" -#include -//#include -#include "Arduino.h" - - -#define SOCKET_NONE 255 -// Various flags and header field values for a DNS message -#define UDP_HEADER_SIZE 8 -#define DNS_HEADER_SIZE 12 -#define TTL_SIZE 4 -#define QUERY_FLAG (0) -#define RESPONSE_FLAG (1<<15) -#define QUERY_RESPONSE_MASK (1<<15) -#define OPCODE_STANDARD_QUERY (0) -#define OPCODE_INVERSE_QUERY (1<<11) -#define OPCODE_STATUS_REQUEST (2<<11) -#define OPCODE_MASK (15<<11) -#define AUTHORITATIVE_FLAG (1<<10) -#define TRUNCATION_FLAG (1<<9) -#define RECURSION_DESIRED_FLAG (1<<8) -#define RECURSION_AVAILABLE_FLAG (1<<7) -#define RESP_NO_ERROR (0) -#define RESP_FORMAT_ERROR (1) -#define RESP_SERVER_FAILURE (2) -#define RESP_NAME_ERROR (3) -#define RESP_NOT_IMPLEMENTED (4) -#define RESP_REFUSED (5) -#define RESP_MASK (15) -#define TYPE_A (0x0001) -#define CLASS_IN (0x0001) -#define LABEL_COMPRESSION_MASK (0xC0) -// Port number that DNS servers listen on -#define DNS_PORT 53 - -// Possible return codes from ProcessResponse -#define SUCCESS 1 -#define TIMED_OUT -1 -#define INVALID_SERVER -2 -#define TRUNCATED -3 -#define INVALID_RESPONSE -4 - -void DNSClient::begin(const IPAddress& aDNSServer) -{ - iDNSServer = aDNSServer; - iRequestId = 0; -} - - -int DNSClient::inet_aton(const char* aIPAddrString, IPAddress& aResult) -{ - // See if we've been given a valid IP address - const char* p =aIPAddrString; - while (*p && - ( (*p == '.') || (*p >= '0') || (*p <= '9') )) - { - p++; - } - - if (*p == '\0') - { - // It's looking promising, we haven't found any invalid characters - p = aIPAddrString; - int segment =0; - int segmentValue =0; - while (*p && (segment < 4)) - { - if (*p == '.') - { - // We've reached the end of a segment - if (segmentValue > 255) - { - // You can't have IP address segments that don't fit in a byte - return 0; - } - else - { - aResult[segment] = (byte)segmentValue; - segment++; - segmentValue = 0; - } - } - else - { - // Next digit - segmentValue = (segmentValue*10)+(*p - '0'); - } - p++; - } - // We've reached the end of address, but there'll still be the last - // segment to deal with - if ((segmentValue > 255) || (segment > 3)) - { - // You can't have IP address segments that don't fit in a byte, - // or more than four segments - return 0; - } - else - { - aResult[segment] = (byte)segmentValue; - return 1; - } - } - else - { - return 0; - } -} - -int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) -{ - int ret =0; - - // See if it's a numeric IP address - if (inet_aton(aHostname, aResult)) - { - // It is, our work here is done - return 1; - } - - // Check we've got a valid DNS server to use - if (iDNSServer == INADDR_NONE) - { - return INVALID_SERVER; - } - - // Find a socket to use - if (iUdp.begin(1024+(millis() & 0xF)) == 1) - { - // Try up to three times - int retries = 0; -// while ((retries < 3) && (ret <= 0)) - { - // Send DNS request - ret = iUdp.beginPacket(iDNSServer, DNS_PORT); - if (ret != 0) - { - // Now output the request data - ret = BuildRequest(aHostname); - if (ret != 0) - { - // And finally send the request - ret = iUdp.endPacket(); - if (ret != 0) - { - // Now wait for a response - int wait_retries = 0; - ret = TIMED_OUT; - while ((wait_retries < 3) && (ret == TIMED_OUT)) - { - ret = ProcessResponse(5000, aResult); - wait_retries++; - } - } - } - } - retries++; - } - - // We're done with the socket now - iUdp.stop(); - } - - return ret; -} - -uint16_t DNSClient::BuildRequest(const char* aName) -{ - // Build header - // 1 1 1 1 1 1 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | ID | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | QDCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | ANCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | NSCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | ARCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // As we only support one request at a time at present, we can simplify - // some of this header - iRequestId = millis(); // generate a random ID - uint16_t twoByteBuffer; - - // FIXME We should also check that there's enough space available to write to, rather - // FIXME than assume there's enough space (as the code does at present) - iUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId)); - - twoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG); - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - twoByteBuffer = htons(1); // One question record - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - twoByteBuffer = 0; // Zero answer records - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - // and zero additional records - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - // Build question - const char* start =aName; - const char* end =start; - uint8_t len; - // Run through the name being requested - while (*end) - { - // Find out how long this section of the name is - end = start; - while (*end && (*end != '.') ) - { - end++; - } - - if (end-start > 0) - { - // Write out the size of this section - len = end-start; - iUdp.write(&len, sizeof(len)); - // And then write out the section - iUdp.write((uint8_t*)start, end-start); - } - start = end+1; - } - - // We've got to the end of the question name, so - // terminate it with a zero-length section - len = 0; - iUdp.write(&len, sizeof(len)); - // Finally the type and class of question - twoByteBuffer = htons(TYPE_A); - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - twoByteBuffer = htons(CLASS_IN); // Internet class of question - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - // Success! Everything buffered okay - return 1; -} - - -uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) -{ - uint32_t startTime = millis(); - - // Wait for a response packet - while(iUdp.parsePacket() <= 0) - { - if((millis() - startTime) > aTimeout) - return TIMED_OUT; - delay(50); - } - - // We've had a reply! - // Read the UDP header - uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header - // Check that it's a response from the right server and the right port - if ( (iDNSServer != iUdp.remoteIP()) || - (iUdp.remotePort() != DNS_PORT) ) - { - // It's not from who we expected - return INVALID_SERVER; - } - - // Read through the rest of the response - if (iUdp.available() < DNS_HEADER_SIZE) - { - return TRUNCATED; - } - iUdp.read(header, DNS_HEADER_SIZE); - - uint16_t header_flags = htons(*((uint16_t*)&header[2])); - // Check that it's a response to this request - if ( ( iRequestId != (*((uint16_t*)&header[0])) ) || - ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) - { - // Mark the entire packet as read - iUdp.flush(); - return INVALID_RESPONSE; - } - // Check for any errors in the response (or in our request) - // although we don't do anything to get round these - if ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) ) - { - // Mark the entire packet as read - iUdp.flush(); - return -5; //INVALID_RESPONSE; - } - - // And make sure we've got (at least) one answer - uint16_t answerCount = htons(*((uint16_t*)&header[6])); - if (answerCount == 0 ) - { - // Mark the entire packet as read - iUdp.flush(); - return -6; //INVALID_RESPONSE; - } - - // Skip over any questions - for (uint16_t i =0; i < htons(*((uint16_t*)&header[4])); i++) - { - // Skip over the name - uint8_t len; - do - { - iUdp.read(&len, sizeof(len)); - if (len > 0) - { - // Don't need to actually read the data out for the string, just - // advance ptr to beyond it - while(len--) - { - iUdp.read(); // we don't care about the returned byte - } - } - } while (len != 0); - - // Now jump over the type and class - for (int i =0; i < 4; i++) - { - iUdp.read(); // we don't care about the returned byte - } - } - - // Now we're up to the bit we're interested in, the answer - // There might be more than one answer (although we'll just use the first - // type A answer) and some authority and additional resource records but - // we're going to ignore all of them. - - for (uint16_t i =0; i < answerCount; i++) - { - // Skip the name - uint8_t len; - do - { - iUdp.read(&len, sizeof(len)); - if ((len & LABEL_COMPRESSION_MASK) == 0) - { - // It's just a normal label - if (len > 0) - { - // And it's got a length - // Don't need to actually read the data out for the string, - // just advance ptr to beyond it - while(len--) - { - iUdp.read(); // we don't care about the returned byte - } - } - } - else - { - // This is a pointer to a somewhere else in the message for the - // rest of the name. We don't care about the name, and RFC1035 - // says that a name is either a sequence of labels ended with a - // 0 length octet or a pointer or a sequence of labels ending in - // a pointer. Either way, when we get here we're at the end of - // the name - // Skip over the pointer - iUdp.read(); // we don't care about the returned byte - // And set len so that we drop out of the name loop - len = 0; - } - } while (len != 0); - - // Check the type and class - uint16_t answerType; - uint16_t answerClass; - iUdp.read((uint8_t*)&answerType, sizeof(answerType)); - iUdp.read((uint8_t*)&answerClass, sizeof(answerClass)); - - // Ignore the Time-To-Live as we don't do any caching - for (int i =0; i < TTL_SIZE; i++) - { - iUdp.read(); // we don't care about the returned byte - } - - // And read out the length of this answer - // Don't need header_flags anymore, so we can reuse it here - iUdp.read((uint8_t*)&header_flags, sizeof(header_flags)); - - if ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) ) - { - if (htons(header_flags) != 4) - { - // It's a weird size - // Mark the entire packet as read - iUdp.flush(); - return -9;//INVALID_RESPONSE; - } - iUdp.read(aAddress.raw_address(), 4); - return SUCCESS; - } - else - { - // This isn't an answer type we're after, move onto the next one - for (uint16_t i =0; i < htons(header_flags); i++) - { - iUdp.read(); // we don't care about the returned byte - } - } - } - - // Mark the entire packet as read - iUdp.flush(); - - // If we get here then we haven't found an answer - return -10;//INVALID_RESPONSE; -} - diff --git a/libraries/UIPEthernet_/Dns.h b/libraries/UIPEthernet_/Dns.h deleted file mode 100644 index 1b6bb3d..0000000 --- a/libraries/UIPEthernet_/Dns.h +++ /dev/null @@ -1,41 +0,0 @@ -// Arduino DNS client for Enc28J60-based Ethernet shield -// (c) Copyright 2009-2010 MCQN Ltd. -// Released under Apache License, version 2.0 - -#ifndef DNSClient_h -#define DNSClient_h - -#include "UIPUdp.h" - -class DNSClient -{ -public: - // ctor - void begin(const IPAddress& aDNSServer); - - /** Convert a numeric IP address string into a four-byte IP address. - @param aIPAddrString IP address to convert - @param aResult IPAddress structure to store the returned IP address - @result 1 if aIPAddrString was successfully converted to an IP address, - else error code - */ - int inet_aton(const char *aIPAddrString, IPAddress& aResult); - - /** Resolve the given hostname to an IP address. - @param aHostname Name to be resolved - @param aResult IPAddress structure to store the returned IP address - @result 1 if aIPAddrString was successfully converted to an IP address, - else error code - */ - int getHostByName(const char* aHostname, IPAddress& aResult); - -protected: - uint16_t BuildRequest(const char* aName); - uint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress); - - IPAddress iDNSServer; - uint16_t iRequestId; - UIPUDP iUdp; -}; - -#endif diff --git a/libraries/UIPEthernet_/README b/libraries/UIPEthernet_/README deleted file mode 100644 index c7368c6..0000000 --- a/libraries/UIPEthernet_/README +++ /dev/null @@ -1,227 +0,0 @@ -This is UIPEthernet version 1.59 - -An plugin-replacement of the stock Arduino Ethernet library for ENC28J60 shields and breakout boards. Full support for persistent (streaming) TCP-connections and UDP (Client and Server each), ARP, ICMP, DHCP and DNS. -Just include 'UIPEthernet.h' instead of 'Ethernet.h' and use all your code written for the stock Arduino Ethernet lib! - -UIPEthernet is written as a wrapper around the mature uIP Stack by Adam Dunkels, which provides the low-level implementation for all supported protocols. To overcome the memory-constrains (a 'regular' uIP-application does all processing in RAM) the ENC28J60 internal memory is used for all stream buffers (in and out). Only 400-600 Bytes of Arduinos RAM are used (depending on the number of concurrently open connections). As of Flash-memory a ATmega368-based Arduino is the minimum requirenment. - -This library is written by Norbert Truchsess - -uIP was written by Adam Dunkels of the Networked Embedded Systems group at the Swedish Institute of Computer Science. - -This library was inspired by the SerialIP implementation by Adam Nielsen , actually I took this code as a starting point, but in the latest versions there are very few lines left. - -Installation ------------- - -To install the libraries, you need to place them into your "libraries" folder. You can find it within your Arduino IDE distribution within the "hardware" folder. - - C:\> cd [path to Arduino distribution]\libraries - C:\> git clone https://github.com/ntruchsess/arduino_uip UIPEthernet - -Be sure to restart the IDE if it was running. - -On a Mac, you will want to create a folder named "libraries" in in the "Documents" -> "Arduino" folder within your home directory. Clone the project there (and restart the IDE, if it was running during this process). - - $ cd ~/Documents/Arduino/libraries - $ git clone https://github.com/ntruchsess/arduino_uip UIPEthernet - -Or you download the zipped version of the library from https://github.com/ntruchsess/arduino_uip/releases, and copy the contained directory UIPEthernet to [path to Arduino distribution]\libraries\UIPEthernet. - -If you are running Arduino-IDE 1.5.x use release-version 1.59 or checkout branch 'Arduino_1.5.x' - -Additional information can be found on the Arduino website: http://www.arduino.cc/en/Hacking/Libraries - -Documentation -------------- - -For more information visit: - - - UIPEthernet Repository on github: - https://github.com/ntruchsess/arduino_uip - - - Arduino Ethernet library description - http://arduino.cc/en/Reference/Ethernet - (Arduino_uip uses the same API as that, just include "UIPEthernet.h", "UIPClient.h", "UIPServer.h" and "UIPUDP.h" instead of the stock "Ethernet.h", "EthernetClient.h", "EthernetServer.h " and "EthernetUDP.h") - - - uIP API reference: - http://www.sics.se/~adam/uip/uip-1.0-refman/ - - - Arduino forums - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl - - - uIP homepage: - http://www.sics.se/~adam/uip/index.php/Main_Page - -Licenses -------------- - -UIPEthernet.h -UIPEthernet.cpp -UIPServer.h -UIPServer.cpp -UIPClient.h -UIPClient.cpp -UIPUdp.h -UIPUdp.cpp -utility/mempool.h -utility/mempool.cpp - -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 . - --------------- - -utility/enc28j60.h - -Author : Pascal Stang (c)2005 -Modified by Norbert Truchsess -Copyright: GPL V2 - --------------- - -utility/Enc28J60Network.h -utility/Enc28J60Network.cpp - -Copyright (c) 2013 Norbert Truchsess -All rights reserved. - -inspired and based on enc28j60.c file from the AVRlib library by Pascal Stang. - -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 . - --------------- - -utility/uip.c -utility/uip_arp.h -utility/uip_arp.c -utility/uip_arch.h -utility/uip.h -utility/uipopt.h - -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. 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. - --------------- - -uip-conf.h -utility/uip-neighbor.h -utility/uip-neighbor.c -utility/uip_timer.h -utility/uip_timer.c -utility/uip_clock.h - -Author Adam Dunkels Adam Dunkels , -Copyright (c) 2004,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. - --------------- - -Dhcp.h -Dhcp.cpp - -DHCP Library v0.3 - April 25, 2009 -Author: Jordan Terrell - blog.jordanterrell.com -- as included in Arduinos stock Ethernet-library, no special licence mentioned here - --------------- - -Dns.h -Dns.cpp - -(c) Copyright 2009-2010 MCQN Ltd. -Released under Apache License, version 2.0 - --------------- - -clock-arch.h -clock-arch.c - -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 diff --git a/libraries/UIPEthernet_/UIPClient.cpp b/libraries/UIPEthernet_/UIPClient.cpp deleted file mode 100644 index b832d0a..0000000 --- a/libraries/UIPEthernet_/UIPClient.cpp +++ /dev/null @@ -1,583 +0,0 @@ -/* - UIPClient.cpp - Arduino implementation of a uIP wrapper class. - 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 . - */ - -extern "C" -{ -#include "utility/uip-conf.h" -#include "utility/uip.h" -#include "utility/uip_arp.h" -#include "string.h" -} -#include "UIPEthernet.h" -#include "UIPClient.h" -#include "Dns.h" - -#ifdef UIPETHERNET_DEBUG_CLIENT -#include "HardwareSerial.h" -#endif - -#define UIP_TCP_PHYH_LEN UIP_LLH_LEN+UIP_IPTCPH_LEN - -uip_userdata_t UIPClient::all_data[UIP_CONNS]; - -UIPClient::UIPClient() : - data(NULL) -{ -} - -UIPClient::UIPClient(uip_userdata_t* conn_data) : - data(conn_data) -{ -} - -int -UIPClient::connect(IPAddress ip, uint16_t port) -{ - stop(); - uip_ipaddr_t ipaddr; - uip_ip_addr(ipaddr, ip); - struct uip_conn* conn = uip_connect(&ipaddr, htons(port)); - if (conn) - { -#if UIP_CONNECT_TIMEOUT > 0 - int32_t timeout = millis() + 1000 * UIP_CONNECT_TIMEOUT; -#endif - while((conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) - { - UIPEthernetClass::tick(); - if ((conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) - { - data = (uip_userdata_t*) conn->appstate; -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("connected, state: ")); - Serial.print(data->state); - Serial.print(F(", first packet in: ")); - Serial.println(data->packets_in[0]); -#endif - return 1; - } -#if UIP_CONNECT_TIMEOUT > 0 - if (((int32_t)(millis() - timeout)) > 0) - { - conn->tcpstateflags = UIP_CLOSED; - break; - } -#endif - } - } - return 0; -} - -int -UIPClient::connect(const char *host, uint16_t port) -{ - // Look up the host first - int ret = 0; -#if UIP_UDP - DNSClient dns; - IPAddress remote_addr; - - dns.begin(UIPEthernetClass::_dnsServerAddress); - ret = dns.getHostByName(host, remote_addr); - if (ret == 1) { - return connect(remote_addr, port); - } -#endif - return ret; -} - -void -UIPClient::stop() -{ - if (data && data->state) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("before stop(), with data")); - _dumpAllData(); -#endif - _flushBlocks(&data->packets_in[0]); - if (data->state & UIP_CLIENT_REMOTECLOSED) - { - data->state = 0; - } - else - { - data->state |= UIP_CLIENT_CLOSE; - } -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("after stop()")); - _dumpAllData(); -#endif - } -#ifdef UIPETHERNET_DEBUG_CLIENT - else - { - Serial.println(F("stop(), data: NULL")); - } -#endif - data = NULL; - UIPEthernetClass::tick(); -} - -uint8_t -UIPClient::connected() -{ - return (data && (data->packets_in[0] != NOBLOCK || (data->state & UIP_CLIENT_CONNECTED))) ? 1 : 0; -} - -bool -UIPClient::operator==(const UIPClient& rhs) -{ - return data && rhs.data && (data == rhs.data); -} - -UIPClient::operator bool() -{ - UIPEthernetClass::tick(); - return data && (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != NOBLOCK); -} - -size_t -UIPClient::write(uint8_t c) -{ - return _write(data, &c, 1); -} - -size_t -UIPClient::write(const uint8_t *buf, size_t size) -{ - return _write(data, buf, size); -} - -size_t -UIPClient::_write(uip_userdata_t* u, const uint8_t *buf, size_t size) -{ - int remain = size; - uint16_t written; -#if UIP_ATTEMPTS_ON_WRITE > 0 - uint16_t attempts = UIP_ATTEMPTS_ON_WRITE; -#endif - repeat: - UIPEthernetClass::tick(); - if (u && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) - { - uint8_t p = _currentBlock(&u->packets_out[0]); - if (u->packets_out[p] == NOBLOCK) - { -newpacket: - u->packets_out[p] = Enc28J60Network::allocBlock(UIP_SOCKET_DATALEN); - if (u->packets_out[p] == NOBLOCK) - { -#if UIP_ATTEMPTS_ON_WRITE > 0 - if ((--attempts)>0) -#endif -#if UIP_ATTEMPTS_ON_WRITE != 0 - goto repeat; -#endif - goto ready; - } - u->out_pos = 0; - } -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient.write: writePacket(")); - Serial.print(u->packets_out[p]); - Serial.print(F(") pos: ")); - Serial.print(u->out_pos); - Serial.print(F(", buf[")); - Serial.print(size-remain); - Serial.print(F("-")); - Serial.print(remain); - Serial.print(F("]: '")); - Serial.write((uint8_t*)buf+size-remain,remain); - Serial.println(F("'")); -#endif - written = Enc28J60Network::writePacket(u->packets_out[p],u->out_pos,(uint8_t*)buf+size-remain,remain); - remain -= written; - u->out_pos+=written; - if (remain > 0) - { - if (p == UIP_SOCKET_NUMPACKETS-1) - { -#if UIP_ATTEMPTS_ON_WRITE > 0 - if ((--attempts)>0) -#endif -#if UIP_ATTEMPTS_ON_WRITE != 0 - goto repeat; -#endif - goto ready; - } - p++; - goto newpacket; - } -ready: -#if UIP_CLIENT_TIMER >= 0 - u->timer = millis()+UIP_CLIENT_TIMER; -#endif - return size-remain; - } - return -1; -} - -int -UIPClient::available() -{ - if (*this) - return _available(data); - return 0; -} - -int -UIPClient::_available(uip_userdata_t *u) -{ - int len = 0; - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) - { - len += Enc28J60Network::blockSize(u->packets_in[i]); - } - return len; -} - -int -UIPClient::read(uint8_t *buf, size_t size) -{ - if (*this) - { - uint16_t remain = size; - if (data->packets_in[0] == NOBLOCK) - return 0; - uint16_t read; - do - { - read = Enc28J60Network::readPacket(data->packets_in[0],0,buf+size-remain,remain); - if (read == Enc28J60Network::blockSize(data->packets_in[0])) - { - remain -= read; - _eatBlock(&data->packets_in[0]); - if (uip_stopped(&uip_conns[data->state & UIP_CLIENT_SOCKETS]) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) - data->state |= UIP_CLIENT_RESTART; - if (data->packets_in[0] == NOBLOCK) - { - if (data->state & UIP_CLIENT_REMOTECLOSED) - { - data->state = 0; - data = NULL; - } - return size-remain; - } - } - else - { - Enc28J60Network::resizeBlock(data->packets_in[0],read); - break; - } - } - while(remain > 0); - return size; - } - return -1; -} - -int -UIPClient::read() -{ - uint8_t c; - if (read(&c,1) < 0) - return -1; - return c; -} - -int -UIPClient::peek() -{ - if (*this) - { - if (data->packets_in[0] != NOBLOCK) - { - uint8_t c; - Enc28J60Network::readPacket(data->packets_in[0],0,&c,1); - return c; - } - } - return -1; -} - -void -UIPClient::flush() -{ - if (*this) - { - _flushBlocks(&data->packets_in[0]); - } -} - -void -uipclient_appcall(void) -{ - uint16_t send_len = 0; - uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate; - if (!u && uip_connected()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient uip_connected")); - UIPClient::_dumpAllData(); -#endif - u = (uip_userdata_t*) UIPClient::_allocateData(); - if (u) - { - uip_conn->appstate = u; -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient allocated state: ")); - Serial.println(u->state,BIN); -#endif - } -#ifdef UIPETHERNET_DEBUG_CLIENT - else - Serial.println(F("UIPClient allocation failed")); -#endif - } - if (u) - { - if (uip_newdata()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient uip_newdata, uip_len:")); - Serial.println(uip_len); -#endif - if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) - { - for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++) - { - if (u->packets_in[i] == NOBLOCK) - { - u->packets_in[i] = Enc28J60Network::allocBlock(uip_len); - if (u->packets_in[i] != NOBLOCK) - { - Enc28J60Network::copyPacket(u->packets_in[i],0,UIPEthernetClass::in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len); - if (i == UIP_SOCKET_NUMPACKETS-1) - uip_stop(); - goto finish_newdata; - } - } - } - UIPEthernetClass::packetstate &= ~UIPETHERNET_FREEPACKET; - uip_stop(); - } - } -finish_newdata: - if (u->state & UIP_CLIENT_RESTART) - { - u->state &= ~UIP_CLIENT_RESTART; - uip_restart(); - } - // If the connection has been closed, save received but unread data. - if (uip_closed() || uip_timedout()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient uip_closed")); - UIPClient::_dumpAllData(); -#endif - // drop outgoing packets not sent yet: - UIPClient::_flushBlocks(&u->packets_out[0]); - if (u->packets_in[0] != NOBLOCK) - { - ((uip_userdata_closed_t *)u)->lport = uip_conn->lport; - u->state |= UIP_CLIENT_REMOTECLOSED; - } - else - u->state = 0; - // disassociate appdata. -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("after UIPClient uip_closed")); - UIPClient::_dumpAllData(); -#endif - uip_conn->appstate = NULL; - goto finish; - } - if (uip_acked()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient uip_acked")); -#endif - UIPClient::_eatBlock(&u->packets_out[0]); - } - if (uip_poll() || uip_rexmit()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - //Serial.println(F("UIPClient uip_poll")); -#endif - if (u->packets_out[0] != NOBLOCK) - { - if (u->packets_out[1] == NOBLOCK) - { - send_len = u->out_pos; - if (send_len > 0) - { - Enc28J60Network::resizeBlock(u->packets_out[0],0,send_len); - } - } - else - send_len = Enc28J60Network::blockSize(u->packets_out[0]); - if (send_len > 0) - { - UIPEthernetClass::uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; - UIPEthernetClass::uip_packet = Enc28J60Network::allocBlock(UIPEthernetClass::uip_hdrlen+send_len); - if (UIPEthernetClass::uip_packet != NOBLOCK) - { - Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen,u->packets_out[0],0,send_len); - UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET; - } - } - goto finish; - } - } - // don't close connection unless all outgoing packets are sent - if (u->state & UIP_CLIENT_CLOSE) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient state UIP_CLIENT_CLOSE")); - UIPClient::_dumpAllData(); -#endif - if (u->packets_out[0] == NOBLOCK) - { - u->state = 0; - uip_conn->appstate = NULL; - uip_close(); -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("no blocks out -> free userdata")); - UIPClient::_dumpAllData(); -#endif - } - else - { - uip_stop(); -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("blocks outstanding transfer -> uip_stop()")); -#endif - } - } - } - finish: - uip_send(uip_appdata,send_len); - uip_len = send_len; -} - -uip_userdata_t * -UIPClient::_allocateData() -{ - for ( uint8_t sock = 0; sock < UIP_CONNS; sock++ ) - { - uip_userdata_t* data = &UIPClient::all_data[sock]; - if (!data->state) - { - data->state = sock | UIP_CLIENT_CONNECTED; - memset(&data->packets_in[0],0,sizeof(uip_userdata_t)-sizeof(data->state)); - return data; - } - } - return NULL; -} - -uint8_t -UIPClient::_currentBlock(memhandle* block) -{ - for (uint8_t i = 1; i < UIP_SOCKET_NUMPACKETS; i++) - { - if (block[i] == NOBLOCK) - return i-1; - } - return UIP_SOCKET_NUMPACKETS-1; -} - -void -UIPClient::_eatBlock(memhandle* block) -{ -#ifdef UIPETHERNET_DEBUG_CLIENT - memhandle* start = block; - Serial.print(F("eatblock(")); - Serial.print(*block); - Serial.print(F("): ")); - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) - { - Serial.print(start[i]); - Serial.print(F(" ")); - } - Serial.print(F("-> ")); -#endif - Enc28J60Network::freeBlock(block[0]); - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS-1; i++) - { - block[i] = block[i+1]; - } - block[UIP_SOCKET_NUMPACKETS-1] = NOBLOCK; -#ifdef UIPETHERNET_DEBUG_CLIENT - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) - { - Serial.print(start[i]); - Serial.print(F(" ")); - } - Serial.println(); -#endif -} - -void -UIPClient::_flushBlocks(memhandle* block) -{ - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) - { - Enc28J60Network::freeBlock(block[i]); - block[i] = NOBLOCK; - } -} - -#ifdef UIPETHERNET_DEBUG_CLIENT -void -UIPClient::_dumpAllData() { - for (uint8_t i=0; i < UIP_CONNS; i++) - { - Serial.print(F("UIPClient::all_data[")); - Serial.print(i); - Serial.print(F("], state:")); - Serial.println(all_data[i].state, BIN); - Serial.print(F("packets_in: ")); - for (uint8_t j=0; j < UIP_SOCKET_NUMPACKETS; j++) - { - Serial.print(all_data[i].packets_in[j]); - Serial.print(F(" ")); - } - Serial.println(); - if (all_data[i].state & UIP_CLIENT_REMOTECLOSED) - { - Serial.print(F("state remote closed, local port: ")); - Serial.println(htons(((uip_userdata_closed_t *)(&all_data[i]))->lport)); - } - else - { - Serial.print(F("packets_out: ")); - for (uint8_t j=0; j < UIP_SOCKET_NUMPACKETS; j++) - { - Serial.print(all_data[i].packets_out[j]); - Serial.print(F(" ")); - } - Serial.println(); - Serial.print(F("out_pos: ")); - Serial.println(all_data[i].out_pos); - } - } -} -#endif diff --git a/libraries/UIPEthernet_/UIPClient.h b/libraries/UIPEthernet_/UIPClient.h deleted file mode 100644 index 40838bb..0000000 --- a/libraries/UIPEthernet_/UIPClient.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - UIPClient.h - Arduino implementation of a uIP wrapper class. - 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 UIPCLIENT_H -#define UIPCLIENT_H - -#include "ethernet_comp.h" -#include "Print.h" -#include "Client.h" -#include "utility/mempool.h" - -extern "C" { - #include "utility/uip.h" -} - -#define UIP_SOCKET_DATALEN UIP_TCP_MSS -//#define UIP_SOCKET_NUMPACKETS UIP_RECEIVE_WINDOW/UIP_TCP_MSS+1 -#ifndef UIP_SOCKET_NUMPACKETS -#define UIP_SOCKET_NUMPACKETS 5 -#endif - -#define UIP_CLIENT_CONNECTED 0x10 -#define UIP_CLIENT_CLOSE 0x20 -#define UIP_CLIENT_REMOTECLOSED 0x40 -#define UIP_CLIENT_RESTART 0x80 -#define UIP_CLIENT_STATEFLAGS (UIP_CLIENT_CONNECTED | UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED | UIP_CLIENT_RESTART) -#define UIP_CLIENT_SOCKETS ~UIP_CLIENT_STATEFLAGS - -typedef uint8_t uip_socket_ptr; - -typedef struct { - uint8_t state; - memhandle packets_in[UIP_SOCKET_NUMPACKETS]; - uint16_t lport; /**< The local TCP port, in network byte order. */ -} uip_userdata_closed_t; - -typedef struct { - uint8_t state; - memhandle packets_in[UIP_SOCKET_NUMPACKETS]; - memhandle packets_out[UIP_SOCKET_NUMPACKETS]; - memaddress out_pos; -#if UIP_CLIENT_TIMER >= 0 - unsigned long timer; -#endif -} uip_userdata_t; - -class UIPClient : public Client { - -public: - UIPClient(); - int connect(IPAddress ip, uint16_t port); - int connect(const char *host, uint16_t port); - int read(uint8_t *buf, size_t size); - void stop(); - uint8_t connected(); - operator bool(); - virtual bool operator==(const EthernetClient&); - virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }; - - size_t write(uint8_t); - size_t write(const uint8_t *buf, size_t size); - int available(); - int read(); - int peek(); - void flush(); - - using Print::write; - -private: - UIPClient(struct uip_conn *_conn); - UIPClient(uip_userdata_t* conn_data); - - uip_userdata_t* data; - - static uip_userdata_t all_data[UIP_CONNS]; - static uip_userdata_t* _allocateData(); - - static size_t _write(uip_userdata_t *,const uint8_t *buf, size_t size); - static int _available(uip_userdata_t *); - - static uint8_t _currentBlock(memhandle* blocks); - static void _eatBlock(memhandle* blocks); - static void _flushBlocks(memhandle* blocks); - -#ifdef UIPETHERNET_DEBUG_CLIENT - static void _dumpAllData(); -#endif - - friend class UIPEthernetClass; - friend class UIPServer; - - friend void uipclient_appcall(void); - -}; - -#endif diff --git a/libraries/UIPEthernet_/UIPEthernet.cpp b/libraries/UIPEthernet_/UIPEthernet.cpp deleted file mode 100644 index 91ec70a..0000000 --- a/libraries/UIPEthernet_/UIPEthernet.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* - UIPEthernet.cpp - Arduino implementation of a uIP wrapper class. - 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 -#include "UIPEthernet.h" -#include "utility/Enc28J60Network.h" - -#if(defined UIPETHERNET_DEBUG || defined UIPETHERNET_DEBUG_CHKSUM) -#include "HardwareSerial.h" -#endif - -#include "UIPUdp.h" - -extern "C" -{ -#include "utility/uip-conf.h" -#include "utility/uip.h" -#include "utility/uip_arp.h" -#include "utility/uip_timer.h" -} - -#define ETH_HDR ((struct uip_eth_hdr *)&uip_buf[0]) - -memhandle UIPEthernetClass::in_packet(NOBLOCK); -memhandle UIPEthernetClass::uip_packet(NOBLOCK); -uint8_t UIPEthernetClass::uip_hdrlen(0); -uint8_t UIPEthernetClass::packetstate(0); - -IPAddress UIPEthernetClass::_dnsServerAddress; -DhcpClass* UIPEthernetClass::_dhcp(NULL); - -unsigned long UIPEthernetClass::periodic_timer; - -// Because uIP isn't encapsulated within a class we have to use global -// variables, so we can only have one TCP/IP stack per program. - -UIPEthernetClass::UIPEthernetClass() -{ -} - -#if UIP_UDP -int -UIPEthernetClass::begin(const uint8_t* mac) -{ - static DhcpClass s_dhcp; - _dhcp = &s_dhcp; - - // Initialise the basic info - init(mac); - - // Now try to get our config info from a DHCP server - int ret = _dhcp->beginWithDHCP((uint8_t*)mac); - if(ret == 1) - { - // We've successfully found a DHCP server and got our configuration info, so set things - // accordingly - configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask()); - } - return ret; -} -#endif - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip) -{ - IPAddress dns = ip; - dns[3] = 1; - begin(mac, ip, dns); -} - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns) -{ - IPAddress gateway = ip; - gateway[3] = 1; - begin(mac, ip, dns, gateway); -} - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway) -{ - IPAddress subnet(255, 255, 255, 0); - begin(mac, ip, dns, gateway, subnet); -} - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) -{ - init(mac); - configure(ip,dns,gateway,subnet); -} - -int UIPEthernetClass::maintain(){ - tick(); - int rc = DHCP_CHECK_NONE; -#if UIP_UDP - if(_dhcp != NULL){ - //we have a pointer to dhcp, use it - rc = _dhcp->checkLease(); - switch ( rc ){ - case DHCP_CHECK_NONE: - //nothing done - break; - case DHCP_CHECK_RENEW_OK: - case DHCP_CHECK_REBIND_OK: - //we might have got a new IP. - configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask()); - break; - default: - //this is actually a error, it will retry though - break; - } - } - return rc; -#endif -} - -IPAddress UIPEthernetClass::localIP() -{ - IPAddress ret; - uip_ipaddr_t a; - uip_gethostaddr(a); - return ip_addr_uip(a); -} - -IPAddress UIPEthernetClass::subnetMask() -{ - IPAddress ret; - uip_ipaddr_t a; - uip_getnetmask(a); - return ip_addr_uip(a); -} - -IPAddress UIPEthernetClass::gatewayIP() -{ - IPAddress ret; - uip_ipaddr_t a; - uip_getdraddr(a); - return ip_addr_uip(a); -} - -IPAddress UIPEthernetClass::dnsServerIP() -{ - return _dnsServerAddress; -} - -void -UIPEthernetClass::tick() -{ - if (in_packet == NOBLOCK) - { - in_packet = Enc28J60Network::receivePacket(); -#ifdef UIPETHERNET_DEBUG - if (in_packet != NOBLOCK) - { - Serial.print(F("--------------\nreceivePacket: ")); - Serial.println(in_packet); - } -#endif - } - if (in_packet != NOBLOCK) - { - packetstate = UIPETHERNET_FREEPACKET; - uip_len = Enc28J60Network::blockSize(in_packet); - if (uip_len > 0) - { - Enc28J60Network::readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE); - if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_IP)) - { - uip_packet = in_packet; //required for upper_layer_checksum of in_packet! -#ifdef UIPETHERNET_DEBUG - Serial.print(F("readPacket type IP, uip_len: ")); - Serial.println(uip_len); -#endif - uip_arp_ipin(); - uip_input(); - if (uip_len > 0) - { - uip_arp_out(); - network_send(); - } - } - else if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_ARP)) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("readPacket type ARP, uip_len: ")); - Serial.println(uip_len); -#endif - uip_arp_arpin(); - if (uip_len > 0) - { - network_send(); - } - } - } - if (in_packet != NOBLOCK && (packetstate & UIPETHERNET_FREEPACKET)) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("freeing packet: ")); - Serial.println(in_packet); -#endif - Enc28J60Network::freePacket(); - in_packet = NOBLOCK; - } - } - - unsigned long now = millis(); - -#if UIP_CLIENT_TIMER >= 0 - boolean periodic = (long)( now - periodic_timer ) >= 0; - for (int i = 0; i < UIP_CONNS; i++) - { -#else - if ((long)( now - periodic_timer ) >= 0) - { - periodic_timer = now + UIP_PERIODIC_TIMER; - - for (int i = 0; i < UIP_CONNS; i++) - { -#endif - uip_conn = &uip_conns[i]; -#if UIP_CLIENT_TIMER >= 0 - if (periodic) - { -#endif - uip_process(UIP_TIMER); -#if UIP_CLIENT_TIMER >= 0 - } - else - { - if ((long)( now - ((uip_userdata_t*)uip_conn->appstate)->timer) >= 0) - uip_process(UIP_POLL_REQUEST); - else - continue; - } -#endif - // If the above function invocation resulted in data that - // should be sent out on the Enc28J60Network, the global variable - // uip_len is set to a value > 0. - if (uip_len > 0) - { - uip_arp_out(); - network_send(); - } - } -#if UIP_CLIENT_TIMER >= 0 - if (periodic) - { - periodic_timer = now + UIP_PERIODIC_TIMER; -#endif -#if UIP_UDP - for (int i = 0; i < UIP_UDP_CONNS; i++) - { - uip_udp_periodic(i); - // If the above function invocation resulted in data that - // should be sent out on the Enc28J60Network, the global variable - // uip_len is set to a value > 0. */ - if (uip_len > 0) - { - UIPUDP::_send((uip_udp_userdata_t *)(uip_udp_conns[i].appstate)); - } - } -#endif /* UIP_UDP */ - } -} - -boolean UIPEthernetClass::network_send() -{ - if (packetstate & UIPETHERNET_SENDPACKET) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("Enc28J60Network_send uip_packet: ")); - Serial.print(uip_packet); - Serial.print(F(", hdrlen: ")); - Serial.println(uip_hdrlen); -#endif - Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_hdrlen); - packetstate &= ~ UIPETHERNET_SENDPACKET; - goto sendandfree; - } - uip_packet = Enc28J60Network::allocBlock(uip_len); - if (uip_packet != NOBLOCK) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("Enc28J60Network_send uip_buf (uip_len): ")); - Serial.print(uip_len); - Serial.print(F(", packet: ")); - Serial.println(uip_packet); -#endif - Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_len); - goto sendandfree; - } - return false; -sendandfree: - Enc28J60Network::sendPacket(uip_packet); - Enc28J60Network::freeBlock(uip_packet); - uip_packet = NOBLOCK; - return true; -} - -void UIPEthernetClass::init(const uint8_t* mac) { - periodic_timer = millis() + UIP_PERIODIC_TIMER; - - Enc28J60Network::init((uint8_t*)mac); - uip_seteth_addr(mac); - - uip_init(); - uip_arp_init(); -} - -void UIPEthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) { - uip_ipaddr_t ipaddr; - - uip_ip_addr(ipaddr, ip); - uip_sethostaddr(ipaddr); - - uip_ip_addr(ipaddr, gateway); - uip_setdraddr(ipaddr); - - uip_ip_addr(ipaddr, subnet); - uip_setnetmask(ipaddr); - - _dnsServerAddress = dns; -} - -UIPEthernetClass UIPEthernet; - -/*---------------------------------------------------------------------------*/ -uint16_t -UIPEthernetClass::chksum(uint16_t sum, const uint8_t *data, uint16_t len) -{ - uint16_t t; - const uint8_t *dataptr; - const uint8_t *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while(dataptr < last_byte) { /* At least two more bytes */ - t = (dataptr[0] << 8) + dataptr[1]; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - dataptr += 2; - } - - if(dataptr == last_byte) { - t = (dataptr[0] << 8) + 0; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - - /* Return sum in host byte order. */ - return sum; -} - -/*---------------------------------------------------------------------------*/ - -uint16_t -UIPEthernetClass::ipchksum(void) -{ - uint16_t sum; - - sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); - return (sum == 0) ? 0xffff : htons(sum); -} - -/*---------------------------------------------------------------------------*/ -uint16_t -#if UIP_UDP -UIPEthernetClass::upper_layer_chksum(uint8_t proto) -#else -uip_tcpchksum(void) -#endif -{ - uint16_t upper_layer_len; - uint16_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. */ -#if UIP_UDP - sum = upper_layer_len + proto; -#else - sum = upper_layer_len + UIP_PROTO_TCP; -#endif - /* Sum IP source and destination addresses. */ - sum = UIPEthernetClass::chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); - - uint8_t upper_layer_memlen; -#if UIP_UDP - switch(proto) - { -// case UIP_PROTO_ICMP: -// case UIP_PROTO_ICMP6: -// upper_layer_memlen = upper_layer_len; -// break; - case UIP_PROTO_UDP: - upper_layer_memlen = UIP_UDPH_LEN; - break; - default: -// case UIP_PROTO_TCP: -#endif - upper_layer_memlen = (BUF->tcpoffset >> 4) << 2; -#if UIP_UDP - break; - } -#endif - sum = UIPEthernetClass::chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen); -#ifdef UIPETHERNET_DEBUG_CHKSUM - Serial.print(F("chksum uip_buf[")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN); - Serial.print(F("-")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen); - Serial.print(F("]: ")); - Serial.println(htons(sum),HEX); -#endif - if (upper_layer_memlen < upper_layer_len) - { - sum = Enc28J60Network::chksum( - sum, - UIPEthernetClass::uip_packet, - UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen, - upper_layer_len - upper_layer_memlen - ); -#ifdef UIPETHERNET_DEBUG_CHKSUM - Serial.print(F("chksum uip_packet(")); - Serial.print(uip_packet); - Serial.print(F(")[")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen); - Serial.print(F("-")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_len); - Serial.print(F("]: ")); - Serial.println(htons(sum),HEX); -#endif - } - return (sum == 0) ? 0xffff : htons(sum); -} - -uint16_t -uip_ipchksum(void) -{ - return UIPEthernet.ipchksum(); -} - -#if UIP_UDP -uint16_t -uip_tcpchksum(void) -{ - uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_TCP); - return sum; -} - -uint16_t -uip_udpchksum(void) -{ - uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_UDP); - return sum; -} -#endif diff --git a/libraries/UIPEthernet_/UIPEthernet.h b/libraries/UIPEthernet_/UIPEthernet.h deleted file mode 100644 index dd3f412..0000000 --- a/libraries/UIPEthernet_/UIPEthernet.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - UIPEthernet.h - Arduino implementation of a uIP wrapper class. - 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 UIPETHERNET_H -#define UIPETHERNET_H - -//#define UIPETHERNET_DEBUG -//#define UIPETHERNET_DEBUG_CHKSUM -//#define UIPETHERNET_DEBUG_UDP -//#define UIPETHERNET_DEBUG_CLIENT - -#include "ethernet_comp.h" -#include -#include "Dhcp.h" -#include "IPAddress.h" -#include "utility/Enc28J60Network.h" -#include "UIPClient.h" -#include "UIPServer.h" -#include "UIPUdp.h" - -extern "C" -{ -#include "utility/uip_timer.h" -#include "utility/uip.h" -} - -#define UIPETHERNET_FREEPACKET 1 -#define UIPETHERNET_SENDPACKET 2 -#define UIPETHERNET_BUFFERREAD 4 - -#define uip_ip_addr(addr, ip) do { \ - ((u16_t *)(addr))[0] = HTONS(((ip[0]) << 8) | (ip[1])); \ - ((u16_t *)(addr))[1] = HTONS(((ip[2]) << 8) | (ip[3])); \ - } while(0) - -#define ip_addr_uip(a) IPAddress(a[0] & 0xFF, a[0] >> 8 , a[1] & 0xFF, a[1] >> 8) //TODO this is not IPV6 capable - -#define uip_seteth_addr(eaddr) do {uip_ethaddr.addr[0] = eaddr[0]; \ - uip_ethaddr.addr[1] = eaddr[1];\ - uip_ethaddr.addr[2] = eaddr[2];\ - uip_ethaddr.addr[3] = eaddr[3];\ - uip_ethaddr.addr[4] = eaddr[4];\ - uip_ethaddr.addr[5] = eaddr[5];} while(0) - -#undef BUF -#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) - -class UIPEthernetClass -{ -public: - UIPEthernetClass(); - - int begin(const uint8_t* mac); - void begin(const uint8_t* mac, IPAddress ip); - void begin(const uint8_t* mac, IPAddress ip, IPAddress dns); - void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway); - void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - - // maintain() must be called at regular intervals to process the incoming serial - // data and issue IP events to the sketch. It does not return until all IP - // events have been processed. Renews dhcp-lease if required. - int maintain(); - - IPAddress localIP(); - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsServerIP(); - -private: - static memhandle in_packet; - static memhandle uip_packet; - static uint8_t uip_hdrlen; - static uint8_t packetstate; - - static IPAddress _dnsServerAddress; - static DhcpClass* _dhcp; - - static unsigned long periodic_timer; - - static void init(const uint8_t* mac); - static void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - - static void tick(); - - static boolean network_send(); - - friend class UIPServer; - - friend class UIPClient; - - friend class UIPUDP; - - static uint16_t chksum(uint16_t sum, const uint8_t* data, uint16_t len); - static uint16_t ipchksum(void); -#if UIP_UDP - static uint16_t upper_layer_chksum(uint8_t proto); -#endif - friend uint16_t uip_ipchksum(void); - friend uint16_t uip_tcpchksum(void); - friend uint16_t uip_udpchksum(void); - - friend void uipclient_appcall(void); - friend void uipudp_appcall(void); - -#if UIP_CONF_IPV6 - uint16_t uip_icmp6chksum(void); -#endif /* UIP_CONF_IPV6 */ -}; - -extern UIPEthernetClass UIPEthernet; - -#endif diff --git a/libraries/UIPEthernet_/UIPServer.cpp b/libraries/UIPEthernet_/UIPServer.cpp deleted file mode 100644 index 21c7ef5..0000000 --- a/libraries/UIPEthernet_/UIPServer.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - UIPServer.cpp - Arduino implementation of a uIP wrapper class. - 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 "UIPEthernet.h" -#include "UIPServer.h" -extern "C" { - #include "utility/uip-conf.h" -} - -UIPServer::UIPServer(uint16_t port) : _port(htons(port)) -{ -} - -UIPClient UIPServer::available() -{ - UIPEthernetClass::tick(); - for ( uip_userdata_t* data = &UIPClient::all_data[0]; data < &UIPClient::all_data[UIP_CONNS]; data++ ) - { - if (data->packets_in[0] != NOBLOCK - && (((data->state & UIP_CLIENT_CONNECTED) && uip_conns[data->state & UIP_CLIENT_SOCKETS].lport ==_port) - || ((data->state & UIP_CLIENT_REMOTECLOSED) && ((uip_userdata_closed_t *)data)->lport == _port))) - return UIPClient(data); - } - return UIPClient(); -} - -void UIPServer::begin() -{ - uip_listen(_port); - UIPEthernetClass::tick(); -} - -size_t UIPServer::write(uint8_t c) -{ - return write(&c,1); -} - -size_t UIPServer::write(const uint8_t *buf, size_t size) -{ - size_t ret = 0; - for ( uip_userdata_t* data = &UIPClient::all_data[0]; data < &UIPClient::all_data[UIP_CONNS]; data++ ) - { - if ((data->state & UIP_CLIENT_CONNECTED) && uip_conns[data->state & UIP_CLIENT_SOCKETS].lport ==_port) - ret += UIPClient::_write(data,buf,size); - } - return ret; -} - diff --git a/libraries/UIPEthernet_/UIPServer.h b/libraries/UIPEthernet_/UIPServer.h deleted file mode 100644 index eea81d2..0000000 --- a/libraries/UIPEthernet_/UIPServer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - UIPServer.h - Arduino implementation of a uIP wrapper class. - 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 UIPSERVER_H -#define UIPSERVER_H - -#include "ethernet_comp.h" -#include "Server.h" -#include "UIPClient.h" - -class UIPServer : public Server { - -public: - UIPServer(uint16_t); - UIPClient available(); - void begin(); - size_t write(uint8_t); - size_t write(const uint8_t *buf, size_t size); - using Print::write; - -private: - uint16_t _port; -}; - -#endif diff --git a/libraries/UIPEthernet_/UIPUdp.cpp b/libraries/UIPEthernet_/UIPUdp.cpp deleted file mode 100644 index 3deb2c4..0000000 --- a/libraries/UIPEthernet_/UIPUdp.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/* - UIPUdp.cpp - Arduino implementation of a uIP wrapper class. - 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 "UIPEthernet.h" -#include "UIPUdp.h" -#include "Dns.h" - -#ifdef UIPETHERNET_DEBUG_UDP -#include "HardwareSerial.h" -#endif - -extern "C" { -#include "utility/uip-conf.h" -#include "utility/uip.h" -#include "utility/uip_arp.h" -} - -#if UIP_UDP -#define UIP_ARPHDRSIZE 42 -#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) - -// Constructor -UIPUDP::UIPUDP() : - _uip_udp_conn(NULL) -{ - memset(&appdata,0,sizeof(appdata)); -} - -// initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use -uint8_t -UIPUDP::begin(uint16_t port) -{ - if (!_uip_udp_conn) - { - _uip_udp_conn = uip_udp_new(NULL, 0); - } - if (_uip_udp_conn) - { - uip_udp_bind(_uip_udp_conn,htons(port)); - _uip_udp_conn->appstate = &appdata; - return 1; - } - return 0; -} - -// Finish with the UDP socket -void -UIPUDP::stop() -{ - if (_uip_udp_conn) - { - uip_udp_remove(_uip_udp_conn); - _uip_udp_conn->appstate = NULL; - _uip_udp_conn=NULL; - Enc28J60Network::freeBlock(appdata.packet_in); - Enc28J60Network::freeBlock(appdata.packet_next); - Enc28J60Network::freeBlock(appdata.packet_out); - memset(&appdata,0,sizeof(appdata)); - } -} - -// Sending UDP packets - -// Start building up a packet to send to the remote host specific in ip and port -// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port -int -UIPUDP::beginPacket(IPAddress ip, uint16_t port) -{ - UIPEthernetClass::tick(); - if (ip && port) - { - uip_ipaddr_t ripaddr; - uip_ip_addr(&ripaddr, ip); -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp beginPacket, ")); -#endif - if (_uip_udp_conn) - { - _uip_udp_conn->rport = htons(port); - uip_ipaddr_copy(_uip_udp_conn->ripaddr, &ripaddr); - } - else - { - _uip_udp_conn = uip_udp_new(&ripaddr,htons(port)); - if (_uip_udp_conn) - { -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("new connection, ")); -#endif - _uip_udp_conn->appstate = &appdata; - } - else - { -#ifdef UIPETHERNET_DEBUG_UDP - Serial.println(F("failed to allocate new connection")); -#endif - return 0; - } - } -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("rip: ")); - Serial.print(ip); - Serial.print(F(", port: ")); - Serial.println(port); -#endif - } - if (_uip_udp_conn) - { - if (appdata.packet_out == NOBLOCK) - { - appdata.packet_out = Enc28J60Network::allocBlock(UIP_UDP_MAXPACKETSIZE); - appdata.out_pos = UIP_UDP_PHYH_LEN; - if (appdata.packet_out != NOBLOCK) - return 1; -#ifdef UIPETHERNET_DEBUG_UDP - else - Serial.println(F("failed to allocate memory for packet")); -#endif - } -#ifdef UIPETHERNET_DEBUG_UDP - else - Serial.println(F("previous packet on that connection not sent yet")); -#endif - } - return 0; -} - -// Start building up a packet to send to the remote host specific in host and port -// Returns 1 if successful, 0 if there was a problem resolving the hostname or port -int -UIPUDP::beginPacket(const char *host, uint16_t port) -{ - // Look up the host first - int ret = 0; - DNSClient dns; - IPAddress remote_addr; - - dns.begin(UIPEthernet.dnsServerIP()); - ret = dns.getHostByName(host, remote_addr); - if (ret == 1) { - return beginPacket(remote_addr, port); - } else { - return ret; - } -} - -// Finish off this packet and send it -// Returns 1 if the packet was sent successfully, 0 if there was an error -int -UIPUDP::endPacket() -{ - if (_uip_udp_conn && appdata.packet_out != NOBLOCK) - { - appdata.send = true; - Enc28J60Network::resizeBlock(appdata.packet_out,0,appdata.out_pos); - uip_udp_periodic_conn(_uip_udp_conn); - if (uip_len > 0) - { - _send(&appdata); - return 1; - } - } - return 0; -} - -// Write a single byte into the packet -size_t -UIPUDP::write(uint8_t c) -{ - return write(&c,1); -} - -// Write size bytes from buffer into the packet -size_t -UIPUDP::write(const uint8_t *buffer, size_t size) -{ - if (appdata.packet_out != NOBLOCK) - { - size_t ret = Enc28J60Network::writePacket(appdata.packet_out,appdata.out_pos,(uint8_t*)buffer,size); - appdata.out_pos += ret; - return ret; - } - return 0; -} - -// Start processing the next available incoming packet -// Returns the size of the packet in bytes, or 0 if no packets are available -int -UIPUDP::parsePacket() -{ - UIPEthernetClass::tick(); -#ifdef UIPETHERNET_DEBUG_UDP - if (appdata.packet_in != NOBLOCK) - { - Serial.print(F("udp parsePacket freeing previous packet: ")); - Serial.println(appdata.packet_in); - } -#endif - Enc28J60Network::freeBlock(appdata.packet_in); - - appdata.packet_in = appdata.packet_next; - appdata.packet_next = NOBLOCK; - -#ifdef UIPETHERNET_DEBUG_UDP - if (appdata.packet_in != NOBLOCK) - { - Serial.print(F("udp parsePacket received packet: ")); - Serial.print(appdata.packet_in); - } -#endif - int size = Enc28J60Network::blockSize(appdata.packet_in); -#ifdef UIPETHERNET_DEBUG_UDP - if (appdata.packet_in != NOBLOCK) - { - Serial.print(F(", size: ")); - Serial.println(size); - } -#endif - return size; -} - -// Number of bytes remaining in the current packet -int -UIPUDP::available() -{ - UIPEthernetClass::tick(); - return Enc28J60Network::blockSize(appdata.packet_in); -} - -// Read a single byte from the current packet -int -UIPUDP::read() -{ - unsigned char c; - if (read(&c,1) > 0) - { - return c; - } - return -1; -} - -// Read up to len bytes from the current packet and place them into buffer -// Returns the number of bytes read, or 0 if none are available -int -UIPUDP::read(unsigned char* buffer, size_t len) -{ - UIPEthernetClass::tick(); - if (appdata.packet_in != NOBLOCK) - { - memaddress read = Enc28J60Network::readPacket(appdata.packet_in,0,buffer,len); - if (read == Enc28J60Network::blockSize(appdata.packet_in)) - { - Enc28J60Network::freeBlock(appdata.packet_in); - appdata.packet_in = NOBLOCK; - } - else - Enc28J60Network::resizeBlock(appdata.packet_in,read); - return read; - } - return 0; -} - -// Return the next byte from the current packet without moving on to the next byte -int -UIPUDP::peek() -{ - UIPEthernetClass::tick(); - if (appdata.packet_in != NOBLOCK) - { - unsigned char c; - if (Enc28J60Network::readPacket(appdata.packet_in,0,&c,1) == 1) - return c; - } - return -1; -} - -// Finish reading the current packet -void -UIPUDP::flush() -{ - UIPEthernetClass::tick(); - Enc28J60Network::freeBlock(appdata.packet_in); - appdata.packet_in = NOBLOCK; -} - -// Return the IP address of the host who sent the current incoming packet -IPAddress -UIPUDP::remoteIP() -{ - return _uip_udp_conn ? ip_addr_uip(_uip_udp_conn->ripaddr) : IPAddress(); -} - -// Return the port of the host who sent the current incoming packet -uint16_t -UIPUDP::remotePort() -{ - return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0; -} - -// uIP callback function - -void -uipudp_appcall(void) { - if (uip_udp_userdata_t *data = (uip_udp_userdata_t *)(uip_udp_conn->appstate)) - { - if (uip_newdata()) - { - if (data->packet_next == NOBLOCK) - { - uip_udp_conn->rport = UDPBUF->srcport; - uip_ipaddr_copy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr); - data->packet_next = Enc28J60Network::allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN); - //if we are unable to allocate memory the packet is dropped. udp doesn't guarantee packet delivery - if (data->packet_next != NOBLOCK) - { - //discard Linklevel and IP and udp-header and any trailing bytes: - Enc28J60Network::copyPacket(data->packet_next,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next)); - #ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_newdata received packet: ")); - Serial.print(data->packet_next); - Serial.print(F(", size: ")); - Serial.println(Enc28J60Network::blockSize(data->packet_next)); - #endif - } - } - } - if (uip_poll() && data->send) - { - //set uip_slen (uip private) by calling uip_udp_send -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_poll preparing packet to send: ")); - Serial.print(data->packet_out); - Serial.print(F(", size: ")); - Serial.println(Enc28J60Network::blockSize(data->packet_out)); -#endif - UIPEthernetClass::uip_packet = data->packet_out; - UIPEthernetClass::uip_hdrlen = UIP_UDP_PHYH_LEN; - uip_udp_send(data->out_pos - (UIP_UDP_PHYH_LEN)); - } - } -} - -void -UIPUDP::_send(uip_udp_userdata_t *data) { - uip_arp_out(); //add arp - if (uip_len == UIP_ARPHDRSIZE) - { - UIPEthernetClass::uip_packet = NOBLOCK; - UIPEthernetClass::packetstate &= ~UIPETHERNET_SENDPACKET; -#ifdef UIPETHERNET_DEBUG_UDP - Serial.println(F("udp, uip_poll results in ARP-packet")); -#endif - } - else - //arp found ethaddr for ip (otherwise packet is replaced by arp-request) - { - data->send = false; - data->packet_out = NOBLOCK; - UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET; -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_packet to send: ")); - Serial.println(UIPEthernetClass::uip_packet); -#endif - } - UIPEthernetClass::network_send(); -} -#endif diff --git a/libraries/UIPEthernet_/UIPUdp.h b/libraries/UIPEthernet_/UIPUdp.h deleted file mode 100644 index b007a3c..0000000 --- a/libraries/UIPEthernet_/UIPUdp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - UIPUdp.h - Arduino implementation of a uIP wrapper class. - 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 UIPUDP_H -#define UIPUDP_H - -#include "ethernet_comp.h" -#include "Arduino.h" -#include -#include "utility/mempool.h" -extern "C" { - #include "utility/uip.h" -} - -#define UIP_UDP_MAXDATALEN 1500 -#define UIP_UDP_PHYH_LEN UIP_LLH_LEN+UIP_IPUDPH_LEN -#define UIP_UDP_MAXPACKETSIZE UIP_UDP_MAXDATALEN+UIP_UDP_PHYH_LEN - -typedef struct { - memaddress out_pos; - memhandle packet_next; - memhandle packet_in; - memhandle packet_out; - boolean send; -} uip_udp_userdata_t; - -class UIPUDP : public UDP -{ - -private: - struct uip_udp_conn *_uip_udp_conn; - - uip_udp_userdata_t appdata; - -public: - UIPUDP(); // Constructor - uint8_t - begin(uint16_t);// initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use - void - stop(); // Finish with the UDP socket - - // Sending UDP packets - - // Start building up a packet to send to the remote host specific in ip and port - // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port - int - beginPacket(IPAddress ip, uint16_t port); - // Start building up a packet to send to the remote host specific in host and port - // Returns 1 if successful, 0 if there was a problem resolving the hostname or port - int - beginPacket(const char *host, uint16_t port); - // Finish off this packet and send it - // Returns 1 if the packet was sent successfully, 0 if there was an error - int - endPacket(); - // Write a single byte into the packet - size_t - write(uint8_t); - // Write size bytes from buffer into the packet - size_t - write(const uint8_t *buffer, size_t size); - - using Print::write; - - // Start processing the next available incoming packet - // Returns the size of the packet in bytes, or 0 if no packets are available - int - parsePacket(); - // Number of bytes remaining in the current packet - int - available(); - // Read a single byte from the current packet - int - read(); - // Read up to len bytes from the current packet and place them into buffer - // Returns the number of bytes read, or 0 if none are available - int - read(unsigned char* buffer, size_t len); - // Read up to len characters from the current packet and place them into buffer - // Returns the number of characters read, or 0 if none are available - int - read(char* buffer, size_t len) - { - return read((unsigned char*) buffer, len); - } - ; - // Return the next byte from the current packet without moving on to the next byte - int - peek(); - void - flush(); // Finish reading the current packet - - // Return the IP address of the host who sent the current incoming packet - IPAddress - remoteIP(); - - // Return the port of the host who sent the current incoming packet - uint16_t - remotePort(); - -private: - - friend void uipudp_appcall(void); - - friend class UIPEthernetClass; - static void _send(uip_udp_userdata_t *data); - -}; - -#endif diff --git a/libraries/UIPEthernet_/ethernet_comp.h b/libraries/UIPEthernet_/ethernet_comp.h deleted file mode 100644 index 4cec2ab..0000000 --- a/libraries/UIPEthernet_/ethernet_comp.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef ETHERNET_COMP_H -#define ETHERNET_COMP_H - -#define Ethernet UIPEthernet -#define EthernetClient UIPClient -#define EthernetServer UIPServer -#define EthernetUDP UIPUDP - -#endif diff --git a/libraries/UIPEthernet_/examples/AdvancedChatServer/AdvancedChatServer.ino b/libraries/UIPEthernet_/examples/AdvancedChatServer/AdvancedChatServer.ino deleted file mode 100644 index 7b3b132..0000000 --- a/libraries/UIPEthernet_/examples/AdvancedChatServer/AdvancedChatServer.ino +++ /dev/null @@ -1,105 +0,0 @@ -/* - Advanced Chat Server - - A simple server that distributes any incoming messages to all - connected clients but the client the message comes from. - To use telnet to your device's IP address and type. - You can see the client's input in the serial monitor as well. - Using an Arduino Wiznet Ethernet shield. - - Circuit: - * Ethernet shield attached to pins 10, 11, 12, 13 - * Analog inputs attached to pins A0 through A5 (optional) - - created 18 Dec 2009 - by David A. Mellis - modified 9 Apr 2012 - by Tom Igoe - redesigned to make use of operator== 25 Nov 2013 - by Norbert Truchsess - - */ - -#include -#include - -// Enter a MAC address and IP address for your controller below. -// The IP address will be dependent on your local network. - -byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; -IPAddress ip(192,168,0,6); - -// telnet defaults to port 23 -EthernetServer server(23); - -EthernetClient clients[4]; - -void setup() { - // initialize the ethernet device - Ethernet.begin(mac, ip); - // start listening for clients - server.begin(); - // Open serial communications and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } - - - Serial.print("Chat server address:"); - Serial.println(Ethernet.localIP()); -} - -void loop() { - // wait for a new client: - EthernetClient client = server.available(); - - if (client) { - - boolean newClient = true; - for (byte i=0;i<4;i++) { - //check whether this client refers to the same socket as one of the existing instances: - if (clients[i]==client) { - newClient = false; - break; - } - } - - if (newClient) { - //check which of the existing clients can be overridden: - for (byte i=0;i<4;i++) { - if (!clients[i] && clients[i]!=client) { - clients[i] = client; - // clead out the input buffer: - client.flush(); - // clead out the input buffer: - client.flush(); - Serial.println("We have a new client"); - client.println("Hello, client!"); - client.print("my IP: "); - client.println(Ethernet.localIP()); - break; - } - } - } - - if (client.available() > 0) { - // read the bytes incoming from the client: - char thisChar = client.read(); - // echo the bytes back to all other connected clients: - for (byte i=0;i<4;i++) { - if (clients[i] && clients[i]!=client) { - clients[i].write(thisChar); - } - } - // echo the bytes to the server as well: - Serial.write(thisChar); - } - } - for (byte i=0;i<4;i++) { - if (!(clients[i].connected())) { - // client.stop() invalidates the internal socket-descriptor, so next use of == will allways return false; - clients[i].stop(); - } - } -} diff --git a/libraries/UIPEthernet_/examples/EchoServer/EchoServer.ino b/libraries/UIPEthernet_/examples/EchoServer/EchoServer.ino deleted file mode 100644 index 8603001..0000000 --- a/libraries/UIPEthernet_/examples/EchoServer/EchoServer.ino +++ /dev/null @@ -1,59 +0,0 @@ -/* - * UIPEthernet EchoServer example. - * - * UIPEthernet is a TCP/IP stack that can be used with a enc28j60 based - * Ethernet-shield. - * - * UIPEthernet uses the fine uIP stack by Adam Dunkels - * - * ----------------- - * - * This Hello World example sets up a server at 192.168.1.6 on port 1000. - * Telnet here to access the service. The uIP stack will also respond to - * pings to test if you have successfully established a TCP connection to - * the Arduino. - * - * This example was based upon uIP hello-world by Adam Dunkels - * Ported to the Arduino IDE by Adam Nielsen - * Adaption to Enc28J60 by Norbert Truchsess - */ - -#include -#include -// The connection_data struct needs to be defined in an external file. -#include -#include - -EthernetServer server = EthernetServer(1000); - -void setup() -{ - Serial.begin(9600); - - uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; - IPAddress myIP(192,168,0,6); - - Ethernet.begin(mac,myIP); - - server.begin(); -} - -void loop() -{ - size_t size; - - if (EthernetClient client = server.available()) - { - if (client) - { - while((size = client.available()) > 0) - { - uint8_t* msg = (uint8_t*)malloc(size); - size = client.read(msg,size); - Serial.write(msg,size); - client.write(msg,size); - free(msg); - } - } - } -} diff --git a/libraries/UIPEthernet_/examples/TcpClient/TcpClient.ino b/libraries/UIPEthernet_/examples/TcpClient/TcpClient.ino deleted file mode 100644 index 444b36a..0000000 --- a/libraries/UIPEthernet_/examples/TcpClient/TcpClient.ino +++ /dev/null @@ -1,77 +0,0 @@ -/* - * UIPEthernet TcpClient example. - * - * UIPEthernet is a TCP/IP stack that can be used with a enc28j60 based - * Ethernet-shield. - * - * UIPEthernet uses the fine uIP stack by Adam Dunkels - * - * ----------------- - * - * This TcpClient example gets its local ip-address via dhcp and sets - * up a tcp socket-connection to 192.168.0.1 port 5000 every 5 Seconds. - * After sending a message it waits for a response. After receiving the - * response the client disconnects and tries to reconnect after 5 seconds. - * - * Copyright (C) 2013 by Norbert Truchsess - */ - -#include -#include - -EthernetClient client; -signed long next; - -void setup() { - - Serial.begin(9600); - - uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; - Ethernet.begin(mac); - - Serial.print("localIP: "); - Serial.println(Ethernet.localIP()); - Serial.print("subnetMask: "); - Serial.println(Ethernet.subnetMask()); - Serial.print("gatewayIP: "); - Serial.println(Ethernet.gatewayIP()); - Serial.print("dnsServerIP: "); - Serial.println(Ethernet.dnsServerIP()); - - next = 0; -} - -void loop() { - - if (((signed long)(millis() - next)) > 0) - { - next = millis() + 5000; - Serial.println("Client connect"); - // replace hostname with name of machine running tcpserver.pl -// if (client.connect("server.local",5000)) - if (client.connect(IPAddress(192,168,0,1),5000)) - { - Serial.println("Client connected"); - client.println("DATA from Client"); - while(client.available()==0) - { - if (next - millis() < 0) - goto close; - } - int size; - while((size = client.available()) > 0) - { - uint8_t* msg = (uint8_t*)malloc(size); - size = client.read(msg,size); - Serial.write(msg,size); - free(msg); - } -close: - //disconnect client - Serial.println("Client disconnect"); - client.stop(); - } - else - Serial.println("Client connect failed"); - } -} diff --git a/libraries/UIPEthernet_/examples/TcpServer/TcpServer.ino b/libraries/UIPEthernet_/examples/TcpServer/TcpServer.ino deleted file mode 100644 index b8a1e6d..0000000 --- a/libraries/UIPEthernet_/examples/TcpServer/TcpServer.ino +++ /dev/null @@ -1,54 +0,0 @@ -/* - * UIPEthernet EchoServer example. - * - * UIPEthernet is a TCP/IP stack that can be used with a enc28j60 based - * Ethernet-shield. - * - * UIPEthernet uses the fine uIP stack by Adam Dunkels - * - * ----------------- - * - * This Hello World example sets up a server at 192.168.1.6 on port 1000. - * Telnet here to access the service. The uIP stack will also respond to - * pings to test if you have successfully established a TCP connection to - * the Arduino. - * - * This example was based upon uIP hello-world by Adam Dunkels - * Ported to the Arduino IDE by Adam Nielsen - * Adaption to Enc28J60 by Norbert Truchsess - */ - -#include -#include - -EthernetServer server = EthernetServer(1000); - -void setup() -{ - Serial.begin(9600); - - uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; - IPAddress myIP(192,168,0,6); - - Ethernet.begin(mac,myIP); - - server.begin(); -} - -void loop() -{ - size_t size; - - if (EthernetClient client = server.available()) - { - while((size = client.available()) > 0) - { - uint8_t* msg = (uint8_t*)malloc(size); - size = client.read(msg,size); - Serial.write(msg,size); - free(msg); - } - client.println("DATA from Server!"); - client.stop(); - } -} diff --git a/libraries/UIPEthernet_/examples/UdpClient/UdpClient.ino b/libraries/UIPEthernet_/examples/UdpClient/UdpClient.ino deleted file mode 100644 index f549c48..0000000 --- a/libraries/UIPEthernet_/examples/UdpClient/UdpClient.ino +++ /dev/null @@ -1,94 +0,0 @@ -/* - * UIPEthernet UdpClient example. - * - * UIPEthernet is a TCP/IP stack that can be used with a enc28j60 based - * Ethernet-shield. - * - * UIPEthernet uses the fine uIP stack by Adam Dunkels - * - * ----------------- - * - * This UdpClient example tries to send a packet via udp to 192.168.0.1 - * on port 5000 every 5 seconds. After successfully sending the packet it - * waits for up to 5 seconds for a response on the local port that has been - * implicitly opened when sending the packet. - * - * Copyright (C) 2013 by Norbert Truchsess (norbert.truchsess@t-online.de) - */ - -#include -#include - -EthernetUDP udp; -unsigned long next; - -void setup() { - - Serial.begin(9600); - - uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; - - Ethernet.begin(mac,IPAddress(192,168,0,6)); - - next = millis()+5000; -} - -void loop() { - - int success; - int len = 0; - - if (((signed long)(millis()-next))>0) - { - do - { - success = udp.beginPacket(IPAddress(192,168,0,1),5000); - Serial.print("beginPacket: "); - Serial.println(success ? "success" : "failed"); - //beginPacket fails if remote ethaddr is unknown. In this case an - //arp-request is send out first and beginPacket succeeds as soon - //the arp-response is received. - } - while (!success && ((signed long)(millis()-next))<0); - if (!success ) - goto stop; - - success = udp.write("hello world from arduino"); - - Serial.print("bytes written: "); - Serial.println(success); - - success = udp.endPacket(); - - Serial.print("endPacket: "); - Serial.println(success ? "success" : "failed"); - - do - { - //check for new udp-packet: - success = udp.parsePacket(); - } - while (!success && ((signed long)(millis()-next))<0); - if (!success ) - goto stop; - - Serial.print("received: '"); - do - { - int c = udp.read(); - Serial.write(c); - len++; - } - while ((success = udp.available())>0); - Serial.print("', "); - Serial.print(len); - Serial.println(" bytes"); - - //finish reading this packet: - udp.flush(); - - stop: - udp.stop(); - next = millis()+5000; - } -} diff --git a/libraries/UIPEthernet_/examples/UdpServer/UdpServer.ino b/libraries/UIPEthernet_/examples/UdpServer/UdpServer.ino deleted file mode 100644 index 06b94be..0000000 --- a/libraries/UIPEthernet_/examples/UdpServer/UdpServer.ino +++ /dev/null @@ -1,89 +0,0 @@ -/* - * UIPEthernet UdpServer example. - * - * UIPEthernet is a TCP/IP stack that can be used with a enc28j60 based - * Ethernet-shield. - * - * UIPEthernet uses the fine uIP stack by Adam Dunkels - * - * ----------------- - * - * This UdpServer example sets up a udp-server at 192.168.0.6 on port 5000. - * send packet via upd to test - * - * Copyright (C) 2013 by Norbert Truchsess (norbert.truchsess@t-online.de) - */ - -#include -#include - -EthernetUDP udp; - -void setup() { - - Serial.begin(9600); - - uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; - - Ethernet.begin(mac,IPAddress(192,168,0,6)); - - int success = udp.begin(5000); - - Serial.print("initialize: "); - Serial.println(success ? "success" : "failed"); - -} - -void loop() { - - //check for new udp-packet: - int size = udp.parsePacket(); - if (size > 0) { - do - { - char* msg = (char*)malloc(size+1); - int len = udp.read(msg,size+1); - msg[len]=0; - Serial.print("received: '"); - Serial.print(msg); - free(msg); - } - while ((size = udp.available())>0); - //finish reading this packet: - udp.flush(); - Serial.println("'"); - int success; - do - { - Serial.print("remote ip: "); - Serial.println(udp.remoteIP()); - Serial.print("remote port: "); - Serial.println(udp.remotePort()); - //send new packet back to ip/port of client. This also - //configures the current connection to ignore packets from - //other clients! - success = udp.beginPacket(udp.remoteIP(),udp.remotePort()); - Serial.print("beginPacket: "); - Serial.println(success ? "success" : "failed"); - //beginPacket fails if remote ethaddr is unknown. In this case an - //arp-request is send out first and beginPacket succeeds as soon - //the arp-response is received. - } - while (!success); - - success = udp.println("hello world from arduino"); - - Serial.print("bytes written: "); - Serial.println(success); - - success = udp.endPacket(); - - Serial.print("endPacket: "); - Serial.println(success ? "success" : "failed"); - - udp.stop(); - //restart with new connection to receive packets from other clients - Serial.print("restart connection: "); - Serial.println (udp.begin(5000) ? "success" : "failed"); - } -} diff --git a/libraries/UIPEthernet_/keywords.txt b/libraries/UIPEthernet_/keywords.txt deleted file mode 100644 index 83ff854..0000000 --- a/libraries/UIPEthernet_/keywords.txt +++ /dev/null @@ -1,58 +0,0 @@ -####################################### -# Syntax Coloring Map for SerialIP -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -UIPEthernet KEYWORD1 -UIPServer KEYWORD1 -UIPClient KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### -PSOCK_BEGIN KEYWORD2 -PSOCK_CLOSE KEYWORD2 -PSOCK_END KEYWORD2 -PSOCK_EXIT KEYWORD2 -PSOCK_INIT KEYWORD2 -PSOCK_READBUF KEYWORD2 -PSOCK_READTO KEYWORD2 -PSOCK_SEND KEYWORD2 -PSOCK_SEND_STR KEYWORD2 - -uip_listen KEYWORD2 -uip_unlisten KEYWORD2 -uip_connect KEYWORD2 -uip_outstanding KEYWORD2 -uip_send KEYWORD2 -uip_datalen KEYWORD2 -uip_close KEYWORD2 -uip_abort KEYWORD2 -uip_stop KEYWORD2 -uip_stopped KEYWORD2 -uip_restart KEYWORD2 -uip_acked KEYWORD2 -uip_connected KEYWORD2 -uip_closed KEYWORD2 -uip_aborted KEYWORD2 -uip_timedout KEYWORD2 -uip_rexmit KEYWORD2 -uip_poll KEYWORD2 -uip_initialmss KEYWORD2 -uip_mss KEYWORD2 -uip_ipaddr KEYWORD2 -uip_ipaddr_maskcmp KEYWORD2 -uip_ipaddr_mask KEYWORD2 -HTONS KEYWORD2 -htons KEYWORD2 - -use_device KEYWORD2 -set_uip_callback KEYWORD2 -set_gateway KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### diff --git a/libraries/UIPEthernet_/library.properties b/libraries/UIPEthernet_/library.properties deleted file mode 100644 index cd8c551..0000000 --- a/libraries/UIPEthernet_/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=UIPEthernet -author=ntruchsess -email=Norbert Truchsess -sentence=Ethernet library for ENC28J60 -paragraph=implements the same API as stock Ethernet-lib. Just replace the include of Ethernet.h with UIPEthernet.h -url=https://github.com/ntruchsess/arduino_uip -architectures=* -version=1.50 -dependencies= -core-dependencies=arduino (>=1.5.0) diff --git a/libraries/UIPEthernet_/utility/Enc28J60Network.cpp b/libraries/UIPEthernet_/utility/Enc28J60Network.cpp deleted file mode 100644 index 9c154cd..0000000 --- a/libraries/UIPEthernet_/utility/Enc28J60Network.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/* - Enc28J60NetworkClass.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" - -#if ENC28J60_USE_SPILIB -#include -#endif - -extern "C" { - #if defined(ARDUINO_ARCH_AVR) - // AVR-specific code - #include - #elif defined(ARDUINO_ARCH_SAM) - // SAM-specific code - #else - // generic, non-platform specific code - #endif -#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) -// -#if defined(ARDUINO_ARCH_AVR) -#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() -{ - uint8_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 > RXSTOP_INIT ? nextPacketPtr+6-RXSTOP_INIT+RXSTART_INIT : 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; -#ifdef ENC28J60DEBUG - Serial.print("receivePacket ["); - Serial.print(readPtr,HEX); - Serial.print("-"); - Serial.print((readPtr+len) % (RXSTOP_INIT+1),HEX); - Serial.print("], next: "); - Serial.print(nextPacketPtr,HEX); - Serial.print(", stat: "); - Serial.print(rxstat,HEX); - Serial.print(", count: "); - Serial.print(readReg(EPKTCNT)); - Serial.print(" -> "); - Serial.println((rxstat & 0x80)!=0 ? "OK" : "failed"); -#endif - // 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 == NOBLOCK ? 0 : 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,HEX); - Serial.print("-"); - Serial.print(end,HEX); - Serial.print("]: "); - 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 = handle == UIP_RECEIVEBUFFERHANDLE && packet->begin + position > RXSTOP_INIT ? packet->begin + position-RXSTOP_INIT+RXSTART_INIT : 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; -#if ENC28J60_USE_SPILIB - // issue read command - SPI.transfer(ENC28J60_READ_BUF_MEM); - // read data - uint8_t c = SPI.transfer(0x00); - CSPASSIVE; - return (c); -#else - // issue read command - SPDR = ENC28J60_READ_BUF_MEM; - waitspi(); - // read data - SPDR = 0x00; - waitspi(); - CSPASSIVE; - return (SPDR); -#endif -} - -void Enc28J60Network::writeByte(uint16_t addr, uint8_t data) -{ - writeRegPair(EWRPTL, addr); - - CSACTIVE; -#if ENC28J60_USE_SPILIB - // issue write command - SPI.transfer(ENC28J60_WRITE_BUF_MEM); - // write data - SPI.transfer(data); -#else - // issue write command - SPDR = ENC28J60_WRITE_BUF_MEM; - waitspi(); - // write data - SPDR = data; - waitspi(); -#endif - 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]; - memaddress start = src_pkt == UIP_RECEIVEBUFFERHANDLE && src->begin + src_pos > RXSTOP_INIT ? src->begin + src_pos-RXSTOP_INIT+RXSTART_INIT : src->begin + src_pos; - enc28J60_mempool_block_move_callback(dest->begin+dest_pos,start,len); - // Move the RX read pointer to the start of the next received packet - // This frees the memory we just read out - setERXRDPT(); -} - -void -enc28J60_mempool_block_move_callback(memaddress dest, memaddress src, memaddress len) -{ -//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) - { - Enc28J60Network::writeByte(dest,Enc28J60Network::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. - */ - Enc28J60Network::writeRegPair(EDMASTL, src); - Enc28J60Network::writeRegPair(EDMADSTL, dest); - - if ((src <= RXSTOP_INIT)&& (len > RXSTOP_INIT))len -= (RXSTOP_INIT-RXSTART_INIT); - Enc28J60Network::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. */ - Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN); - - /* 4. Start the DMA copy by setting ECON1.DMAST. */ - Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST); - - // wait until runnig DMA is completed - while (Enc28J60Network::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 -#if ENC28J60_USE_SPILIB - SPI.transfer(op | (address & ADDR_MASK)); - // read data - if(address & 0x80) - { - // do dummy read if needed (for mac and mii, see datasheet page 29) - SPI.transfer(0x00); - } - uint8_t c = SPI.transfer(0x00); - // release CS - CSPASSIVE; - return(c); -#else - // 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); -#endif -} - -void -Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data) -{ - CSACTIVE; - // issue write command -#if ENC28J60_USE_SPILIB - SPI.transfer(op | (address & ADDR_MASK)); - // write data - SPI.transfer(data); -#else - // issue write command - SPDR = op | (address & ADDR_MASK); - waitspi(); - // write data - SPDR = data; - waitspi(); -#endif - CSPASSIVE; -} - -void -Enc28J60Network::readBuffer(uint16_t len, uint8_t* data) -{ - CSACTIVE; - // issue read command -#if ENC28J60_USE_SPILIB - SPI.transfer(ENC28J60_READ_BUF_MEM); -#else - SPDR = ENC28J60_READ_BUF_MEM; - waitspi(); -#endif - while(len) - { - len--; - // read data -#if ENC28J60_USE_SPILIB - *data = SPI.transfer(0x00); -#else - SPDR = 0x00; - waitspi(); - *data = SPDR; -#endif - data++; - } - //*data='\0'; - CSPASSIVE; -} - -void -Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data) -{ - CSACTIVE; - // issue write command -#if ENC28J60_USE_SPILIB - SPI.transfer(ENC28J60_WRITE_BUF_MEM); -#else - SPDR = ENC28J60_WRITE_BUF_MEM; - waitspi(); -#endif - while(len) - { - len--; - // write data -#if ENC28J60_USE_SPILIB - SPI.transfer(*data); - data++; -#else - SPDR = *data; - data++; - waitspi(); -#endif - } - 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); - } -} - -uint16_t -Enc28J60Network::phyRead(uint8_t address) -{ - writeReg(MIREGADR,address); - writeReg(MICMD, MICMD_MIIRD); - // wait until the PHY read completes - while(readReg(MISTAT) & MISTAT_BUSY){ - delayMicroseconds(15); - } //and MIRDH - writeReg(MICMD, 0); - return (readReg(MIRDL) | readReg(MIRDH) << 8); -} - -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 -#if ENC28J60_USE_SPILIB - SPI.transfer(ENC28J60_READ_BUF_MEM); -#else - SPDR = ENC28J60_READ_BUF_MEM; - waitspi(); -#endif - uint16_t i; - for (i = 0; i < len; i+=2) - { - // read data -#if ENC28J60_USE_SPILIB - t = SPI.transfer(0x00) << 8; - t += SPI.transfer(0x00); -#else - SPDR = 0x00; - waitspi(); - t = SPDR << 8; - SPDR = 0x00; - waitspi(); - t += SPDR; -#endif - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - if(i == len) { -#if ENC28J60_USE_SPILIB - t = (SPI.transfer(0x00) << 8) + 0; -#else - SPDR = 0x00; - waitspi(); - t = (SPDR << 8) + 0; -#endif - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - CSPASSIVE; - - /* Return sum in host byte order. */ - return sum; -} - -void -Enc28J60Network::powerOff() -{ - writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN); - delay(50); - writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS); - delay(50); - writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV); -} - -void -Enc28J60Network::powerOn() -{ - writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV); - delay(50); - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); - delay(50); -} - -bool -Enc28J60Network::linkStatus() -{ - return (phyRead(PHSTAT2) & 0x0400) > 0; -} - -Enc28J60Network Enc28J60; diff --git a/libraries/UIPEthernet_/utility/Enc28J60Network.h b/libraries/UIPEthernet_/utility/Enc28J60Network.h deleted file mode 100644 index aef1f59..0000000 --- a/libraries/UIPEthernet_/utility/Enc28J60Network.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Enc28J60NetworkClass.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 // this is pin 10 on Uno and pin 53 on Mega256 - -#if defined(ARDUINO_ARCH_AVR) -// AVR-specific code -#define SPI_MOSI MOSI -#define SPI_MISO MISO -#define SPI_SCK SCK -#define SPI_SS SS -#define ENC28J60_USE_SPILIB 0 -#elif defined(ARDUINO_ARCH_SAM) -#define ENC28J60_USE_SPILIB 1 -#endif - -#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: - static uint16_t nextPacketPtr; - static uint8_t bank; - - static struct memblock receivePkt; - - static uint8_t readOp(uint8_t op, uint8_t address); - static void writeOp(uint8_t op, uint8_t address, uint8_t data); - static uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len); - static void setERXRDPT(); - static void readBuffer(uint16_t len, uint8_t* data); - static void writeBuffer(uint16_t len, uint8_t* data); - static uint8_t readByte(uint16_t addr); - static void writeByte(uint16_t addr, uint8_t data); - static void setBank(uint8_t address); - static uint8_t readReg(uint8_t address); - static void writeReg(uint8_t address, uint8_t data); - static void writeRegPair(uint8_t address, uint16_t data); - static void phyWrite(uint8_t address, uint16_t data); - static uint16_t phyRead(uint8_t address); - static void clkout(uint8_t clk); - - friend void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress); - -public: - - uint8_t getrev(void); - void powerOn(); - void powerOff(); - bool linkStatus(); - - static void init(uint8_t* macaddr); - static memhandle receivePacket(); - static void freePacket(); - static memaddress blockSize(memhandle handle); - static void sendPacket(memhandle handle); - static uint16_t readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); - static uint16_t writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); - static void copyPacket(memhandle dest, memaddress dest_pos, memhandle src, memaddress src_pos, uint16_t len); - static uint16_t chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len); -}; - -extern Enc28J60Network Enc28J60; -#endif /* Enc28J60NetworkClass_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 c2f7abf..0000000 --- a/libraries/UIPEthernet_/utility/mempool.cpp +++ /dev/null @@ -1,168 +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 - -struct memblock MemoryPool::blocks[MEMPOOL_NUM_MEMBLOCKS+1]; - -void -MemoryPool::init() -{ - memset(&blocks[0], 0, sizeof(blocks)); - blocks[POOLSTART].begin = MEMPOOL_STARTADDRESS; - blocks[POOLSTART].size = 0; - blocks[POOLSTART].nextblock = NOBLOCK; -} - -memhandle -MemoryPool::allocBlock(memaddress size) -{ - memblock* best = NULL; - memhandle cur = POOLSTART; - memblock* block = &blocks[POOLSTART]; - memaddress bestsize = MEMPOOL_SIZE + 1; - - do - { - memhandle next = block->nextblock; - memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : 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 MEMPOOL_MEMBLOCK_MV - MEMPOOL_MEMBLOCK_MV(dest,*src,nextblock->size); -#endif - *src = dest; - } - block = nextblock; - } - if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size) - best = block; - else - goto notfound; - } - - found: - { - block = &blocks[POOLOFFSET]; - for (cur = POOLOFFSET; cur < MEMPOOL_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) -{ - if (handle == NOBLOCK) - return; - 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 2a1db21..0000000 --- a/libraries/UIPEthernet_/utility/mempool.h +++ /dev/null @@ -1,54 +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" - -struct memblock -{ - memaddress begin; - memaddress size; - memhandle nextblock; -}; - -class MemoryPool -{ -#ifdef MEMPOOLTEST_H - friend class MemoryPoolTest; -#endif - -protected: - static struct memblock blocks[MEMPOOL_NUM_MEMBLOCKS+1]; - -public: - static void init(); - static memhandle allocBlock(memaddress); - static void freeBlock(memhandle); - static void resizeBlock(memhandle handle, memaddress position); - static void resizeBlock(memhandle handle, memaddress position, memaddress size); - static 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 9615f92..0000000 --- a/libraries/UIPEthernet_/utility/mempool_conf.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MEMPOOLCONF_H -#define MEMPOOLCONF_H -#include "uipethernet-conf.h" -extern "C" { - #include "uipopt.h" - #include "enc28j60.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_CONNS -#define NUM_UDP_MEMBLOCKS 3*UIP_UDP_CONNS -#else -#define NUM_UDP_MEMBLOCKS 0 -#endif - -#define MEMPOOL_NUM_MEMBLOCKS (NUM_TCP_MEMBLOCKS+NUM_UDP_MEMBLOCKS) - -#define MEMPOOL_STARTADDRESS TXSTART_INIT+1 -#define MEMPOOL_SIZE TXSTOP_INIT-TXSTART_INIT - -void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress); - -#define MEMPOOL_MEMBLOCK_MV(dest,src,size) enc28J60_mempool_block_move_callback(dest,src,size) - -#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.c b/libraries/UIPEthernet_/utility/uip.c deleted file mode 100644 index c8ea98d..0000000 --- a/libraries/UIPEthernet_/utility/uip.c +++ /dev/null @@ -1,1898 +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 cc, 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. */ -#undef BUF -#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(cc = 0; cc < UIP_LISTENPORTS; ++cc) { - uip_listenports[cc] = 0; - } - for(cc = 0; cc < UIP_CONNS; ++cc) { - uip_conns[cc].tcpstateflags = UIP_CLOSED; - } -#if UIP_ACTIVE_OPEN - lastport = 1024; -#endif /* UIP_ACTIVE_OPEN */ - -#if UIP_UDP - for(cc = 0; cc < UIP_UDP_CONNS; ++cc) { - uip_udp_conns[cc].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(cc = 0; cc < UIP_CONNS; ++cc) { - conn = &uip_conns[cc]; - if(conn->tcpstateflags != UIP_CLOSED && - conn->lport == htons(lastport)) { - goto again; - } - } - - conn = 0; - for(cc = 0; cc < UIP_CONNS; ++cc) { - cconn = &uip_conns[cc]; - 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(cc = 0; cc < UIP_UDP_CONNS; ++cc) { - if(uip_udp_conns[cc].lport == htons(lastport)) { - goto again; - } - } - - - conn = 0; - for(cc = 0; cc < UIP_UDP_CONNS; ++cc) { - if(uip_udp_conns[cc].lport == 0) { - conn = &uip_udp_conns[cc]; - 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(cc = 0; cc < UIP_LISTENPORTS; ++cc) { - if(uip_listenports[cc] == port) { - uip_listenports[cc] = 0; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_listen(u16_t port) -{ - for(cc = 0; cc < UIP_LISTENPORTS; ++cc) { - if(uip_listenports[cc] == 0) { - uip_listenports[cc] = 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(cc = 0; cc < UIP_LISTENPORTS; ++cc) { - if(tmp16 == uip_listenports[cc]) - 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. */ - cc = BUF->seqno[3]; - BUF->seqno[3] = BUF->ackno[3]; - BUF->ackno[3] = cc; - - cc = BUF->seqno[2]; - BUF->seqno[2] = BUF->ackno[2]; - BUF->ackno[2] = cc; - - cc = BUF->seqno[1]; - BUF->seqno[1] = BUF->ackno[1]; - BUF->ackno[1] = cc; - - cc = BUF->seqno[0]; - BUF->seqno[0] = BUF->ackno[0]; - BUF->ackno[0] = cc; - - /* 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(cc = 0; cc < UIP_CONNS; ++cc) { - if(uip_conns[cc].tcpstateflags == UIP_CLOSED) { - uip_connr = &uip_conns[cc]; - break; - } - if(uip_conns[cc].tcpstateflags == UIP_TIME_WAIT) { - if(uip_connr == 0 || - uip_conns[cc].timer > uip_connr->timer) { - uip_connr = &uip_conns[cc]; - } - } - } - - 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(cc = 0; cc < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + cc]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++cc; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + cc] << 8) | - (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + cc]; - 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 + cc] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - cc += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc]; - } - } - } - - /* 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. */ - cc = (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 - cc - 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(cc = 0; cc < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + cc]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++cc; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + cc] << 8) | - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + cc]; - 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 + cc] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - cc += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc]; - } - } - } - 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 f220ff5..0000000 --- a/libraries/UIPEthernet_/utility/uip_arp.c +++ /dev/null @@ -1,424 +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; - -#undef BUF -#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 36c7948..0000000 --- a/libraries/UIPEthernet_/utility/uip_debug.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include -#include -extern "C" { - #include "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 b9c8d73..0000000 --- a/libraries/UIPEthernet_/utility/uipethernet-conf.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef UIPETHERNET_CONF_H -#define UIPETHERNET_CONF_H - -/* for TCP */ -#define UIP_SOCKET_NUMPACKETS 5 -#define UIP_CONF_MAX_CONNECTIONS 1 - -/* for UDP - * set UIP_CONF_UDP to 0 to disable UDP (saves aprox. 5kb flash) */ -#define UIP_CONF_UDP 0 -#define UIP_CONF_BROADCAST 1 -#define UIP_CONF_UDP_CONNS 4 - -/* 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 - -/* timeout after which UIPClient::connect gives up. The timeout is specified in seconds. - * if set to a number <= 0 connect will timeout when uIP does (which might be longer than you expect...) */ -#define UIP_CONNECT_TIMEOUT -1 - -/* periodic timer for uip (in ms) */ -#define UIP_PERIODIC_TIMER 250 - -/* timer to poll client for data after last write (in ms) - * set to -1 to disable fast polling and rely on periodic only (saves 100 bytes flash) */ -#define UIP_CLIENT_TIMER 10 - -#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 a75e185..0000000 --- a/libraries/UIPEthernet_/utility/util.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) ) -#undef ntohs -#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