diff --git a/.gitignore b/.gitignore index 0910caf..053d712 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,13 @@ -*.log -*.txt -*.json -!haos-addon/**/*.json -shinelanx-modbus/ -__pycache__/ -*.pyc -.env +__pycache__/ +!haos-addon/**/*.json +.env +*.json +*.log +*.pyc +*.txt # versehentlich getrackte Alt-Dateien, gehoeren nicht ins Repo +growatt-diagnose-tool/ Modbus-Server-Kathrein.pdf ShineLAN-X/releases/*.bin -growatt-diagnose-tool/ +shinelanx-modbus/ diff --git a/ShineLAN-X/README.md b/ShineLAN-X/README.md deleted file mode 100644 index 6080e0a..0000000 --- a/ShineLAN-X/README.md +++ /dev/null @@ -1,119 +0,0 @@ -# Growatt ShineLAN-X — Custom Firmware - -Custom-Firmware für den **Growatt ShineLAN-X** LAN-Stick. Liest Modbus RTU vom Wechselrichter und publiziert alle Werte per **MQTT** direkt in Home Assistant — vollständig lokal, ohne Growatt-Cloud. - ---- - -## Hardware - -| Komponente | Details | -|---|---| -| MCU | STM32F103RBT6 (LQFP-64) | -| Ethernet | ENC28J60 (Bitbang SPI2 auf PB12–PB15) | -| Wechselrichter-Anbindung | USB-CDC (virtueller COM-Port, 115200 Baud) | -| Programmier-Interface | SWD via ST-Link | - -### Pin-Belegung (vollständig verifiziert) - -Quelle: [mwalle/shinelanx-modbus](https://github.com/mwalle/shinelanx-modbus) — identische Platine. - -| Funktion | Pin | Hinweis | -|---|---|---| -| ETH CS | PB12 | SPI2 NSS | -| ETH SCK | PB13 | SPI2 SCK | -| ETH MISO | PB14 | SPI2 MISO | -| ETH MOSI | PB15 | SPI2 MOSI | -| ETH RST | PC8 | | -| ETH INT | PC6 | optional | -| USB D- | PA11 | Wechselrichter-Kommunikation | -| USB D+ | PA12 | Wechselrichter-Kommunikation | -| USB Pullup | PA8 | | -| Debug UART TX | PA9 | USART1, 115200 | -| Debug UART RX | PA10 | USART1, 115200 | -| LED Debug | PC7 | aktiv LOW | -| LED Rot | PB1 | aktiv LOW | -| LED Grün | PB0 | aktiv LOW | -| LED Blau | PC5 | aktiv LOW | -| Taster | PA3 | aktiv LOW | - -### SWD-Verkabelung (Flashen) - -| ShineLAN-X Testpunkt | ST-Link V2 | -|---|---| -| SWDIO | SWDIO | -| SWDCLK | SWCLK | -| GND | GND | -| 3.3V | 3.3V (nur wenn nicht extern versorgt) | - ---- - -## Konfiguration - -Alle Einstellungen in `firmware/include/config.h`: - -```cpp -// DHCP (1) oder statische IP (0) -#define USE_DHCP 1 - -// MQTT-Broker -#define MQTT_BROKER "192.168.1.1" -#define MQTT_USER "mqtt" -#define MQTT_PASSWORD "..." - -// Modbus Slave-Adresse (Standard: 1) -#define MODBUS_ADDR 1 -``` - ---- - -## Flashen - -```bash -cd firmware -pio run --target upload -``` - ---- - -## Wechselrichter-Kompatibilität - -Die Sensor-Liste in `main.cpp` entspricht dem **Growatt SPH 5000 TL3-BH-UP** (dreiphasig, mit Batterie). - -Beim Testen mit dem **MIC 1500 TL-X** (einphasig, ohne Batterie): - -| Unterschied | MIC 1500 | SPH 5000 | -|---|---|---| -| AC Output Power | Register **40** | Register 35 | -| PV-Strings | nur PV1 | PV1 + PV2 | -| Phasen | nur L1 | L1 / L2 / L3 | -| Batterie-Register | nicht vorhanden | 1009–1058 | - -Nicht vorhandene Register werden automatisch übersprungen (kein Absturz). Für Dauerbetrieb am MIC 1500 einfach die nicht passenden Sensoren in `main.cpp` auskommentieren und `ac_power_total` auf Register 40 ändern. - ---- - -## MQTT Topics - -Nach dem Start sendet die Firmware automatisch **MQTT Discovery** — Home Assistant erkennt das Gerät ohne manuelle Konfiguration. - -| Topic | Inhalt | -|---|---| -| `homeassistant/sensor/growatt_shinelan_*/config` | Discovery (retained) | -| `growatt/shinelan/pv1_power` | PV1 Leistung in W | -| `growatt/shinelan/ac_power_total` | AC Ausgangsleistung in W | -| `growatt/shinelan/energy_today` | Tagesenergie in kWh | -| `growatt/shinelan/energy_total` | Gesamtenergie in kWh | -| `growatt/shinelan/bat_soc` | Batterie Ladestand in % | -| `growatt/shinelan/energy_import_total` | Netzbezug gesamt in kWh | - ---- - -## LED-Status - -| LED | Bedeutung | -|---|---| -| Alle 3 kurz an | Startup | -| Grün | MQTT verbunden | -| Rot | MQTT-Verbindungsfehler | -| Debug (PC7) | Ethernet Link UP | -| Blau blinkt | Modbus-Abfrage läuft | diff --git a/ShineLAN-X/firmware/.gitignore b/ShineLAN-X/firmware/.gitignore deleted file mode 100644 index 89cc49c..0000000 --- a/ShineLAN-X/firmware/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pio -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch diff --git a/ShineLAN-X/firmware/.vscode/extensions.json b/ShineLAN-X/firmware/.vscode/extensions.json deleted file mode 100644 index 080e70d..0000000 --- a/ShineLAN-X/firmware/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ], - "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" - ] -} diff --git a/ShineLAN-X/firmware/CLAUDE.md b/ShineLAN-X/firmware/CLAUDE.md deleted file mode 100644 index ba71fe8..0000000 --- a/ShineLAN-X/firmware/CLAUDE.md +++ /dev/null @@ -1,20 +0,0 @@ -# Growatt ShineLAN-X Firmware - -PlatformIO-Projekt fuer STM32F103RBT6. Liest Modbus RTU vom Wechselrichter via USB-CDC und publiziert via MQTT an Home Assistant. - -## Wiki Knowledge Base - -Path: /Users/retr0/Nextcloud/HomeLab/Vault - -Beim Start einer neuen Session: -1. Zuerst `wiki/hot.md` lesen (aktueller Kontext) -2. Dann `wiki/entities/Growatt ShineLAN-X Firmware.md` fuer Projektdetails -3. Nur bei Bedarf weitere Wiki-Seiten - -## Wichtige Konventionen - -- Kommentare nur wenn das WARUM nicht offensichtlich ist -- Keine trailing summaries nach Tool-Calls -- config.h ist geheimnis-frei (DEFAULT_* Werte) -- committen OK -- Echte Credentials werden nur im EEPROM gespeichert, nie im Source -- Framework-Hacks in `~/.platformio/` werden bei `pio pkg update` zurueckgesetzt diff --git a/ShineLAN-X/firmware/include/config.h b/ShineLAN-X/firmware/include/config.h deleted file mode 100644 index 255c265..0000000 --- a/ShineLAN-X/firmware/include/config.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -// ============================================================ -// Pin-Belegung — STM32F103RBT6, LQFP-64 -// Quelle: https://github.com/mwalle/shinelanx-modbus -// ============================================================ - -// ENC28J60 — SPI2 (Hardware-SPI) -#define ETH_CS_PIN PB12 -#define ETH_SCK_PIN PB13 -#define ETH_MISO_PIN PB14 -#define ETH_MOSI_PIN PB15 -#define ETH_RST_PIN PC8 - -// LEDs (aktiv LOW) -#define LED_DEBUG PC7 -#define LED_RED PB1 -#define LED_GREEN PB0 -#define LED_BLUE PC5 - -// User-Taster -#define BTN_USER PA3 - -// MAC-Adresse -#define MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED - -// ============================================================ -// MODBUS -// ============================================================ -#define MODBUS_BAUD 9600 -#define MODBUS_ADDR 1 - -// ============================================================ -// GERÄT -// ============================================================ -#define MQTT_CLIENT "growatt-shinelan" -#define DEVICE_ID "growatt_shinelan" -#define DEVICE_NAME "Growatt ShineLAN-X" -#define DEVICE_MODEL "ShineLAN-X" -#define DEVICE_MFR "Growatt" - -// ============================================================ -// STANDARD-WERTE (erster Boot / Werkseinstellungen) -// Werden über die Web-UI überschrieben und in EEPROM gespeichert. -// ============================================================ -#define DEFAULT_DHCP true -#define DEFAULT_STATIC_IP 192,168,1,99 -#define DEFAULT_GW 192,168,1,1 -#define DEFAULT_SUBNET 255,255,255,0 -#define DEFAULT_DNS 192,168,1,1 -#define DEFAULT_MQTT_BROKER "192.168.1.1" -#define DEFAULT_MQTT_PORT 1883 -#define DEFAULT_MQTT_USER "" -#define DEFAULT_MQTT_PASS "" -#define DEFAULT_UPDATE_MS 10000UL - -// ============================================================ -// WECHSELRICHTER-MODELL -// Genau einen einkommentieren: -// ============================================================ -#define INVERTER_MIC1500 // Growatt MIC 1500/2000 TL-X (einphasig) -// #define INVERTER_SPH5000 // Growatt SPH 5000 TL3 (dreiphasig, Hybrid) diff --git a/ShineLAN-X/firmware/include/config_manager.h b/ShineLAN-X/firmware/include/config_manager.h deleted file mode 100644 index 4af36a3..0000000 --- a/ShineLAN-X/firmware/include/config_manager.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include -#include -#include "config.h" - -#define CFG_MAGIC 0xA55A1234 - -struct NetConfig { - uint32_t magic; - bool useDhcp; - uint8_t ip[4]; - uint8_t gw[4]; - uint8_t sn[4]; - uint8_t dns[4]; - char mqttBroker[40]; - uint16_t mqttPort; - char mqttUser[32]; - char mqttPass[64]; - uint32_t updateMs; -}; - -inline void configDefaults(NetConfig& c) { - c.magic = CFG_MAGIC; - c.useDhcp = DEFAULT_DHCP; - uint8_t dip[] = {DEFAULT_STATIC_IP}; - uint8_t dgw[] = {DEFAULT_GW}; - uint8_t dsn[] = {DEFAULT_SUBNET}; - uint8_t ddn[] = {DEFAULT_DNS}; - memcpy(c.ip, dip, 4); - memcpy(c.gw, dgw, 4); - memcpy(c.sn, dsn, 4); - memcpy(c.dns, ddn, 4); - strncpy(c.mqttBroker, DEFAULT_MQTT_BROKER, sizeof(c.mqttBroker) - 1); - c.mqttBroker[sizeof(c.mqttBroker) - 1] = 0; - c.mqttPort = DEFAULT_MQTT_PORT; - strncpy(c.mqttUser, DEFAULT_MQTT_USER, sizeof(c.mqttUser) - 1); - c.mqttUser[sizeof(c.mqttUser) - 1] = 0; - strncpy(c.mqttPass, DEFAULT_MQTT_PASS, sizeof(c.mqttPass) - 1); - c.mqttPass[sizeof(c.mqttPass) - 1] = 0; - c.updateMs = DEFAULT_UPDATE_MS; -} - -inline void configLoad(NetConfig& c) { - EEPROM.get(0, c); - if (c.magic != CFG_MAGIC) configDefaults(c); -} - -inline void configSave(const NetConfig& c) { - EEPROM.put(0, c); -} diff --git a/ShineLAN-X/firmware/include/enc28j60_bitbang.h b/ShineLAN-X/firmware/include/enc28j60_bitbang.h deleted file mode 100644 index b0c6924..0000000 --- a/ShineLAN-X/firmware/include/enc28j60_bitbang.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include -#include "config.h" - -// ============================================================ -// Bitbang-SPI für ENC28J60 auf PC6/PC7/PC8/PC9 -// ENC28J60 verwendet SPI Mode 0 (CPOL=0, CPHA=0) -// ============================================================ - -static inline void eth_spi_init() { - pinMode(ETH_SCK_PIN, OUTPUT); digitalWrite(ETH_SCK_PIN, LOW); - pinMode(ETH_MOSI_PIN, OUTPUT); digitalWrite(ETH_MOSI_PIN, LOW); - pinMode(ETH_MISO_PIN, INPUT); - pinMode(ETH_CS_PIN, OUTPUT); digitalWrite(ETH_CS_PIN, HIGH); -} - -static inline void eth_cs_low() { digitalWrite(ETH_CS_PIN, LOW); } -static inline void eth_cs_high() { digitalWrite(ETH_CS_PIN, HIGH); } - -static inline uint8_t eth_spi_transfer(uint8_t out) { - uint8_t in = 0; - for (int8_t i = 7; i >= 0; i--) { - digitalWrite(ETH_MOSI_PIN, (out >> i) & 1); - digitalWrite(ETH_SCK_PIN, HIGH); - in = (in << 1) | digitalRead(ETH_MISO_PIN); - digitalWrite(ETH_SCK_PIN, LOW); - } - return in; -} diff --git a/ShineLAN-X/firmware/lib/EthernetENC/.piopm b/ShineLAN-X/firmware/lib/EthernetENC/.piopm deleted file mode 100644 index 01c20e6..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/.piopm +++ /dev/null @@ -1 +0,0 @@ -{"type": "library", "name": "EthernetENC", "version": "2.0.5", "spec": {"owner": "jandrassy", "id": 11203, "name": "EthernetENC", "requirements": null, "uri": null}} \ No newline at end of file diff --git a/ShineLAN-X/firmware/lib/EthernetENC/README.md b/ShineLAN-X/firmware/lib/EthernetENC/README.md deleted file mode 100644 index c7d7411..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/README.md +++ /dev/null @@ -1,158 +0,0 @@ -First an important note: There are more suitable libraries for ENC28J60 with ESP8266, RP2040, ESP32 and Mbed Arduino platforms: - -* With ESP8266 and RP2040 platform you can use the EthernetCompat.h from the lwIP_enc28j60 bundled library. -* With ESP32 platform version 3 you can use the [EthernetESP32](https://github.com/Networking-for-Arduino/EthernetESP32) library which integrates with networking on the ESP32 platform. -* With Arduino Mbed Core boards you can use the [ENC28J60-EMAC](https://github.com/Networking-for-Arduino/ENC28J60-EMAC) library with the platforms Ethernet library - ---- - -# EthernetENC - -EthernetENC is the Ethernet library for ENC28J60. It is a modern version of [the UIPEthernet library](https://github.com/jandrassy/EthernetENC/wiki/UIPEthernet). - -The modernization includes: -* Ethernet 2.0.0 Arduino library functions -* compatible include file names EthernetClient.h, EthernetServer.h and EthernetUdp.h -* support of many Arduino architectures by using the SPI library -* SPI transactions to share the SPI bus with devices with different communication settings -* SPI communication at 20 MHz if the MCU supports it, else on the maximum supported by the MCU -* client.flush() to send the packet immediately -* calls yield() in blocking functions -* has UDP backlog to receive more than one message at time -* Arduino 1.5 library format built with dot_a_linkage option for optimal build result - -[The documentation of Arduino Ethernet library](https://www.arduino.cc/en/Reference/Ethernet) applies for classes and functions descriptions. - -Limitations: -* UDP.beginMulticast is not supported, because the uIP stack doesn't support multicast -* UDP broadcasts receiving is turned off on ENC to lower the processing load on the library - -This library doesn't have examples, because examples of the Arduino Ethernet library apply. You can find them in the Arduino IDE Examples menu Ethernet section. Only change `#include ` to `#include `. Some examples require [a little change](https://github.com/jandrassy/EthernetENC/wiki/Examples). - -This library is based on the Norbert Truchsess's arduino-uip original source code repository and uses experience from the development of the multi-architecture support by Cassy. Applicable fixes and enhancements from development of EthernetENC were transfered to Cassy's UIPEthernet. - -**You can find more information in project's [Wiki](https://github.com/jandrassy/EthernetENC/wiki).** - -## Original notes by Norbert Truchsess - -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. - -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. - - -## 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. - --------------- - -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 - -``` \ No newline at end of file diff --git a/ShineLAN-X/firmware/lib/EthernetENC/library.properties b/ShineLAN-X/firmware/lib/EthernetENC/library.properties deleted file mode 100644 index eecd621..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/library.properties +++ /dev/null @@ -1,11 +0,0 @@ -name=EthernetENC -author=Norbert Truchsess, Juraj Andrassy -maintainer=Juraj Andrassy -sentence=Ethernet library for ENC28J60. Only include EthernetENC.h instead of Ethernet.h -paragraph=This is a modern version of the UIPEthernet library. EthernetENC library is compatible with all Arduino architectures with Arduino SPI library with transactions support. -url=https://github.com/Networking-for-Arduino/EthernetENC/wiki -architectures=* -version=2.0.5 -category=Communication -includes=EthernetENC.h -dot_a_linkage=true diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/Dhcp.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/Dhcp.cpp deleted file mode 100644 index cfcd2f6..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/Dhcp.cpp +++ /dev/null @@ -1,491 +0,0 @@ -// DHCP Library v0.3 - April 25, 2009 -// Author: Jordan Terrell - blog.jordanterrell.com - -#include "Dhcp.h" -#include -#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(){ - memset(_dhcpLocalIp, 0, 4); - memset(_dhcpSubnetMask, 0, 4); - memset(_dhcpGatewayIp, 0, 4); - memset(_dhcpDhcpServerIp, 0, 4); - memset(_dhcpDnsServerIp, 0, 4); -} - -//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 - the only one flag DHCP uses is - // to request the server response as broadcast, not unicast -// 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; - if (_hostname == nullptr) { - 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); - } else { - uint8_t len = strlen(_hostname); - buffer[17] = len; - _dhcpUdpSocket.write(buffer, 18); - _dhcpUdpSocket.write(_hostname, len); - } - - 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.discardReceived(); - 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( _dhcpDhcpServerIp[0] == 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.discardReceived(); - - 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::setHostname(const char* hostname) { - _hostname = hostname; -} - -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/ShineLAN-X/firmware/lib/EthernetENC/src/Dhcp.h b/ShineLAN-X/firmware/lib/EthernetENC/src/Dhcp.h deleted file mode 100644 index ec99072..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/Dhcp.h +++ /dev/null @@ -1,189 +0,0 @@ -// DHCP Library v0.3 - April 25, 2009 -// Author: Jordan Terrell - blog.jordanterrell.com - -#ifndef Dhcp_h -#define Dhcp_h - -#include "EthernetUdp.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]; - const char* _hostname = nullptr; -#ifdef __arm__ - uint8_t _dhcpLocalIp[4] __attribute__((aligned(4))); - uint8_t _dhcpSubnetMask[4] __attribute__((aligned(4))); - uint8_t _dhcpGatewayIp[4] __attribute__((aligned(4))); - uint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4))); - uint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4))); -#else - uint8_t _dhcpLocalIp[4]; - uint8_t _dhcpSubnetMask[4]; - uint8_t _dhcpGatewayIp[4]; - uint8_t _dhcpDhcpServerIp[4]; - uint8_t _dhcpDnsServerIp[4]; -#endif - 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; - EthernetUDP _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(); - - void setHostname(const char* hostname); -}; - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/Dns.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/Dns.cpp deleted file mode 100644 index 4d82236..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/Dns.cpp +++ /dev/null @@ -1,416 +0,0 @@ -// Arduino DNS client for Enc28J60-based Ethernet shield -// (c) Copyright 2009-2010 MCQN Ltd. -// Released under Apache License, version 2.0 - -#include "Dns.h" -#include - -#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.discardReceived(); - 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.discardReceived(); - 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.discardReceived(); - 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.discardReceived(); - 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.discardReceived(); - - // If we get here then we haven't found an answer - return -10;//INVALID_RESPONSE; -} - diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/Dns.h b/ShineLAN-X/firmware/lib/EthernetENC/src/Dns.h deleted file mode 100644 index 81abc17..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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 "EthernetUdp.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; - EthernetUDP iUdp; -}; - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/Ethernet.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/Ethernet.cpp deleted file mode 100644 index df1c77f..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/Ethernet.cpp +++ /dev/null @@ -1,559 +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 "Ethernet.h" -#include "Dns.h" -#include "utility/Enc28J60Network.h" - -extern "C" -{ -#include "utility/uip-conf.h" -#include "utility/uip.h" -#include "utility/uip_arp.h" -} - -#define ETH_HDR ((struct uip_eth_hdr *)&uip_buf[0]) - -bool UIPEthernetClass::initialized = false; -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; -unsigned long UIPEthernetClass::arp_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() -{ -} - -void UIPEthernetClass::init(uint8_t csPin) -{ - Enc28J60Network::setCsPin(csPin); -} - -#if UIP_UDP -void -UIPEthernetClass::setHostname(const char* hostname) -{ - if (_dhcp == NULL) { - _dhcp = new DhcpClass(); - } - _dhcp->setHostname(hostname); -} - -int -UIPEthernetClass::begin(const uint8_t* mac, unsigned long timeout, unsigned long responseTimeout) -{ - if (_dhcp == NULL) { - _dhcp = new DhcpClass(); - } - - // Initialise the basic info - init(mac); - - // Now try to get our config info from a DHCP server - int ret = _dhcp->beginWithDHCP((uint8_t*)mac, timeout, responseTimeout); - 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); -} - -void UIPEthernetClass::end() -{ - //close all clients - for (int i = 0; i < UIP_CONNS; i++) - { - if (EthernetClient::all_data[i].state) { - EthernetClient client(&EthernetClient::all_data[i]); - client.stop(); - } - } - // handle clients closings - uint32_t st = millis(); - while (millis() - st < 3000) - { - tick(); - } - initialized = false; - configure(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); -} - -int UIPEthernetClass::maintain(){ - if (!initialized) - return 0; - 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; - } - } -#endif - return rc; -} - -EthernetLinkStatus UIPEthernetClass::linkStatus() -{ - if (!Enc28J60Network::getrev()) - return Unknown; - return Enc28J60Network::linkStatus() ? LinkON : LinkOFF; -} - -EthernetHardwareStatus UIPEthernetClass::hardwareStatus() -{ - if (!Enc28J60Network::getrev()) - return EthernetNoHardware; - return EthernetENC28J60; -} - -uint8_t* UIPEthernetClass::macAddress(uint8_t* mac) -{ - memcpy(mac, uip_ethaddr.addr, 6); - return mac; -} - -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; -} - -IPAddress UIPEthernetClass::dnsIP(int n) { - return (n == 0) ? _dnsServerAddress : IPAddress(); -} - -int UIPEthernetClass::hostByName(const char* hostname, IPAddress& result) -{ - // Look up the host first - int ret = 0; -#if UIP_UDP - DNSClient dns; - dns.begin(_dnsServerAddress); - ret = dns.getHostByName(hostname, result); -#endif - return ret; -} - -void -UIPEthernetClass::tick() -{ - if (!initialized) - return; - - // run ARP table cleanup every 10 seconds as required by a comment in uip_arp.h - if (millis() - arp_timer > 10000) { - arp_timer = millis(); - uip_arp_timer(); - } - - if (in_packet == NOBLOCK) - { - in_packet = Enc28J60Network::receivePacket(); -#ifdef UIPETHERNET_DEBUG - if (in_packet != NOBLOCK) - { - Serial.println(F("--------------\npacket received")); - } -#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.print(uip_len); - Serial.print(F(", bits: ")); - Serial.println(BUF->flags, BIN); -#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.println(F("freeing received packet")); -#endif - Enc28J60Network::freePacket(); - in_packet = NOBLOCK; - } - } - - unsigned long now = millis(); - - if ((long)( now - periodic_timer ) >= 0) - { - periodic_timer = now + UIP_PERIODIC_TIMER; - - for (int i = 0; i < UIP_CONNS; i++) - { - uip_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) - { - uip_arp_out(); - network_send(); - } - } -#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) - { - EthernetUDP::_send(&uip_udp_conns[i]); - } - } -#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, UIP_SENDBUFFER_OFFSET,uip_buf,uip_hdrlen); - packetstate &= ~ UIPETHERNET_SENDPACKET; - goto sendandfree; - } - uip_packet = Enc28J60Network::allocBlock(uip_len + UIP_SENDBUFFER_OFFSET + UIP_SENDBUFFER_PADDING); - 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.print(uip_packet); - Serial.print(F(", bits: ")); - Serial.println(BUF->flags, BIN); -#endif - Enc28J60Network::writePacket(uip_packet, UIP_SENDBUFFER_OFFSET,uip_buf,uip_len); - goto sendandfree; - } - return false; -sendandfree: - bool success = Enc28J60Network::sendPacket(uip_packet); - Enc28J60Network::freeBlock(uip_packet); - uip_packet = NOBLOCK; - return success; -} - -void UIPEthernetClass::init(const uint8_t* mac) { - periodic_timer = millis() + UIP_PERIODIC_TIMER; - - initialized = 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; -} - -void -UIPEthernetClass::call_yield() -{ - static bool in_yield; - static uint32_t last_call_millis; - if (!in_yield && millis() - last_call_millis > 0) - { - last_call_millis = millis(); - in_yield = true; - yield(); - in_yield = false; - } -} - -/*---------------------------------------------------------------------------*/ -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, - (UIPEthernetClass::packetstate & UIPETHERNET_SENDPACKET ? UIP_IPH_LEN + UIP_LLH_LEN + UIP_SENDBUFFER_OFFSET : 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 UIPEthernetClass::ipchksum(); -} - -#if UIP_UDP -uint16_t -uip_tcpchksum(void) -{ - uint16_t sum = UIPEthernetClass::upper_layer_chksum(UIP_PROTO_TCP); - return sum; -} - -uint16_t -uip_udpchksum(void) -{ - uint16_t sum = UIPEthernetClass::upper_layer_chksum(UIP_PROTO_UDP); - return sum; -} -#endif - -UIPEthernetClass Ethernet; - -extern "C" void serialPrint(int i); -void serialPrint(int i) { - Serial.println(i); - Serial.flush(); -} diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/Ethernet.h b/ShineLAN-X/firmware/lib/EthernetENC/src/Ethernet.h deleted file mode 100644 index 3f9ddbf..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/Ethernet.h +++ /dev/null @@ -1,161 +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 -#include "Dhcp.h" -#include -#include "utility/Enc28J60Network.h" -#include "EthernetClient.h" -#include "EthernetServer.h" -#include "EthernetUdp.h" - -extern "C" -{ -#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) - -#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) - -enum EthernetLinkStatus { - Unknown, - LinkON, - LinkOFF -}; - -enum EthernetHardwareStatus { - EthernetNoHardware, - EthernetW5100, - EthernetW5200, - EthernetW5500, - EthernetENC28J60 = 10 -}; - -class UIPEthernetClass -{ -public: - UIPEthernetClass(); - - void init(uint8_t csPin); - - int begin(const uint8_t* mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); - 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); - - void end(); - - // 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(); - - EthernetLinkStatus linkStatus(); - EthernetHardwareStatus hardwareStatus(); - - uint8_t* macAddress(uint8_t* mac); - void MACAddress(uint8_t *mac_address) { macAddress(mac_address); } - - IPAddress localIP(); - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsServerIP(); - IPAddress dnsIP(int n = 0); - - void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; } - void setDNS(IPAddress dns_server) { _dnsServerAddress = dns_server; } - - void setHostname(const char* hostname); // only the pointer is stored! - - int hostByName(const char* hostname, IPAddress& result); - -private: - static bool initialized; - 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 unsigned long arp_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(); - - static void call_yield(); - - friend class EthernetServer; - - friend class EthernetClient; - - friend class EthernetUDP; - - 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 Ethernet; - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetClient.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetClient.cpp deleted file mode 100644 index 636bc1d..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetClient.cpp +++ /dev/null @@ -1,663 +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 "Ethernet.h" -#include "EthernetClient.h" - -#define UIP_TCP_PHYH_LEN UIP_LLH_LEN+UIP_IPTCPH_LEN - -#define UIPClient EthernetClient // to not pollute source code history with the rename - -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 - uint32_t timeout = millis() + connectTimeout; -#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 - IPAddress remote_addr; - ret = Ethernet.hostByName(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 - if (data->state & UIP_CLIENT_REMOTECLOSED) - { - data->state = 0; - } - else - { - flush(); - data->state |= UIP_CLIENT_CLOSE; - } - _flushBlocks(data->packets_in); -#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(&c, 1); -} - -size_t -UIPClient::write(const uint8_t *buf, size_t size) -{ - uip_userdata_t* u = data; - int remain = size; - uint16_t written; -#if UIP_WRITE_TIMEOUT > 0 - uint32_t timeout_start = millis(); -#endif - repeat: - UIPEthernetClass::tick(); - if (u && u->state && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) - { - uint8_t p = _currentBlock(u->packets_out); - if (u->packets_out[p] == NOBLOCK) - { -newpacket: - u->packets_out[p] = Enc28J60Network::allocBlock(UIP_SOCKET_DATALEN); - if (u->packets_out[p] == NOBLOCK) - { -#if UIP_WRITE_TIMEOUT > 0 - if (millis() - timeout_start > UIP_WRITE_TIMEOUT) - { - setWriteError(); - goto ready; - } -#endif - Ethernet.call_yield(); - goto repeat; - } - 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 == 0) // block 0 just filled, start sending immediately - { - flush(); - goto repeat; - } - if (p == UIP_SOCKET_NUMPACKETS-1) - { -#if UIP_WRITE_TIMEOUT > 0 - if (millis() - timeout_start > UIP_WRITE_TIMEOUT) - { - setWriteError(); - goto ready; - } -#endif - Ethernet.call_yield(); - goto repeat; - } - p++; - goto newpacket; - } -ready: - return size-remain; - } - return 0; -} - -int -UIPClient::availableForWrite() -{ - const int MAX_AVAILABLE = UIP_SOCKET_DATALEN * UIP_SOCKET_NUMPACKETS; - UIPEthernetClass::tick(); - if (data->packets_out[0] == NOBLOCK) - return MAX_AVAILABLE; - uint8_t p = _currentBlock(data->packets_out); - int used = UIP_SOCKET_DATALEN * p + data->out_pos; - return MAX_AVAILABLE - used; -} - -void -UIPClient::flush() -{ - UIPEthernetClass::tick(); - - if (data && data->packets_out[0] != NOBLOCK) - { - struct uip_conn* conn = &uip_conns[data->conn_index]; - if (!uip_outstanding(conn)) - { - uip_poll_conn(conn); - if (uip_len > 0) - { - uip_arp_out(); - UIPEthernetClass::network_send(); - } - } - } -} - -int -UIPClient::available() -{ - if (!(*this)) - return 0; - - int len = 0; - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) - { - len += Enc28J60Network::blockSize(data->packets_in[i]); - } - - // if sketch checks for incoming data and there are unsent data, flush the transmit buffer - if (!len) - flush(); - return len; -} - -int -UIPClient::read(uint8_t *buf, size_t size) -{ - if (*this) - { - uint16_t remain = size; - if (data->packets_in[0] == NOBLOCK) - { - flush(); // if sketch checks for incoming data and there are unsent data, flush the transmit buffer - 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); - if (uip_stopped(&uip_conns[data->conn_index]) && !(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::discardReceived() -{ - if (*this) - { - _flushBlocks(data->packets_in); - } -} - -IPAddress -UIPClient::remoteIP(void) -{ - return data ? ip_addr_uip(uip_conns[data->conn_index].ripaddr) : IPAddress(); -} - -uint16_t -UIPClient::remotePort(void) -{ - return data ? ntohs(uip_conns[data->conn_index].rport) : 0; -} - -uint8_t -UIPClient::status() -{ - return !data ? UIP_CLOSED : uip_conns[data->conn_index].tcpstateflags & UIP_TS_MASK; -} - -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 && !(u->state & UIP_CLIENT_CLOSE)) - { - 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() || uip_aborted()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient uip_closed")); - UIPClient::_dumpAllData(); -#endif - // drop outgoing packets not sent yet: - UIPClient::_flushBlocks(u->packets_out); - 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); - goto send; - } - if (uip_poll() || uip_rexmit()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - //Serial.println(F("UIPClient uip_poll")); -#endif -send: - 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 + UIP_SENDBUFFER_OFFSET + UIP_SENDBUFFER_PADDING); - if (UIPEthernetClass::uip_packet != NOBLOCK) - { - Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen + UIP_SENDBUFFER_OFFSET,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 = uip_userdata_t(); - data->conn_index = uip_conn - uip_conns; // pointer arithmetics - data->state = UIP_CLIENT_CONNECTED; - 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++) - { - if (!all_data[i].state) - continue; - Serial.print(F("UIPClient::all_data[")); - Serial.print(i); - Serial.print(F("], state:")); - Serial.println(all_data[i].state, BIN); - struct uip_conn& conn = uip_conns[all_data[i].conn_index]; - Serial.println(ip_addr_uip(conn.ripaddr)); - Serial.print(F("ix: ")); - Serial.print(all_data[i].conn_index); - Serial.print(F(" tcp flags: 0x")); - Serial.print(conn.tcpstateflags, HEX); - Serial.print(F(" retransmission: timer ")); - Serial.print(conn.timer); - Serial.print(F(" nrtx ")); - Serial.println(conn.nrtx); - 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); - } - Serial.println(); - } - for (uint8_t i=0; i < UIP_CONNS; i++) - { - struct uip_conn& conn = uip_conns[i]; - Serial.print(i); - Serial.print(' '); - Serial.print(ip_addr_uip(conn.ripaddr)); - Serial.print(':'); - Serial.print(ntohs(conn.rport)); - Serial.print(' '); - Serial.print(ntohs(conn.lport)); - Serial.print(F(" tcp flags: 0x")); - Serial.print(conn.tcpstateflags, HEX); - Serial.print(F(" retransmission: timer ")); - Serial.print(conn.timer); - Serial.print(F(" nrtx ")); - Serial.println(conn.nrtx); - } -} -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetClient.h b/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetClient.h deleted file mode 100644 index 8807ece..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetClient.h +++ /dev/null @@ -1,110 +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 -#include "utility/mempool.h" - -extern "C" { - #include "utility/uip.h" -} - -#define UIP_SOCKET_DATALEN UIP_TCP_MSS - -#define UIP_CLIENT_CONNECTED 0x01 -#define UIP_CLIENT_CLOSE 0x02 -#define UIP_CLIENT_REMOTECLOSED 0x04 -#define UIP_CLIENT_RESTART 0x08 -#define UIP_CLIENT_ACCEPTED 0x10 - -typedef struct { - uint8_t conn_index; - 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 conn_index; - uint8_t state; - memhandle packets_in[UIP_SOCKET_NUMPACKETS] = {NOBLOCK}; - memhandle packets_out[UIP_SOCKET_NUMPACKETS] = {NOBLOCK}; - memaddress out_pos; -} uip_userdata_t; - -class EthernetClient : public Client { - -public: - EthernetClient(); - 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 availableForWrite(); - void flush(); // flush sends the buffered data - - int available(); - int read(); - int peek(); - void discardReceived(); - - using Print::write; - - IPAddress remoteIP(); - uint16_t remotePort(); - - uint8_t status(); - - void setConnectionTimeout(uint16_t millis) {connectTimeout = millis;} - -private: - EthernetClient(struct uip_conn *_conn); - EthernetClient(uip_userdata_t* conn_data); - - uip_userdata_t* data; - uint16_t connectTimeout = 1000 * UIP_CONNECT_TIMEOUT; - - static uip_userdata_t all_data[UIP_CONNS]; - static uip_userdata_t* _allocateData(); - - 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 EthernetServer; - - friend void uipclient_appcall(void); - -}; - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetENC.h b/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetENC.h deleted file mode 100644 index 01e5d5b..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetENC.h +++ /dev/null @@ -1 +0,0 @@ -#include "Ethernet.h" diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetServer.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetServer.cpp deleted file mode 100644 index 9237ad9..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetServer.cpp +++ /dev/null @@ -1,112 +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 "Ethernet.h" -#include "EthernetServer.h" -extern "C" { - #include "utility/uip-conf.h" -} - -#define UIPServer EthernetServer // to not pollute source code history with the rename -#define UIPClient EthernetClient - -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->conn_index].lport ==_port) - || ((data->state & UIP_CLIENT_REMOTECLOSED) && ((uip_userdata_closed_t *)data)->lport == _port))) - return UIPClient(data); - } - return UIPClient(); -} - -UIPClient UIPServer::accept() -{ - UIPEthernetClass::tick(); - for ( uip_userdata_t* data = &UIPClient::all_data[0]; data < &UIPClient::all_data[UIP_CONNS]; data++ ) - { - if (!(data->state & UIP_CLIENT_ACCEPTED) - && (((data->state & UIP_CLIENT_CONNECTED) && uip_conns[data->conn_index].lport ==_port) - || ((data->state & UIP_CLIENT_REMOTECLOSED) && ((uip_userdata_closed_t *)data)->lport == _port))) { - data->state |= UIP_CLIENT_ACCEPTED; - return UIPClient(data); - } - } - return UIPClient(); -} - -void UIPServer::begin() -{ - uip_listen(_port); - UIPEthernetClass::tick(); - listening = true; -} - -void UIPServer::begin(uint16_t port) -{ - _port = port; - begin(); -} - -void UIPServer::end() { - uip_unlisten(_port); - listening = false; - 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->conn_index].lport ==_port) - { - UIPClient client(data); - client.stop(); - } - } -} - -UIPServer::operator bool() { - return listening; -} - -size_t UIPServer::writeToAllClients(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->conn_index].lport ==_port) - { - EthernetClient client(data); - ret = client.write(buf, size); - } - } - return ret; -} - -size_t EthernetServerPrint::write(uint8_t c) -{ - return write(&c,1); -} - -size_t EthernetServerPrint::write(const uint8_t *buf, size_t size) -{ - return EthernetServer::writeToAllClients(buf, size); -} diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetServer.h b/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetServer.h deleted file mode 100644 index fec7006..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetServer.h +++ /dev/null @@ -1,55 +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 "EthernetClient.h" - -class EthernetServer { - -public: - EthernetServer(uint16_t port = 80); - EthernetClient available(); - EthernetClient accept(); - void begin(); - void begin(uint16_t port); - void end(); - operator bool(); - -protected: - size_t writeToAllClients(const uint8_t *buf, size_t size); - -private: - uint16_t _port; - bool listening = false; -}; - -class EthernetServerPrint : public EthernetServer, public Print { - -public: - EthernetServerPrint(uint16_t port = 80) : EthernetServer(port) {} - - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t *buf, size_t size); - - using Print::write; - -}; - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetUdp.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetUdp.cpp deleted file mode 100644 index 979037b..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetUdp.cpp +++ /dev/null @@ -1,424 +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 "Ethernet.h" -#include "EthernetUdp.h" - -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]) - -#define UIPUDP EthernetUDP // to not pollute source code history with the rename - -// Constructor -UIPUDP::UIPUDP() : - _uip_udp_conn(NULL), - 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); - _flushBlocks(appdata.packet_next); - Enc28J60Network::freeBlock(appdata.packet_out); - appdata = uip_udp_userdata_t(); - } -} - -// 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[0] || ip[1] || ip[2] || ip[3]) && port) - { - uip_ipaddr_t ripaddr; - uip_ip_addr(&ripaddr, ip); -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp beginPacket, ")); -#endif - if (_uip_udp_conn) - { - // [J.A]: for UDP server, setting ripaddr and rport causes in uIP filtering - // of incoming messages. it would be better to store the IP and port in fields - // and set them only in endPacket(). - _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 + UIP_SENDBUFFER_OFFSET + UIP_SENDBUFFER_PADDING); - appdata.out_pos = UIP_UDP_PHYH_LEN + UIP_SENDBUFFER_OFFSET; - 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; - IPAddress remote_addr; - ret = Ethernet.hostByName(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_SENDBUFFER_PADDING); - uip_udp_periodic_conn(_uip_udp_conn); - if (uip_len > 0) - { - _send(_uip_udp_conn); - 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[0].packet; - uip_ipaddr_copy(appdata.remote_ip, appdata.packet_next[0].remote_ip); - appdata.remote_port = appdata.packet_next[0].remote_port; - _moveBlocks(appdata.packet_next); - -#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::discardReceived() -{ - 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 ip_addr_uip(appdata.remote_ip); -} - -// Return the port of the host who sent the current incoming packet -uint16_t -UIPUDP::remotePort() -{ - return ntohs(appdata.remote_port); -} - -// uIP callback function - -void -uipudp_appcall(void) { - if (uip_udp_userdata_t *data = (uip_udp_userdata_t *)(uip_udp_conn->appstate)) - { - if (uip_newdata()) - { - uint8_t p = UIPUDP::_newBlock(data->packet_next); - if (data->packet_next[p].packet == NOBLOCK) - { - data->packet_next[p].remote_port = UDPBUF->srcport; - uip_ipaddr_copy( data->packet_next[p].remote_ip,UDPBUF->srcipaddr); - data->packet_next[p].packet = 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[p].packet != NOBLOCK) - { - //discard Linklevel and IP and udp-header and any trailing bytes: - Enc28J60Network::copyPacket(data->packet_next[p].packet,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next[p].packet)); - #ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_newdata received packet: ")); - Serial.print(data->packet_next[p].packet); - Serial.print(F(", size: ")); - Serial.println(Enc28J60Network::blockSize(data->packet_next[p].packet)); - #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::packetstate |= UIPETHERNET_SENDPACKET; - UIPEthernetClass::uip_hdrlen = UIP_UDP_PHYH_LEN; - uip_udp_send(data->out_pos - (UIP_UDP_PHYH_LEN + UIP_SENDBUFFER_OFFSET)); - } - } -} - -void -UIPUDP::_send(struct uip_udp_conn *uip_udp_conn) { - - 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 - UIPEthernetClass::network_send(); - } - else - //arp found ethaddr for ip (otherwise packet is replaced by arp-request) - { - uip_udp_userdata_t* data = (uip_udp_userdata_t *)(uip_udp_conn->appstate); - UIPEthernetClass::network_send(); - data->send = false; - data->packet_out = NOBLOCK; - - // [J.A] a listening UDP port in uIP filters received messages - // if rport and ripaddr are set. so we better clear them - uip_udp_conn->rport = 0; - uip_udp_conn->ripaddr[0] = 0; - uip_udp_conn->ripaddr[1] = 0; - -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_packet to send: ")); - Serial.println(UIPEthernetClass::uip_packet); -#endif - } -} - -uint8_t -UIPUDP::_newBlock(uip_udp_msg_rec_t* block) -{ - for (uint8_t i = 0; i < UIP_UDP_BACKLOG; i++) - { - if (block[i].packet == NOBLOCK) - return i; - } - return UIP_UDP_BACKLOG-1; -} - -void -UIPUDP::_moveBlocks(uip_udp_msg_rec_t* block) -{ - for (uint8_t i = 0; i < UIP_UDP_BACKLOG-1; i++) - { - block[i] = block[i+1]; - } - block[UIP_UDP_BACKLOG-1].packet = NOBLOCK; -} - -void -UIPUDP::_flushBlocks(uip_udp_msg_rec_t* block) -{ - for (uint8_t i = 0; i < UIP_UDP_BACKLOG; i++) - { - Enc28J60Network::freeBlock(block[i].packet); - block[i].packet = NOBLOCK; - } -} -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetUdp.h b/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetUdp.h deleted file mode 100644 index 43d27ca..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/EthernetUdp.h +++ /dev/null @@ -1,139 +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 -#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 { - memhandle packet = NOBLOCK; - uip_ipaddr_t remote_ip; - uint16_t remote_port = 0; -} uip_udp_msg_rec_t; - -typedef struct { - memaddress out_pos; - uip_udp_msg_rec_t packet_next[UIP_UDP_BACKLOG]; - memhandle packet_in = NOBLOCK; - memhandle packet_out = NOBLOCK; - boolean send; - uip_ipaddr_t remote_ip; - uint16_t remote_port = 0; -} uip_udp_userdata_t; - -class EthernetUDP : public UDP -{ - -private: - struct uip_udp_conn *_uip_udp_conn; - - uip_udp_userdata_t appdata; - -public: - EthernetUDP(); // 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); - // flush() should send the data, but here endPacket does it - void - flush() {}; // in Print it is empty, UDP makes it pure virtual - - 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 - discardReceived(); // former flush - - // 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(struct uip_udp_conn *uip_udp_conn); - - static uint8_t _newBlock(uip_udp_msg_rec_t* blocks); - static void _moveBlocks(uip_udp_msg_rec_t* blocks); - static void _flushBlocks(uip_udp_msg_rec_t* blocks); -}; - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/tcp_states.h b/ShineLAN-X/firmware/lib/EthernetENC/src/tcp_states.h deleted file mode 100644 index 02864da..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/tcp_states.h +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef UIP_TCP_STATES_H -#define UIP_TCP_STATES_H - -#include - -// common constants for client.state() return values -enum uip_tcp_state { - CLOSED = UIP_CLOSED, - SYN_SENT = UIP_SYN_SENT, - SYN_RCVD = UIP_SYN_RCVD, - ESTABLISHED = UIP_ESTABLISHED, - FIN_WAIT_1 = UIP_FIN_WAIT_1, - FIN_WAIT_2 = UIP_FIN_WAIT_2, - CLOSE_WAIT = 10, // not used - CLOSING = UIP_CLOSING, - LAST_ACK = UIP_LAST_ACK, - TIME_WAIT = UIP_TIME_WAIT -}; - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/Enc28J60Network.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/Enc28J60Network.cpp deleted file mode 100644 index 6649b48..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/Enc28J60Network.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - Enc28J60NetworkClass.cpp — Bitbang-SPI version for non-hardware-SPI pins - Based on UIPEthernet by Norbert Truchsess, GPL V2 - - Modification: Hardware SPI replaced with bitbang SPI. - Target: STM32F103RBT6 with ENC28J60 on PC6(SCK)/PC7(MISO)/PC8(CS)/PC9(MOSI) - */ - -#include "Enc28J60Network.h" -#include -#include "config.h" // ETH_SCK_PIN / ETH_MOSI_PIN / ETH_MISO_PIN -// Note: intentionally NOT included — this version uses bitbang SPI - -extern "C" { -#include "enc28j60.h" -#include "uip.h" -} - -// ============================================================ -// Bitbang SPI — SPI Mode 0 (CPOL=0, CPHA=0) -// Pin definitions come from project include/config.h via build system -// ============================================================ -#ifndef ETH_SCK_PIN - #error "ETH_SCK_PIN not defined — check include/config.h" -#endif - -static bool _spi_ready = false; - -static void bitbang_init() { - if (_spi_ready) return; - pinMode(ETH_SCK_PIN, OUTPUT); digitalWrite(ETH_SCK_PIN, LOW); - pinMode(ETH_MOSI_PIN, OUTPUT); digitalWrite(ETH_MOSI_PIN, LOW); - pinMode(ETH_MISO_PIN, INPUT); - _spi_ready = true; -} - -static inline uint8_t bitbang_transfer(uint8_t out) { - uint8_t in = 0; - for (int8_t i = 7; i >= 0; i--) { - digitalWrite(ETH_MOSI_PIN, (out >> i) & 1); - digitalWrite(ETH_SCK_PIN, HIGH); - in = (in << 1) | digitalRead(ETH_MISO_PIN); - digitalWrite(ETH_SCK_PIN, LOW); - } - return in; -} -// ============================================================ - -// set CS to 0 = active -#define CSACTIVE digitalWrite(csPin, LOW) -// set CS to 1 = passive -#define CSPASSIVE digitalWrite(csPin, HIGH) - -bool Enc28J60Network::spiInitialized = false; -uint8_t Enc28J60Network::csPin = SS; -uint16_t Enc28J60Network::nextPacketPtr; -uint8_t Enc28J60Network::bank = 0xff; - -struct memblock Enc28J60Network::receivePkt; - -void Enc28J60Network::initSPI() -{ - if (spiInitialized) - return; - bitbang_init(); - pinMode(csPin, OUTPUT); - CSPASSIVE; - spiInitialized = true; -} - -bool Enc28J60Network::init(uint8_t* macaddr) -{ - MemoryPool::init(); - initSPI(); - - // perform system reset - writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); - delay(50); - nextPacketPtr = RXSTART_INIT; - writeRegPair(ERXSTL, RXSTART_INIT); - writeRegPair(ERXRDPTL, RXSTART_INIT); - writeRegPair(ERXNDL, RXSTOP_INIT); - writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN); - writeRegPair(EPMM0, 0x303f); - writeRegPair(EPMCSL, 0xf7f9); - writeRegPair(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); - writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); - writeRegPair(MAIPGL, 0x0C12); - writeReg(MABBIPG, 0x12); - writeRegPair(MAMXFLL, MAX_FRAMELEN); - writeReg(MAADR5, macaddr[0]); - writeReg(MAADR4, macaddr[1]); - writeReg(MAADR3, macaddr[2]); - writeReg(MAADR2, macaddr[3]); - writeReg(MAADR1, macaddr[4]); - writeReg(MAADR0, macaddr[5]); - phyWrite(PHCON2, PHCON2_HDLDIS); - setBank(ECON1); - writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); - phyWrite(PHLCON, 0x476); - - return getrev(); -} - -memhandle Enc28J60Network::receivePacket() -{ - uint8_t rxstat; - uint16_t len; - - if (readReg(EPKTCNT) != 0) - { - uint16_t readPtr = nextPacketPtr+6 > RXSTOP_INIT ? - nextPacketPtr+6-((RXSTOP_INIT + 1)-RXSTART_INIT) : nextPacketPtr+6; - writeRegPair(ERDPTL, nextPacketPtr); - nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0); - nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; - len = readOp(ENC28J60_READ_BUF_MEM, 0); - len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; - len -= 4; - rxstat = readOp(ENC28J60_READ_BUF_MEM, 0); - writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); - if ((rxstat & 0x80) != 0) - { - receivePkt.begin = readPtr; - receivePkt.size = len; - return UIP_RECEIVEBUFFERHANDLE; - } - 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; -} - -bool Enc28J60Network::sendPacket(memhandle handle) -{ - memblock *packet = &blocks[handle]; - uint16_t start = packet->begin; - uint16_t end = start + packet->size - 1 - UIP_SENDBUFFER_PADDING; - - writeByte(start, 0); - - writeRegPair(ETXSTL, start); - writeRegPair(ETXNDL, end); - - bool success = false; - for (uint8_t retry = 0; retry < TX_COLLISION_RETRY_COUNT; retry++) - { - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); - writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); - writeOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF | EIR_TXIF); - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); - uint8_t eir; - while (((eir = readReg(EIR)) & (EIR_TXIF | EIR_TXERIF)) == 0); - writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS); - success = ((eir & EIR_TXERIF) == 0); - if (success) break; - uint8_t tsv4 = readByte(end + 4); - if (!(tsv4 & 0b00100000)) break; - } - return success; -} - -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 + 1)-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; - if (len > packet->size - position) len = packet->size - position; - if (len == 0) return 0; - writeRegPair(EWRPTL, start); - writeBuffer(len, buffer); - return len; -} - -uint8_t Enc28J60Network::readByte(uint16_t addr) -{ - writeRegPair(ERDPTL, addr); - CSACTIVE; - bitbang_transfer(ENC28J60_READ_BUF_MEM); - uint8_t c = bitbang_transfer(0x00); - CSPASSIVE; - return c; -} - -void Enc28J60Network::writeByte(uint16_t addr, uint8_t data) -{ - writeRegPair(EWRPTL, addr); - CSACTIVE; - bitbang_transfer(ENC28J60_WRITE_BUF_MEM); - bitbang_transfer(data); - 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 + 1) - RXSTART_INIT) : src->begin + src_pos; - enc28J60_mempool_block_move_callback(dest->begin + dest_pos, start, len); -} - -void enc28J60_mempool_block_move_callback(memaddress dest, memaddress src, memaddress len) -{ - if (len == 1) - { - Enc28J60Network::writeByte(dest, Enc28J60Network::readByte(src)); - } - else - { - len += src - 1; - Enc28J60Network::writeRegPair(EDMASTL, src); - Enc28J60Network::writeRegPair(EDMADSTL, dest); - if ((src <= RXSTOP_INIT) && (len > RXSTOP_INIT)) - len -= ((RXSTOP_INIT + 1)-RXSTART_INIT); - Enc28J60Network::writeRegPair(EDMANDL, len); - Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN); - Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST); - 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; - bitbang_transfer(op | (address & ADDR_MASK)); - if (address & 0x80) bitbang_transfer(0x00); // dummy read for MAC/MII - uint8_t c = bitbang_transfer(0x00); - CSPASSIVE; - return c; -} - -void Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data) -{ - CSACTIVE; - bitbang_transfer(op | (address & ADDR_MASK)); - bitbang_transfer(data); - CSPASSIVE; -} - -void Enc28J60Network::readBuffer(uint16_t len, uint8_t* data) -{ - CSACTIVE; - bitbang_transfer(ENC28J60_READ_BUF_MEM); - while (len--) *data++ = bitbang_transfer(0x00); - CSPASSIVE; -} - -void Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data) -{ - CSACTIVE; - bitbang_transfer(ENC28J60_WRITE_BUF_MEM); - while (len--) bitbang_transfer(*data++); - CSPASSIVE; -} - -void Enc28J60Network::setBank(uint8_t address) -{ - if ((address & BANK_MASK) != 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) -{ - setBank(address); - return readOp(ENC28J60_READ_CTRL_REG, address); -} - -void Enc28J60Network::writeReg(uint8_t address, uint8_t data) -{ - setBank(address); - writeOp(ENC28J60_WRITE_CTRL_REG, address, data); -} - -void Enc28J60Network::writeRegPair(uint8_t address, uint16_t data) -{ - setBank(address); - 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) -{ - writeReg(MIREGADR, address); - writeRegPair(MIWRL, data); - while (readReg(MISTAT) & MISTAT_BUSY) delayMicroseconds(15); -} - -uint16_t Enc28J60Network::phyRead(uint8_t address) -{ - writeReg(MIREGADR, address); - writeReg(MICMD, MICMD_MIIRD); - while (readReg(MISTAT) & MISTAT_BUSY) delayMicroseconds(15); - writeReg(MICMD, 0); - return (readReg(MIRDL) | readReg(MIRDH) << 8); -} - -void Enc28J60Network::clkout(uint8_t clk) -{ - writeReg(ECOCON, clk & 0x7); -} - -uint8_t Enc28J60Network::getrev(void) -{ - initSPI(); - 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; - bitbang_transfer(ENC28J60_READ_BUF_MEM); - uint16_t i; - for (i = 0; i < len; i += 2) - { - t = bitbang_transfer(0x00) << 8; - t += bitbang_transfer(0x00); - sum += t; - if (sum < t) sum++; - } - if (i == len) - { - t = (bitbang_transfer(0x00) << 8) + 0; - sum += t; - if (sum < t) sum++; - } - CSPASSIVE; - 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; -} diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/Enc28J60Network.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/Enc28J60Network.h deleted file mode 100644 index f35801b..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/Enc28J60Network.h +++ /dev/null @@ -1,94 +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 UIP_RECEIVEBUFFERHANDLE 0xff - -#define UIP_SENDBUFFER_PADDING 7 -#define UIP_SENDBUFFER_OFFSET 1 - -#define TX_COLLISION_RETRY_COUNT 3 - -//#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 uint8_t csPin; - static bool spiInitialized; - - 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: - - static uint8_t getrev(void); - static void powerOn(); - static void powerOff(); - static bool linkStatus(); - - static void setCsPin(uint8_t _csPin) {csPin = _csPin;} - static void initSPI(); - static bool init(uint8_t* macaddr); - static memhandle receivePacket(); - static void freePacket(); - static memaddress blockSize(memhandle handle); - static bool 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); -}; - -#endif /* Enc28J60NetworkClass_H_ */ diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/enc28j60.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/enc28j60.h deleted file mode 100644 index 3a45c59..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/mempool.cpp b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/mempool.cpp deleted file mode 100644 index c2f7abf..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/mempool.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/mempool.h deleted file mode 100644 index 2a1db21..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/mempool_conf.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/mempool_conf.h deleted file mode 100644 index 5f953dd..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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 ((2+UIP_UDP_BACKLOG)*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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip-conf.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip-conf.h deleted file mode 100644 index a6242c4..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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 __BYTE_ORDER__ - -/** - * 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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip.c b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip.c deleted file mode 100644 index 84ea8c3..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip.c +++ /dev/null @@ -1,1897 +0,0 @@ -#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ - -/** - * \defgroup uip The uIP TCP/IP stack - * @{ - * - * uIP is an implementation of the TCP/IP protocol stack intended for - * small 8-bit and 16-bit microcontrollers. - * - * uIP provides the necessary protocols for Internet communication, - * with a very small code footprint and RAM requirements - the uIP - * code size is on the order of a few kilobytes and RAM usage is on - * the order of a few hundred bytes. - */ - -/** - * \file - * The uIP TCP/IP stack code. - * \author Adam Dunkels - */ - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ - * - */ - -/* - * uIP is a small implementation of the IP, UDP and TCP protocols (as - * well as some basic ICMP stuff). The implementation couples the IP, - * UDP, TCP and the application layers very tightly. To keep the size - * of the compiled code down, this code frequently uses the goto - * statement. While it would be possible to break the uip_process() - * function into many smaller functions, this would increase the code - * size because of the overhead of parameter passing and the fact that - * the optimier would not be as efficient. - * - * The principle is that we have a small buffer, called the uip_buf, - * in which the device driver puts an incoming packet. The TCP/IP - * stack parses the headers in the packet, and calls the - * application. If the remote host has sent data to the application, - * this data is present in the uip_buf and the application read the - * data from there. It is up to the application to put this data into - * a byte stream if needed. The application will not be fed with data - * that is out of sequence. - * - * If the application whishes to send data to the peer, it should put - * its data into the uip_buf. The uip_appdata pointer points to the - * first available byte. The TCP/IP stack will calculate the - * checksums, and fill in the necessary header fields and finally send - * the packet back to the peer. -*/ - -#include "uip.h" -#include "uipopt.h" -#include "uip_arch.h" - -#if UIP_CONF_IPV6 -#include "uip-neighbor.h" -#endif /* UIP_CONF_IPV6 */ - -#include - -/*---------------------------------------------------------------------------*/ -/* Variable definitions. */ - - -/* The IP address of this host. If it is defined to be fixed (by - setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set - here. Otherwise, the address */ -#if UIP_FIXEDADDR > 0 -const uip_ipaddr_t uip_hostaddr = - {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), - HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; -const uip_ipaddr_t uip_draddr = - {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), - HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; -const uip_ipaddr_t uip_netmask = - {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), - HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; -#else -uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; -#endif /* UIP_FIXEDADDR */ - -static const uip_ipaddr_t all_ones_addr = -#if UIP_CONF_IPV6 - {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; -#else /* UIP_CONF_IPV6 */ - {0xffff,0xffff}; -#endif /* UIP_CONF_IPV6 */ -static const uip_ipaddr_t all_zeroes_addr = -#if UIP_CONF_IPV6 - {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; -#else /* UIP_CONF_IPV6 */ - {0x0000,0x0000}; -#endif /* UIP_CONF_IPV6 */ - - -#if UIP_FIXEDETHADDR -const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, - UIP_ETHADDR1, - UIP_ETHADDR2, - UIP_ETHADDR3, - UIP_ETHADDR4, - UIP_ETHADDR5}}; -#else -struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}; -#endif - -#ifndef UIP_CONF_EXTERNAL_BUFFER -u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains - incoming packets. */ -#endif /* UIP_CONF_EXTERNAL_BUFFER */ - -void *uip_appdata; /* The uip_appdata pointer points to - application data. */ -void *uip_sappdata; /* The uip_appdata pointer points to - the application data which is to - be sent. */ -#if UIP_URGDATA > 0 -void *uip_urgdata; /* The uip_urgdata pointer points to - urgent data (out-of-band data), if - present. */ -u16_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - -u16_t uip_len, uip_slen; - /* The uip_len is either 8 or 16 bits, - depending on the maximum packet - size. */ - -u8_t uip_flags; /* The uip_flags variable is used for - communication between the TCP/IP stack - and the application program. */ -struct uip_conn *uip_conn; /* uip_conn always points to the current - connection. */ - -struct uip_conn uip_conns[UIP_CONNS]; - /* The uip_conns array holds all TCP - connections. */ -u16_t uip_listenports[UIP_LISTENPORTS]; - /* The uip_listenports list all currently - listning ports. */ -#if UIP_UDP -struct uip_udp_conn *uip_udp_conn; -struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; -#endif /* UIP_UDP */ - -static u16_t ipid; /* Ths ipid variable is an increasing - number that is used for the IP ID - field. */ - -void uip_setipid(u16_t id) { ipid = id; } - -static u8_t iss[4]; /* The iss variable is used for the TCP - initial sequence number. */ - -#if UIP_ACTIVE_OPEN -static u16_t lastport; /* Keeps track of the last port used for - a new connection. */ -#endif /* UIP_ACTIVE_OPEN */ - -/* Temporary variables. */ -u8_t uip_acc32[4]; -static u8_t c, opt; -static u16_t tmp16; - -/* Structures and definitions. */ -#define TCP_FIN 0x01 -#define TCP_SYN 0x02 -#define TCP_RST 0x04 -#define TCP_PSH 0x08 -#define TCP_ACK 0x10 -#define TCP_URG 0x20 -#define TCP_CTL 0x3f - -#define TCP_OPT_END 0 /* End of TCP options list */ -#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ -#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ - -#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ - -#define ICMP_ECHO_REPLY 0 -#define ICMP_ECHO 8 - -#define ICMP6_ECHO_REPLY 129 -#define ICMP6_ECHO 128 -#define ICMP6_NEIGHBOR_SOLICITATION 135 -#define ICMP6_NEIGHBOR_ADVERTISEMENT 136 - -#define ICMP6_FLAG_S (1 << 6) - -#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 -#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 - - -/* Macros. */ -#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) -#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) - - -#if UIP_STATISTICS == 1 -struct uip_stats uip_stat; -#define UIP_STAT(s) s -#else -#define UIP_STAT(s) -#endif /* UIP_STATISTICS == 1 */ - -#if UIP_LOGGING == 1 -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -#if ! UIP_ARCH_ADD32 -void -uip_add32(u8_t *op32, u16_t op16) -{ - uip_acc32[3] = op32[3] + (op16 & 0xff); - uip_acc32[2] = op32[2] + (op16 >> 8); - uip_acc32[1] = op32[1]; - uip_acc32[0] = op32[0]; - - if(uip_acc32[2] < (op16 >> 8)) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - - - if(uip_acc32[3] < (op16 & 0xff)) { - ++uip_acc32[2]; - if(uip_acc32[2] == 0) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - } -} - -#endif /* UIP_ARCH_ADD32 */ - -#if ! UIP_ARCH_CHKSUM -/*---------------------------------------------------------------------------*/ -static u16_t -chksum(u16_t sum, const u8_t *data, u16_t len) -{ - u16_t t; - const u8_t *dataptr; - const u8_t *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while(dataptr < last_byte) { /* At least two more bytes */ - t = (dataptr[0] << 8) + dataptr[1]; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - dataptr += 2; - } - - if(dataptr == last_byte) { - t = (dataptr[0] << 8) + 0; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - - /* Return sum in host byte order. */ - return sum; -} -/*---------------------------------------------------------------------------*/ -u16_t -uip_chksum(u16_t *data, u16_t len) -{ - return htons(chksum(0, (u8_t *)data, len)); -} -/*---------------------------------------------------------------------------*/ -#ifndef UIP_ARCH_IPCHKSUM -u16_t -uip_ipchksum(void) -{ - u16_t sum; - - sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); - DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum); - return (sum == 0) ? 0xffff : htons(sum); -} -#endif -/*---------------------------------------------------------------------------*/ -static u16_t -upper_layer_chksum(u8_t proto) -{ - u16_t upper_layer_len; - u16_t sum; - -#if UIP_CONF_IPV6 - upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); -#else /* UIP_CONF_IPV6 */ - upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; -#endif /* UIP_CONF_IPV6 */ - - /* First sum pseudoheader. */ - - /* IP protocol and length fields. This addition cannot carry. */ - sum = upper_layer_len + proto; - /* Sum IP source and destination addresses. */ - sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); - - /* Sum TCP header and data. */ - sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], - upper_layer_len); - - return (sum == 0) ? 0xffff : htons(sum); -} -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 -u16_t -uip_icmp6chksum(void) -{ - return upper_layer_chksum(UIP_PROTO_ICMP6); - -} -#endif /* UIP_CONF_IPV6 */ -/*---------------------------------------------------------------------------*/ -u16_t -uip_tcpchksum(void) -{ - return upper_layer_chksum(UIP_PROTO_TCP); -} -/*---------------------------------------------------------------------------*/ -#if UIP_UDP_CHECKSUMS -u16_t -uip_udpchksum(void) -{ - return upper_layer_chksum(UIP_PROTO_UDP); -} -#endif /* UIP_UDP_CHECKSUMS */ -#endif /* UIP_ARCH_CHKSUM */ -/*---------------------------------------------------------------------------*/ -void -uip_init(void) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - uip_listenports[c] = 0; - } - for(c = 0; c < UIP_CONNS; ++c) { - uip_conns[c].tcpstateflags = UIP_CLOSED; - } -#if UIP_ACTIVE_OPEN - lastport = 1024; -#endif /* UIP_ACTIVE_OPEN */ - -#if UIP_UDP - for(c = 0; c < UIP_UDP_CONNS; ++c) { - uip_udp_conns[c].lport = 0; - } -#endif /* UIP_UDP */ - - - /* IPv4 initialization. */ -#if UIP_FIXEDADDR == 0 - /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ -#endif /* UIP_FIXEDADDR */ - -} -/*---------------------------------------------------------------------------*/ -#if UIP_ACTIVE_OPEN -struct uip_conn * -uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) -{ - register struct uip_conn *conn, *cconn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - /* Check if this port is already in use, and if so try to find - another one. */ - for(c = 0; c < UIP_CONNS; ++c) { - conn = &uip_conns[c]; - if(conn->tcpstateflags != UIP_CLOSED && - conn->lport == htons(lastport)) { - goto again; - } - } - - conn = 0; - for(c = 0; c < UIP_CONNS; ++c) { - cconn = &uip_conns[c]; - if(cconn->tcpstateflags == UIP_CLOSED) { - conn = cconn; - break; - } - if(cconn->tcpstateflags == UIP_TIME_WAIT) { - if(conn == 0 || - cconn->timer > conn->timer) { - conn = cconn; - } - } - } - - if(conn == 0) { - return 0; - } - - conn->tcpstateflags = UIP_SYN_SENT; - - conn->snd_nxt[0] = iss[0]; - conn->snd_nxt[1] = iss[1]; - conn->snd_nxt[2] = iss[2]; - conn->snd_nxt[3] = iss[3]; - - conn->initialmss = conn->mss = UIP_TCP_MSS; - - conn->len = 1; /* TCP length of the SYN is one. */ - conn->nrtx = 0; - conn->timer = 1; /* Send the SYN next time around. */ - conn->rto = UIP_RTO; - conn->sa = 0; - conn->sv = 16; /* Initial value of the RTT variance. */ - conn->lport = htons(lastport); - conn->rport = rport; - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - - return conn; -} -#endif /* UIP_ACTIVE_OPEN */ -/*---------------------------------------------------------------------------*/ -#if UIP_UDP -struct uip_udp_conn * -uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) -{ - register struct uip_udp_conn *conn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == htons(lastport)) { - goto again; - } - } - - - conn = 0; - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == 0) { - conn = &uip_udp_conns[c]; - break; - } - } - - if(conn == 0) { - return 0; - } - - conn->lport = HTONS(lastport); - conn->rport = rport; - if(ripaddr == NULL) { - memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); - } else { - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - } - conn->ttl = UIP_TTL; - - return conn; -} -#endif /* UIP_UDP */ -/*---------------------------------------------------------------------------*/ -void -uip_unlisten(u16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == port) { - uip_listenports[c] = 0; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_listen(u16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == 0) { - uip_listenports[c] = port; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -/* XXX: IP fragment reassembly: not well-tested. */ - -#if UIP_REASSEMBLY && !UIP_CONF_IPV6 -#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) -static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; -static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; -static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, - 0x0f, 0x07, 0x03, 0x01}; -static u16_t uip_reasslen; -static u8_t uip_reassflags; -#define UIP_REASS_FLAG_LASTFRAG 0x01 -static u8_t uip_reasstmr; - -#define IP_MF 0x20 - -static u8_t -uip_reass(void) -{ - u16_t offset, len; - u16_t i; - - /* If ip_reasstmr is zero, no packet is present in the buffer, so we - write the IP header of the fragment into the reassembly - buffer. The timer is updated with the maximum age. */ - if(uip_reasstmr == 0) { - memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); - uip_reasstmr = UIP_REASS_MAXAGE; - uip_reassflags = 0; - /* Clear the bitmap. */ - memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); - } - - /* Check if the incoming fragment matches the one currently present - in the reasembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] && - BUF->srcipaddr[1] == FBUF->srcipaddr[1] && - BUF->destipaddr[0] == FBUF->destipaddr[0] && - BUF->destipaddr[1] == FBUF->destipaddr[1] && - BUF->ipid[0] == FBUF->ipid[0] && - BUF->ipid[1] == FBUF->ipid[1]) { - - len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; - offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; - - /* If the offset or the offset + fragment length overflows the - reassembly buffer, we discard the entire packet. */ - if(offset > UIP_REASS_BUFSIZE || - offset + len > UIP_REASS_BUFSIZE) { - uip_reasstmr = 0; - goto nullreturn; - } - - /* Copy the fragment into the reassembly buffer, at the right - offset. */ - memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], - (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), - len); - - /* Update the bitmap. */ - if(offset / (8 * 8) == (offset + len) / (8 * 8)) { - /* If the two endpoints are in the same byte, we only update - that byte. */ - - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7] & - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } else { - /* If the two endpoints are in different bytes, we update the - bytes in the endpoints and fill the stuff inbetween with - 0xff. */ - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7]; - for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) { - uip_reassbitmap[i] = 0xff; - } - uip_reassbitmap[(offset + len) / (8 * 8)] |= - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } - - /* If this fragment has the More Fragments flag set to zero, we - know that this is the last fragment, so we can calculate the - size of the entire packet. We also set the - IP_REASS_FLAG_LASTFRAG flag to indicate that we have received - the final fragment. */ - - if((BUF->ipoffset[0] & IP_MF) == 0) { - uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; - uip_reasslen = offset + len; - } - - /* Finally, we check if we have a full packet in the buffer. We do - this by checking if we have the last fragment and if all bits - in the bitmap are set. */ - if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { - /* Check all bytes up to and including all but the last byte in - the bitmap. */ - for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { - if(uip_reassbitmap[i] != 0xff) { - goto nullreturn; - } - } - /* Check the last byte in the bitmap. It should contain just the - right amount of bits. */ - if(uip_reassbitmap[uip_reasslen / (8 * 8)] != - (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { - goto nullreturn; - } - - /* If we have come this far, we have a full packet in the - buffer, so we allocate a pbuf and copy the packet into it. We - also reset the timer. */ - uip_reasstmr = 0; - memcpy(BUF, FBUF, uip_reasslen); - - /* Pretend to be a "normal" (i.e., not fragmented) IP packet - from now on. */ - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - BUF->len[0] = uip_reasslen >> 8; - BUF->len[1] = uip_reasslen & 0xff; - BUF->ipchksum = 0; - BUF->ipchksum = ~(uip_ipchksum()); - - return uip_reasslen; - } - } - - nullreturn: - return 0; -} -#endif /* UIP_REASSEMBLY */ -/*---------------------------------------------------------------------------*/ -static void -uip_add_rcv_nxt(u16_t n) -{ - uip_add32(uip_conn->rcv_nxt, n); - uip_conn->rcv_nxt[0] = uip_acc32[0]; - uip_conn->rcv_nxt[1] = uip_acc32[1]; - uip_conn->rcv_nxt[2] = uip_acc32[2]; - uip_conn->rcv_nxt[3] = uip_acc32[3]; -} -/*---------------------------------------------------------------------------*/ -void -uip_process(u8_t flag) -{ - register struct uip_conn *uip_connr = uip_conn; - -#if UIP_UDP - if(flag == UIP_UDP_SEND_CONN) { - goto udp_send; - } -#endif /* UIP_UDP */ - - uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; - - /* Check if we were invoked because of a poll request for a - particular connection. */ - if(flag == UIP_POLL_REQUEST) { - if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && - !uip_outstanding(uip_connr)) { - uip_flags = UIP_POLL; - UIP_APPCALL(); - goto appsend; - } - goto drop; - - /* Check if we were invoked because of the perodic timer fireing. */ - } else if(flag == UIP_TIMER) { -#if UIP_REASSEMBLY - if(uip_reasstmr != 0) { - --uip_reasstmr; - } -#endif /* UIP_REASSEMBLY */ - /* Increase the initial sequence number. */ - if(++iss[3] == 0) { - if(++iss[2] == 0) { - if(++iss[1] == 0) { - ++iss[0]; - } - } - } - - /* Reset the length variables. */ - uip_len = 0; - uip_slen = 0; - - /* Check if the connection is in a state in which we simply wait - for the connection to time out. If so, we increase the - connection's timer and remove the connection if it times - out. */ - if(uip_connr->tcpstateflags == UIP_TIME_WAIT || - uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { - ++(uip_connr->timer); - if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { - uip_connr->tcpstateflags = UIP_CLOSED; - } - } else if(uip_connr->tcpstateflags != UIP_CLOSED) { - /* If the connection has outstanding data, we increase the - connection's timer and see if it has reached the RTO value - in which case we retransmit. */ - if(uip_outstanding(uip_connr)) { - if(uip_connr->timer-- == 0) { - if(uip_connr->nrtx == UIP_MAXRTX || - ((uip_connr->tcpstateflags == UIP_SYN_SENT || - uip_connr->tcpstateflags == UIP_SYN_RCVD) && - uip_connr->nrtx == UIP_MAXSYNRTX)) { - uip_connr->tcpstateflags = UIP_CLOSED; - - /* We call UIP_APPCALL() with uip_flags set to - UIP_TIMEDOUT to inform the application that the - connection has timed out. */ - uip_flags = UIP_TIMEDOUT; - UIP_APPCALL(); - - /* We also send a reset packet to the remote host. */ - BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - /* Exponential backoff. */ - uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? - 4: - uip_connr->nrtx); - ++(uip_connr->nrtx); - - /* Ok, so we need to retransmit. We do this differently - depending on which state we are in. In ESTABLISHED, we - call upon the application so that it may prepare the - data for the retransmit. In SYN_RCVD, we resend the - SYNACK that we sent earlier and in LAST_ACK we have to - retransmit our FINACK. */ - UIP_STAT(++uip_stat.tcp.rexmit); - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_SYN_RCVD: - /* In the SYN_RCVD state, we should retransmit our - SYNACK. */ - goto tcp_send_synack; - -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - BUF->flags = 0; - goto tcp_send_syn; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application - to do the actual retransmit after which we jump into - the code for sending out the packet (the apprexmit - label). */ - uip_flags = UIP_REXMIT; - UIP_APPCALL(); - goto apprexmit; - - case UIP_FIN_WAIT_1: - case UIP_CLOSING: - case UIP_LAST_ACK: - /* In all these states we should retransmit a FINACK. */ - goto tcp_send_finack; - - } - } - } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { - /* If there was no need for a retransmission, we poll the - application for new data. */ - uip_flags = UIP_POLL; - UIP_APPCALL(); - goto appsend; - } - } - goto drop; - } -#if UIP_UDP - if(flag == UIP_UDP_TIMER) { - if(uip_udp_conn->lport != 0) { - uip_conn = NULL; - uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - uip_len = uip_slen = 0; - uip_flags = UIP_POLL; - UIP_UDP_APPCALL(); - goto udp_send; - } else { - goto drop; - } - } -#endif - - /* This is where the input processing starts. */ - UIP_STAT(++uip_stat.ip.recv); - - /* Start of IP input header processing code. */ - -#if UIP_CONF_IPV6 - /* Check validity of the IP header. */ - if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.vhlerr); - UIP_LOG("ipv6: invalid version."); - goto drop; - } -#else /* UIP_CONF_IPV6 */ - /* Check validity of the IP header. */ - if(BUF->vhl != 0x45) { /* IP version and header length. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.vhlerr); - UIP_LOG("ip: invalid version or header length."); - goto drop; - } -#endif /* UIP_CONF_IPV6 */ - - /* Check the size of the packet. If the size reported to us in - uip_len is smaller the size reported in the IP header, we assume - that the packet has been corrupted in transit. If the size of - uip_len is larger than the size reported in the IP packet header, - the packet has been padded and we set uip_len to the correct - value.. */ - - if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) { - uip_len = (BUF->len[0] << 8) + BUF->len[1]; -#if UIP_CONF_IPV6 - uip_len += 40; /* The length reported in the IPv6 header is the - length of the payload that follows the - header. However, uIP uses the uip_len variable - for holding the size of the entire packet, - including the IP header. For IPv4 this is not a - problem as the length field in the IPv4 header - contains the length of the entire packet. But - for IPv6 we need to add the size of the IPv6 - header (40 bytes). */ -#endif /* UIP_CONF_IPV6 */ - } else { - UIP_LOG("ip: packet shorter than reported in IP header."); - goto drop; - } - -#if !UIP_CONF_IPV6 - /* Check the fragment flag. */ - if((BUF->ipoffset[0] & 0x3f) != 0 || - BUF->ipoffset[1] != 0) { -#if UIP_REASSEMBLY - uip_len = uip_reass(); - if(uip_len == 0) { - goto drop; - } -#else /* UIP_REASSEMBLY */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); - goto drop; -#endif /* UIP_REASSEMBLY */ - } -#endif /* UIP_CONF_IPV6 */ - - if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { - /* If we are configured to use ping IP address configuration and - hasn't been assigned an IP address yet, we accept all ICMP - packets. */ -#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 - if(BUF->proto == UIP_PROTO_ICMP) { - UIP_LOG("ip: possible ping config packet received."); - goto icmp_input; - } else { - UIP_LOG("ip: packet dropped since no address assigned."); - goto drop; - } -#endif /* UIP_PINGADDRCONF */ - - } else { - /* If IP broadcast support is configured, we check for a broadcast - UDP packet, which may be destined to us. */ -#if UIP_BROADCAST - DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); - if(BUF->proto == UIP_PROTO_UDP && - uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr) - /*&& - uip_ipchksum() == 0xffff*/) { - goto udp_input; - } -#endif /* UIP_BROADCAST */ - - /* Check if the packet is destined for our IP address. */ -#if !UIP_CONF_IPV6 - if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) { - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } -#else /* UIP_CONF_IPV6 */ - /* For IPv6, packet reception is a little trickier as we need to - make sure that we listen to certain multicast addresses (all - hosts multicast address, and the solicited-node multicast - address) as well. However, we will cheat here and accept all - multicast packets that are sent to the ff02::/16 addresses. */ - if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) && - BUF->destipaddr[0] != HTONS(0xff02)) { - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } -#endif /* UIP_CONF_IPV6 */ - } - -#if !UIP_CONF_IPV6 - if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header - checksum. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.chkerr); - UIP_LOG("ip: bad checksum."); - goto drop; - } -#endif /* UIP_CONF_IPV6 */ - - if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, - proceed with TCP input - processing. */ - goto tcp_input; - } - -#if UIP_UDP - if(BUF->proto == UIP_PROTO_UDP) { - goto udp_input; - } -#endif /* UIP_UDP */ - -#if !UIP_CONF_IPV6 - /* ICMPv4 processing code follows. */ - if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from - here. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip: neither tcp nor icmp."); - goto drop; - } - -#if UIP_PINGADDRCONF - icmp_input: -#endif /* UIP_PINGADDRCONF */ - UIP_STAT(++uip_stat.icmp.recv); - - /* ICMP echo (i.e., ping) processing. This is simple, we only change - the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP - checksum before we return the packet. */ - if(ICMPBUF->type != ICMP_ECHO) { - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.typeerr); - UIP_LOG("icmp: not icmp echo."); - goto drop; - } - - /* If we are configured to use ping IP address assignment, we use - the destination IP address of this ping packet and assign it to - ourself. */ -#if UIP_PINGADDRCONF - if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { - uip_hostaddr[0] = BUF->destipaddr[0]; - uip_hostaddr[1] = BUF->destipaddr[1]; - } -#endif /* UIP_PINGADDRCONF */ - - ICMPBUF->type = ICMP_ECHO_REPLY; - - if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) { - ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1; - } else { - ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8); - } - - /* Swap IP addresses. */ - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - - UIP_STAT(++uip_stat.icmp.sent); - goto send; - - /* End of IPv4 input header processing code. */ -#else /* !UIP_CONF_IPV6 */ - - /* This is IPv6 ICMPv6 processing code. */ - DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); - - if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from - here. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip: neither tcp nor icmp6."); - goto drop; - } - - UIP_STAT(++uip_stat.icmp.recv); - - /* If we get a neighbor solicitation for our address we should send - a neighbor advertisement message back. */ - if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { - if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { - - if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { - /* Save the sender's address in our neighbor list. */ - uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); - } - - /* We should now send a neighbor advertisement back to where the - neighbor solicication came from. */ - ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; - ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ - - ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; - - uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); - uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); - ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; - ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ - memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_icmp6chksum(); - goto send; - - } - goto drop; - } else if(ICMPBUF->type == ICMP6_ECHO) { - /* ICMP echo (i.e., ping) processing. This is simple, we only - change the ICMP type from ECHO to ECHO_REPLY and update the - ICMP checksum before we return the packet. */ - - ICMPBUF->type = ICMP6_ECHO_REPLY; - - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_icmp6chksum(); - - UIP_STAT(++uip_stat.icmp.sent); - goto send; - } else { - DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type); - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.typeerr); - UIP_LOG("icmp: unknown ICMP message."); - goto drop; - } - - /* End of IPv6 ICMP processing. */ - -#endif /* !UIP_CONF_IPV6 */ - -#if UIP_UDP - /* UDP input processing. */ - udp_input: - /* UDP processing is really just a hack. We don't do anything to the - UDP/IP headers, but let the UDP application do all the hard - work. If the application sets uip_slen, it has a packet to - send. */ -#if UIP_UDP_CHECKSUMS - uip_len = uip_len - UIP_IPUDPH_LEN; - uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { - UIP_STAT(++uip_stat.udp.drop); - UIP_STAT(++uip_stat.udp.chkerr); - UIP_LOG("udp: bad checksum."); - goto drop; - } -#else /* UIP_UDP_CHECKSUMS */ - uip_len = uip_len - UIP_IPUDPH_LEN; -#endif /* UIP_UDP_CHECKSUMS */ - - /* Demultiplex this UDP packet between the UDP "connections". */ - for(uip_udp_conn = &uip_udp_conns[0]; - uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; - ++uip_udp_conn) { - /* If the local UDP port is non-zero, the connection is considered - to be used. If so, the local port number is checked against the - destination port number in the received packet. If the two port - numbers match, the remote port number is checked if the - connection is bound to a remote port. Finally, if the - connection is bound to a remote IP address, the source IP - address of the packet is checked. */ - if(uip_udp_conn->lport != 0 && - UDPBUF->destport == uip_udp_conn->lport && - (uip_udp_conn->rport == 0 || - UDPBUF->srcport == uip_udp_conn->rport) && - (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || - uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || - uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { - goto udp_found; - } - } - UIP_LOG("udp: no matching connection found"); - goto drop; - - udp_found: - uip_conn = NULL; - uip_flags = UIP_NEWDATA; - uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - uip_slen = 0; - UIP_UDP_APPCALL(); - udp_send: - if(uip_slen == 0) { - goto drop; - } - uip_len = uip_slen + UIP_IPUDPH_LEN; - -#if UIP_CONF_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ - BUF->len[0] = (uip_len >> 8); - BUF->len[1] = (uip_len & 0xff); -#endif /* UIP_CONF_IPV6 */ - - BUF->ttl = uip_udp_conn->ttl; - BUF->proto = UIP_PROTO_UDP; - - UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN); - UDPBUF->udpchksum = 0; - - BUF->srcport = uip_udp_conn->lport; - BUF->destport = uip_udp_conn->rport; - - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr); - - uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; - -#if UIP_UDP_CHECKSUMS - /* Calculate UDP checksum. */ - UDPBUF->udpchksum = ~(uip_udpchksum()); - if(UDPBUF->udpchksum == 0) { - UDPBUF->udpchksum = 0xffff; - } -#endif /* UIP_UDP_CHECKSUMS */ - - goto ip_send_nolen; -#endif /* UIP_UDP */ - - /* TCP input processing. */ - tcp_input: - UIP_STAT(++uip_stat.tcp.recv); - - /* Start of TCP input header processing code. */ - - if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP - checksum. */ - UIP_STAT(++uip_stat.tcp.drop); - UIP_STAT(++uip_stat.tcp.chkerr); - UIP_LOG("tcp: bad checksum."); - goto drop; - } - - - /* Demultiplex this segment. */ - /* First check any active connections. */ - for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; - ++uip_connr) { - if(uip_connr->tcpstateflags != UIP_CLOSED && - BUF->destport == uip_connr->lport && - BUF->srcport == uip_connr->rport && - uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { - goto found; - } - } - - /* If we didn't find and active connection that expected the packet, - either this packet is an old duplicate, or this is a SYN packet - destined for a connection in LISTEN. If the SYN flag isn't set, - it is an old packet and we send a RST. */ - if((BUF->flags & TCP_CTL) != TCP_SYN) { - goto reset; - } - - tmp16 = BUF->destport; - /* Next, check listening connections. */ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(tmp16 == uip_listenports[c]) - goto found_listen; - } - - /* No matching connection found, so we send a RST packet. */ - UIP_STAT(++uip_stat.tcp.synrst); - reset: - - /* We do not send resets in response to resets. */ - if(BUF->flags & TCP_RST) { - goto drop; - } - - UIP_STAT(++uip_stat.tcp.rst); - - BUF->flags = TCP_RST | TCP_ACK; - uip_len = UIP_IPTCPH_LEN; - BUF->tcpoffset = 5 << 4; - - /* Flip the seqno and ackno fields in the TCP header. */ - c = BUF->seqno[3]; - BUF->seqno[3] = BUF->ackno[3]; - BUF->ackno[3] = c; - - c = BUF->seqno[2]; - BUF->seqno[2] = BUF->ackno[2]; - BUF->ackno[2] = c; - - c = BUF->seqno[1]; - BUF->seqno[1] = BUF->ackno[1]; - BUF->ackno[1] = c; - - c = BUF->seqno[0]; - BUF->seqno[0] = BUF->ackno[0]; - BUF->ackno[0] = c; - - /* We also have to increase the sequence number we are - acknowledging. If the least significant byte overflowed, we need - to propagate the carry to the other bytes as well. */ - if(++BUF->ackno[3] == 0) { - if(++BUF->ackno[2] == 0) { - if(++BUF->ackno[1] == 0) { - ++BUF->ackno[0]; - } - } - } - - /* Swap port numbers. */ - tmp16 = BUF->srcport; - BUF->srcport = BUF->destport; - BUF->destport = tmp16; - - /* Swap IP addresses. */ - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - - /* And send out the RST packet! */ - goto tcp_send_noconn; - - /* This label will be jumped to if we matched the incoming packet - with a connection in LISTEN. In that case, we should create a new - connection and send a SYNACK in return. */ - found_listen: - /* First we check if there are any connections avaliable. Unused - connections are kept in the same table as used connections, but - unused ones have the tcpstate set to CLOSED. Also, connections in - TIME_WAIT are kept track of and we'll use the oldest one if no - CLOSED connections are found. Thanks to Eddie C. Dost for a very - nice algorithm for the TIME_WAIT search. */ - uip_connr = 0; - for(c = 0; c < UIP_CONNS; ++c) { - if(uip_conns[c].tcpstateflags == UIP_CLOSED) { - uip_connr = &uip_conns[c]; - break; - } - if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { - if(uip_connr == 0 || - uip_conns[c].timer > uip_connr->timer) { - uip_connr = &uip_conns[c]; - } - } - } - - if(uip_connr == 0) { - /* All connections are used already, we drop packet and hope that - the remote end will retransmit the packet at a time when we - have more spare connections. */ - UIP_STAT(++uip_stat.tcp.syndrop); - UIP_LOG("tcp: found no unused connections."); - goto drop; - } - uip_conn = uip_connr; - - /* Fill in the necessary fields for the new connection. */ - uip_connr->rto = uip_connr->timer = UIP_RTO; - uip_connr->sa = 0; - uip_connr->sv = 4; - uip_connr->nrtx = 0; - uip_connr->lport = BUF->destport; - uip_connr->rport = BUF->srcport; - uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); - uip_connr->tcpstateflags = UIP_SYN_RCVD; - - uip_connr->snd_nxt[0] = iss[0]; - uip_connr->snd_nxt[1] = iss[1]; - uip_connr->snd_nxt[2] = iss[2]; - uip_connr->snd_nxt[3] = iss[3]; - uip_connr->len = 1; - - /* rcv_nxt should be the seqno from the incoming packet + 1. */ - uip_connr->rcv_nxt[3] = BUF->seqno[3]; - uip_connr->rcv_nxt[2] = BUF->seqno[2]; - uip_connr->rcv_nxt[1] = BUF->seqno[1]; - uip_connr->rcv_nxt[0] = BUF->seqno[0]; - uip_add_rcv_nxt(1); - - /* Parse the TCP MSS option, if present. */ - if((BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = uip_connr->mss = - tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - - /* Our response will be a SYNACK. */ -#if UIP_ACTIVE_OPEN - tcp_send_synack: - BUF->flags = TCP_ACK; - - tcp_send_syn: - BUF->flags |= TCP_SYN; -#else /* UIP_ACTIVE_OPEN */ - tcp_send_synack: - BUF->flags = TCP_SYN | TCP_ACK; -#endif /* UIP_ACTIVE_OPEN */ - - /* We send out the TCP Maximum Segment Size option with our - SYNACK. */ - BUF->optdata[0] = TCP_OPT_MSS; - BUF->optdata[1] = TCP_OPT_MSS_LEN; - BUF->optdata[2] = (UIP_TCP_MSS) / 256; - BUF->optdata[3] = (UIP_TCP_MSS) & 255; - uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; - BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; - goto tcp_send; - - /* This label will be jumped to if we found an active connection. */ - found: - uip_conn = uip_connr; - uip_flags = 0; - /* We do a very naive form of TCP reset processing; we just accept - any RST and kill our connection. We should in fact check if the - sequence number of this reset is wihtin our advertised window - before we accept the reset. */ - if(BUF->flags & TCP_RST) { - uip_connr->tcpstateflags = UIP_CLOSED; - UIP_LOG("tcp: got reset, aborting connection."); - uip_flags = UIP_ABORT; - UIP_APPCALL(); - goto drop; - } - /* Calculated the length of the data, if the application has sent - any data to us. */ - c = (BUF->tcpoffset >> 4) << 2; - /* uip_len will contain the length of the actual TCP data. This is - calculated by subtracing the length of the TCP header (in - c) and the length of the IP header (20 bytes). */ - uip_len = uip_len - c - UIP_IPH_LEN; - - /* First, check if the sequence number of the incoming packet is - what we're expecting next. If not, we send out an ACK with the - correct numbers in. */ - if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && - ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { - if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && - (BUF->seqno[0] != uip_connr->rcv_nxt[0] || - BUF->seqno[1] != uip_connr->rcv_nxt[1] || - BUF->seqno[2] != uip_connr->rcv_nxt[2] || - BUF->seqno[3] != uip_connr->rcv_nxt[3])) { - goto tcp_send_ack; - } - } - - /* Next, check if the incoming segment acknowledges any outstanding - data. If so, we update the sequence number, reset the length of - the outstanding data, calculate RTT estimations, and reset the - retransmission timer. */ - if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) { - uip_add32(uip_connr->snd_nxt, uip_connr->len); - - if(BUF->ackno[0] == uip_acc32[0] && - BUF->ackno[1] == uip_acc32[1] && - BUF->ackno[2] == uip_acc32[2] && - BUF->ackno[3] == uip_acc32[3]) { - /* Update sequence number. */ - uip_connr->snd_nxt[0] = uip_acc32[0]; - uip_connr->snd_nxt[1] = uip_acc32[1]; - uip_connr->snd_nxt[2] = uip_acc32[2]; - uip_connr->snd_nxt[3] = uip_acc32[3]; - - - /* Do RTT estimation, unless we have done retransmissions. */ - if(uip_connr->nrtx == 0) { - signed char m; - m = uip_connr->rto - uip_connr->timer; - /* This is taken directly from VJs original code in his paper */ - m = m - (uip_connr->sa >> 3); - uip_connr->sa += m; - if(m < 0) { - m = -m; - } - m = m - (uip_connr->sv >> 2); - uip_connr->sv += m; - uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; - - } - /* Set the acknowledged flag. */ - uip_flags = UIP_ACKDATA; - /* Reset the retransmission timer. */ - uip_connr->timer = uip_connr->rto; - - /* Reset length of outstanding data. */ - uip_connr->len = 0; - } - - } - - /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not - implemented, since we force the application to close when the - peer sends a FIN (hence the application goes directly from - ESTABLISHED to LAST_ACK). */ - case UIP_SYN_RCVD: - /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and - we are waiting for an ACK that acknowledges the data we sent - out the last time. Therefore, we want to have the UIP_ACKDATA - flag set. If so, we enter the ESTABLISHED state. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_flags = UIP_CONNECTED; - uip_connr->len = 0; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - uip_slen = 0; - UIP_APPCALL(); - goto appsend; - } - goto drop; -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In SYN_SENT, we wait for a SYNACK that is sent in response to - our SYN. The rcv_nxt is set to sequence number in the SYNACK - plus one, and we send an ACK. We move into the ESTABLISHED - state. */ - if((uip_flags & UIP_ACKDATA) && - (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { - - /* Parse the TCP MSS option, if present. */ - if((BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = - uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->rcv_nxt[0] = BUF->seqno[0]; - uip_connr->rcv_nxt[1] = BUF->seqno[1]; - uip_connr->rcv_nxt[2] = BUF->seqno[2]; - uip_connr->rcv_nxt[3] = BUF->seqno[3]; - uip_add_rcv_nxt(1); - uip_flags = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - uip_len = 0; - uip_slen = 0; - UIP_APPCALL(); - goto appsend; - } - /* Inform the application that the connection failed */ - uip_flags = UIP_ABORT; - UIP_APPCALL(); - /* The connection is closed after we send the RST */ - uip_conn->tcpstateflags = UIP_CLOSED; - goto reset; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application to feed - data into the uip_buf. If the UIP_ACKDATA flag is set, the - application should put new data into the buffer, otherwise we are - retransmitting an old segment, and the application should put that - data into the buffer. - - If the incoming packet is a FIN, we should close the connection on - this side as well, and we send out a FIN and enter the LAST_ACK - state. We require that there is no outstanding data; otherwise the - sequence numbers will be screwed up. */ - - if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - if(uip_outstanding(uip_connr)) { - goto drop; - } - uip_add_rcv_nxt(1 + uip_len); - uip_flags |= UIP_CLOSE; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - } - UIP_APPCALL(); - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_LAST_ACK; - uip_connr->nrtx = 0; - tcp_send_finack: - BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* Check the URG flag. If this is set, the segment carries urgent - data that we must pass to the application. */ - if((BUF->flags & TCP_URG) != 0) { -#if UIP_URGDATA > 0 - uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1]; - if(uip_urglen > uip_len) { - /* There is more urgent data in the next segment to come. */ - uip_urglen = uip_len; - } - uip_add_rcv_nxt(uip_urglen); - uip_len -= uip_urglen; - uip_urgdata = uip_appdata; - uip_appdata += uip_urglen; - } else { - uip_urglen = 0; -#else /* UIP_URGDATA > 0 */ - uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]); - uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1]; -#endif /* UIP_URGDATA > 0 */ - } - - /* If uip_len > 0 we have TCP data in the packet, and we flag this - by setting the UIP_NEWDATA flag and update the sequence number - we acknowledge. If the application has stopped the dataflow - using uip_stop(), we must not accept any data packets from the - remote host. */ - if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - - /* Check if the available buffer space advertised by the other end - is smaller than the initial MSS for this connection. If so, we - set the current MSS to the window size to ensure that the - application does not send more data than the other end can - handle. - - If the remote host advertises a zero window, we set the MSS to - the initial MSS so that the application will send an entire MSS - of data. This data will not be acknowledged by the receiver, - and the application will retransmit it. This is called the - "persistent timer" and uses the retransmission mechanim. - */ - tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1]; - if(tmp16 > uip_connr->initialmss || - tmp16 == 0) { - tmp16 = uip_connr->initialmss; - } - uip_connr->mss = tmp16; - - /* If this packet constitutes an ACK for outstanding data (flagged - by the UIP_ACKDATA flag, we should call the application since it - might want to send more data. If the incoming packet had data - from the peer (as flagged by the UIP_NEWDATA flag), the - application must also be notified. - - When the application is called, the global variable uip_len - contains the length of the incoming data. The application can - access the incoming data through the global pointer - uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN - bytes into the uip_buf array. - - If the application wishes to send any data, this data should be - put into the uip_appdata and the length of the data should be - put into uip_len. If the application don't have any data to - send, uip_len must be set to 0. */ - if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { - uip_slen = 0; - UIP_APPCALL(); - - appsend: - - if(uip_flags & UIP_ABORT) { - uip_slen = 0; - uip_connr->tcpstateflags = UIP_CLOSED; - BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - if(uip_flags & UIP_CLOSE) { - uip_slen = 0; - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_FIN_WAIT_1; - uip_connr->nrtx = 0; - BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* If uip_slen > 0, the application has data to be sent. */ - if(uip_slen > 0) { - - /* If the connection has acknowledged data, the contents of - the ->len variable should be discarded. */ - if((uip_flags & UIP_ACKDATA) != 0) { - uip_connr->len = 0; - } - - /* If the ->len variable is non-zero the connection has - already data in transit and cannot send anymore right - now. */ - if(uip_connr->len == 0) { - - /* The application cannot send more than what is allowed by - the mss (the minumum of the MSS and the available - window). */ - if(uip_slen > uip_connr->mss) { - uip_slen = uip_connr->mss; - } - - /* Remember how much data we send out now so that we know - when everything has been acknowledged. */ - uip_connr->len = uip_slen; - } else { - - /* If the application already had unacknowledged data, we - make sure that the application does not send (i.e., - retransmit) out more than it previously sent out. */ - uip_slen = uip_connr->len; - } - } - uip_connr->nrtx = 0; - apprexmit: - uip_appdata = uip_sappdata; - - /* If the application has data to be sent, or if the incoming - packet had new data in it, we must send out a packet. */ - if(uip_slen > 0 && uip_connr->len > 0) { - /* Add the length of the IP and TCP headers. */ - uip_len = uip_connr->len + UIP_TCPIP_HLEN; - /* We always set the ACK flag in response packets. */ - BUF->flags = TCP_ACK | TCP_PSH; - /* Send the packet. */ - goto tcp_send_noopts; - } - /* If there is no data to send, just send out a pure ACK if - there is newdata. */ - if(uip_flags & UIP_NEWDATA) { - uip_len = UIP_TCPIP_HLEN; - BUF->flags = TCP_ACK; - goto tcp_send_noopts; - } - } - goto drop; - case UIP_LAST_ACK: - /* We can close this connection if the peer has acknowledged our - FIN. This is indicated by the UIP_ACKDATA flag. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_CLOSED; - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - } - break; - - case UIP_FIN_WAIT_1: - /* The application has closed the connection, but the remote host - hasn't closed its end yet. Thus we do nothing but wait for a - FIN from the other side. */ - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(BUF->flags & TCP_FIN) { - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; - } else { - uip_connr->tcpstateflags = UIP_CLOSING; - } - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } else if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_FIN_WAIT_2; - uip_connr->len = 0; - goto drop; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_FIN_WAIT_2: - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(BUF->flags & TCP_FIN) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_TIME_WAIT: - goto tcp_send_ack; - - case UIP_CLOSING: - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - } - } - goto drop; - - - /* We jump here when we are ready to send the packet, and just want - to set the appropriate TCP sequence numbers in the TCP header. */ - tcp_send_ack: - BUF->flags = TCP_ACK; - tcp_send_nodata: - uip_len = UIP_IPTCPH_LEN; - tcp_send_noopts: - BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; - tcp_send: - /* We're done with the input processing. We are now ready to send a - reply. Our job is to fill in all the fields of the TCP and IP - headers before calculating the checksum and finally send the - packet. */ - BUF->ackno[0] = uip_connr->rcv_nxt[0]; - BUF->ackno[1] = uip_connr->rcv_nxt[1]; - BUF->ackno[2] = uip_connr->rcv_nxt[2]; - BUF->ackno[3] = uip_connr->rcv_nxt[3]; - - BUF->seqno[0] = uip_connr->snd_nxt[0]; - BUF->seqno[1] = uip_connr->snd_nxt[1]; - BUF->seqno[2] = uip_connr->snd_nxt[2]; - BUF->seqno[3] = uip_connr->snd_nxt[3]; - - BUF->proto = UIP_PROTO_TCP; - - BUF->srcport = uip_connr->lport; - BUF->destport = uip_connr->rport; - - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); - - if(uip_connr->tcpstateflags & UIP_STOPPED) { - /* If the connection has issued uip_stop(), we advertise a zero - window so that the remote host will stop sending data. */ - BUF->wnd[0] = BUF->wnd[1] = 0; - } else { - BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); - BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); - } - - tcp_send_noconn: - BUF->ttl = UIP_TTL; -#if UIP_CONF_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ - BUF->len[0] = (uip_len >> 8); - BUF->len[1] = (uip_len & 0xff); -#endif /* UIP_CONF_IPV6 */ - - BUF->urgp[0] = BUF->urgp[1] = 0; - - /* Calculate TCP checksum. */ - BUF->tcpchksum = 0; - BUF->tcpchksum = ~(uip_tcpchksum()); - - ip_send_nolen: - -#if UIP_CONF_IPV6 - BUF->vtc = 0x60; - BUF->tcflow = 0x00; - BUF->flow = 0x00; -#else /* UIP_CONF_IPV6 */ - BUF->vhl = 0x45; - BUF->tos = 0; - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - ++ipid; - BUF->ipid[0] = ipid >> 8; - BUF->ipid[1] = ipid & 0xff; - /* Calculate IP checksum. */ - BUF->ipchksum = 0; - BUF->ipchksum = ~(uip_ipchksum()); - DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); -#endif /* UIP_CONF_IPV6 */ - - UIP_STAT(++uip_stat.tcp.sent); - send: - DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, - (BUF->len[0] << 8) | BUF->len[1]); - - UIP_STAT(++uip_stat.ip.sent); - /* Return and let the caller do the actual transmission. */ - uip_flags = 0; - return; - drop: - uip_len = 0; - uip_flags = 0; - return; -} -/*---------------------------------------------------------------------------*/ -u16_t -htons(u16_t val) -{ - return HTONS(val); -} -/*---------------------------------------------------------------------------*/ -void -uip_send(const void *data, int len) -{ - uip_slen = len; - if(len > 0) { - if(data != uip_sappdata) { - memcpy(uip_sappdata, (data), uip_slen); - } - } -} -/** @} */ diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip.h deleted file mode 100644 index 4fc0452..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip_arch.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip_arch.h deleted file mode 100644 index 71fd84b..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip_arp.c b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip_arp.c deleted file mode 100644 index 86b4df8..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip_arp.c +++ /dev/null @@ -1,422 +0,0 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uiparp uIP Address Resolution Protocol - * @{ - * - * The Address Resolution Protocol ARP is used for mapping between IP - * addresses and link level addresses such as the Ethernet MAC - * addresses. ARP uses broadcast queries to ask for the link level - * address of a known IP address and the host which is configured with - * the IP address for which the query was meant, will respond with its - * link level address. - * - * \note This ARP implementation only supports Ethernet. - */ - -/** - * \file - * Implementation of the ARP Address Resolution Protocol. - * \author Adam Dunkels - * - */ - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $ - * - */ - - -#include "uip_arp.h" - -#include - -struct arp_hdr { - struct uip_eth_hdr ethhdr; - u16_t hwtype; - u16_t protocol; - u8_t hwlen; - u8_t protolen; - u16_t opcode; - struct uip_eth_addr shwaddr; - u16_t sipaddr[2]; - struct uip_eth_addr dhwaddr; - u16_t dipaddr[2]; -}; - -struct ethip_hdr { - struct uip_eth_hdr ethhdr; - /* IP header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; -}; - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -#define ARP_HWTYPE_ETH 1 - -struct arp_entry { - u16_t ipaddr[2]; - struct uip_eth_addr ethaddr; - u8_t time; -}; - -static const struct uip_eth_addr broadcast_ethaddr = - {{0xff,0xff,0xff,0xff,0xff,0xff}}; -static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; - -static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; -static u16_t ipaddr[2]; -static u8_t i, c; - -static u8_t arptime; -static u8_t tmpage; - -#define BUF ((struct arp_hdr *)&uip_buf[0]) -#define IPBUF ((struct ethip_hdr *)&uip_buf[0]) -/*-----------------------------------------------------------------------------------*/ -/** - * Initialize the ARP module. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_init(void) -{ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - memset(arp_table[i].ipaddr, 0, 4); - } -} -/*-----------------------------------------------------------------------------------*/ -/** - * Periodic ARP processing function. - * - * This function performs periodic timer processing in the ARP module - * and should be called at regular intervals. The recommended interval - * is 10 seconds between the calls. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_timer(void) -{ - struct arp_entry *tabptr; - - ++arptime; - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && - arptime - tabptr->time >= UIP_ARP_MAXAGE) { - memset(tabptr->ipaddr, 0, 4); - } - } - -} -/*-----------------------------------------------------------------------------------*/ -static void -uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) -{ - register struct arp_entry *tabptr; - /* Walk through the ARP mapping table and try to find an entry to - update. If none is found, the IP -> MAC address mapping is - inserted in the ARP table. */ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - - tabptr = &arp_table[i]; - /* Only check those entries that are actually in use. */ - if(tabptr->ipaddr[0] != 0 && - tabptr->ipaddr[1] != 0) { - - /* Check if the source IP address of the incoming packet matches - the IP address in this ARP table entry. */ - if(memcmp(ipaddr, tabptr->ipaddr, 4) == 0) { - - /* 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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip_arp.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uip_arp.h deleted file mode 100644 index ef93054..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uipethernet-conf.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uipethernet-conf.h deleted file mode 100644 index 6387091..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uipethernet-conf.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef UIPETHERNET_CONF_H -#define UIPETHERNET_CONF_H - -// https://github.com/jandrassy/EthernetENC/wiki/Settings - -/* for TCP */ -#ifndef UIP_SOCKET_NUMPACKETS -#define UIP_SOCKET_NUMPACKETS 3 -#endif -#ifndef UIP_CONF_MAX_CONNECTIONS -#define UIP_CONF_MAX_CONNECTIONS 4 -#endif - -/* for UDP - * set UIP_CONF_UDP to 0 to disable UDP (saves aprox. 4kB flash) */ -#ifndef UIP_CONF_UDP -#define UIP_CONF_UDP 1 -#endif -#ifndef UIP_CONF_UDP_CONNS -#define UIP_CONF_UDP_CONNS 2 -#endif - -/** - * size of received UDP messages backlog. it must be at least 1 - */ -#ifndef UIP_UDP_BACKLOG -#define UIP_UDP_BACKLOG 2 -#endif - -/* timeout in ms for attempts to get a free memory block to write - * before returning number of bytes sent so far - * set to 0 to block until connection is closed by timeout */ -#ifndef UIP_WRITE_TIMEOUT -#define UIP_WRITE_TIMEOUT 2000 -#endif - -/* 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...) */ -#ifndef UIP_CONNECT_TIMEOUT -#define UIP_CONNECT_TIMEOUT 5 -#endif - -/* periodic timer for uip (in ms) */ -#ifndef UIP_PERIODIC_TIMER -#define UIP_PERIODIC_TIMER 100 -#endif - -#endif diff --git a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uipopt.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uipopt.h deleted file mode 100644 index 945decd..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/uipopt.h +++ /dev/null @@ -1,555 +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 - #if defined(LITTLE_ENDIAN) - #define UIP_LITTLE_ENDIAN LITTLE_ENDIAN - #elif defined(__ORDER_LITTLE_ENDIAN__) - #define UIP_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ - #else - #define UIP_LITTLE_ENDIAN 1234 - #endif -#endif /* UIP_LITTLE_ENDIAN */ -#ifndef UIP_BIG_ENDIAN - #if defined(BIG_ENDIAN) - #define UIP_BIG_ENDIAN BIG_ENDIAN - #elif defined(__ORDER_BIG_ENDIAN__) - #define UIP_BIG_ENDIAN __ORDER_BIG_ENDIAN__ - #else - #define UIP_BIG_ENDIAN 4321 - #endif -#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/ShineLAN-X/firmware/lib/EthernetENC/src/utility/util.h b/ShineLAN-X/firmware/lib/EthernetENC/src/utility/util.h deleted file mode 100644 index 11e4242..0000000 --- a/ShineLAN-X/firmware/lib/EthernetENC/src/utility/util.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ - ((x)<< 8 & 0x00FF0000UL) | \ - ((x)>> 8 & 0x0000FF00UL) | \ - ((x)>>24 & 0x000000FFUL) ) -#define ntohl(x) htonl(x) - -#endif diff --git a/ShineLAN-X/firmware/platformio.ini b/ShineLAN-X/firmware/platformio.ini deleted file mode 100644 index 826935a..0000000 --- a/ShineLAN-X/firmware/platformio.ini +++ /dev/null @@ -1,22 +0,0 @@ -[env:growatt-shinelan] -platform = ststm32 -board = genericSTM32F103RB -framework = arduino -upload_protocol = stlink -debug_tool = stlink -monitor_speed = 115200 - -lib_deps = - 4-20ma/ModbusMaster@^2.0.1 - knolleary/PubSubClient@^2.8 - # EthernetENC ist lokal in lib/EthernetENC/ (Bitbang-SPI Modifikation) - -build_flags = - -DPIO_FRAMEWORK_ARDUINO_NOERRNO - -DUSBCON - -DUSBD_USE_CDC - -DHAL_PCD_MODULE_ENABLED - -DUSB_CDC_TRANSMIT_TIMEOUT=3000 - -DCUSTOM_USBD_PID=0x5740 - '-DUSB_PRODUCT_STRING="STM32 Virtual COM Port"' - -I include diff --git a/ShineLAN-X/firmware/src/main.cpp b/ShineLAN-X/firmware/src/main.cpp deleted file mode 100644 index f865faa..0000000 --- a/ShineLAN-X/firmware/src/main.cpp +++ /dev/null @@ -1,712 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "config_manager.h" - -extern "C" void SystemClock_Config(void) { - RCC_OscInitTypeDef osc = {}; - RCC_ClkInitTypeDef clk = {}; - RCC_PeriphCLKInitTypeDef periphClk = {}; - - osc.OscillatorType = RCC_OSCILLATORTYPE_HSE; - osc.HSEState = RCC_HSE_ON; - osc.PLL.PLLState = RCC_PLL_ON; - osc.PLL.PLLSource = RCC_PLLSOURCE_HSE; - osc.PLL.PLLMUL = RCC_PLL_MUL9; - if (HAL_RCC_OscConfig(&osc) == HAL_OK) { - clk.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK - | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; - clk.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - clk.AHBCLKDivider = RCC_SYSCLK_DIV1; - clk.APB1CLKDivider = RCC_HCLK_DIV2; - clk.APB2CLKDivider = RCC_HCLK_DIV1; - HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_2); - periphClk.PeriphClockSelection = RCC_PERIPHCLK_USB; - periphClk.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; - HAL_RCCEx_PeriphCLKConfig(&periphClk); - } else { - osc.OscillatorType = RCC_OSCILLATORTYPE_HSI; - osc.HSEState = RCC_HSE_OFF; - osc.HSIState = RCC_HSI_ON; - osc.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; - osc.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; - osc.PLL.PLLMUL = RCC_PLL_MUL12; - HAL_RCC_OscConfig(&osc); - clk.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK - | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; - clk.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - clk.AHBCLKDivider = RCC_SYSCLK_DIV1; - clk.APB1CLKDivider = RCC_HCLK_DIV2; - clk.APB2CLKDivider = RCC_HCLK_DIV1; - HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_1); - periphClk.PeriphClockSelection = RCC_PERIPHCLK_USB; - periphClk.UsbClockSelection = RCC_USBCLKSOURCE_PLL; - HAL_RCCEx_PeriphCLKConfig(&periphClk); - } -} - -// Hält PA8 HIGH (USB getrennt) bis setup() es manuell verbindet -extern "C" void USBD_reenumerate(void) { - __HAL_RCC_GPIOA_CLK_ENABLE(); - GPIO_InitTypeDef gpio = {}; - gpio.Pin = GPIO_PIN_8; - gpio.Mode = GPIO_MODE_OUTPUT_PP; - gpio.Pull = GPIO_NOPULL; - gpio.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(GPIOA, &gpio); - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); -} - -HardwareSerial DebugSerial(PA10, PA9); - -// USB-Diagnose: was der Wechselrichter per Control-Transfer schickt -extern __IO bool dtrState; -extern __IO bool rtsState; -struct { uint32_t baud; uint8_t format; uint8_t parity; uint8_t bits; } - g_lineCoding = {115200, 0, 0, 8}; -volatile bool g_lineCodingUpdated = false; - -// Wird vom USB-Stack aufgerufen wenn Wechselrichter SET_LINE_CODING schickt -// usbd_cdc_if.c kann nicht geändert werden → wir lesen linecoding-Struct direkt -extern "C" { - typedef struct { uint32_t bitrate; uint8_t format; uint8_t paritytype; uint8_t datatype; } - USBD_CDC_LineCodingTypeDef; - extern USBD_CDC_LineCodingTypeDef linecoding; -} - -// CDC SERIAL_STATE Notification — NuttX sendet dies beim Öffnen von /dev/ttyACM0 -// signalisiert dem Wechselrichter DCD+DSR=1 → startet Modbus-Server im Inverter -#include "usbd_core.h" -extern USBD_HandleTypeDef hUSBD_Device_CDC; - -#define CDC_SERIAL_STATE_EP 0x82U - -void sendSerialStateNotification() { - static uint8_t notif[10] = { - 0xA1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00 - }; - USBD_LL_Transmit(&hUSBD_Device_CDC, CDC_SERIAL_STATE_EP, notif, sizeof(notif)); -} - -// ModbusMaster schreibt Byte-für-Byte. Würden wir sofort senden, käme Byte 1 als -// eigenes 1-Byte USB-Paket an — der Wechselrichter behandelt jedes Short Packet -// als Frame-Ende und sieht keinen gültigen Modbus-Frame. -// Lösung: Bytes puffern, dann in flush() als ein einziges USB-Paket senden. -class ModbusStream : public Stream { -public: - uint8_t txBuf[16]; uint8_t txLen = 0; - uint8_t rxBuf[32]; uint8_t rxLen = 0; - uint32_t rxTotal = 0; - void reset() { txLen = 0; rxLen = 0; } - - int available() override { return SerialUSB.available(); } - int read() override { - int b = SerialUSB.read(); - if (b >= 0) { rxTotal++; if (rxLen < sizeof(rxBuf)) rxBuf[rxLen++] = (uint8_t)b; } - return b; - } - int peek() override { return SerialUSB.peek(); } - size_t write(uint8_t b) override { - if (txLen < sizeof(txBuf)) txBuf[txLen++] = b; - return 1; - } - size_t write(const uint8_t* buf, size_t size) override { - for (size_t i = 0; i < size && txLen < sizeof(txBuf); i++) txBuf[txLen++] = buf[i]; - return size; - } - void flush() override { - if (txLen > 0) SerialUSB.write(txBuf, txLen); - // txLen nicht zurücksetzen — Debug-Code liest txBuf danach noch - } - using Print::write; -} modbusSerial; - -// ============================================================ -// Sensor-Definitionen -// ============================================================ -struct Sensor { - const char* id; - const char* name; - uint16_t address; - bool isDword; - float scale; - const char* unit; - const char* deviceClass; - const char* stateClass; - const char* icon; -}; - -#if defined(INVERTER_MIC1500) -const Sensor SENSORS[] = { - {"pv_voltage", "PV Voltage", 3, false, 0.1f, "V", "voltage", "measurement", "mdi:solar-panel"}, - {"pv_current", "PV Current", 4, false, 0.1f, "A", "current", "measurement", "mdi:solar-panel"}, - {"pv_power", "PV Power", 5, true, 0.1f, "W", "power", "measurement", "mdi:solar-panel"}, - {"grid_frequency", "Grid Frequency", 37, false, 0.01f, "Hz", "frequency", "measurement", "mdi:sine-wave"}, - {"grid_voltage", "Grid Voltage", 38, false, 0.1f, "V", "voltage", "measurement", "mdi:flash"}, - {"grid_current", "Grid Current", 39, false, 0.1f, "A", "current", "measurement", "mdi:flash"}, - {"ac_power", "AC Output Power", 40, true, 0.1f, "W", "power", "measurement", "mdi:flash"}, - {"energy_today", "Energy Today", 53, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:solar-power"}, - {"energy_total", "Energy Total", 55, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:solar-power"}, - {"inverter_temp", "Inverter Temperature", 93, false, 0.1f, "°C", "temperature", "measurement", "mdi:thermometer"}, -}; -#elif defined(INVERTER_SPH5000) -const Sensor SENSORS[] = { - {"pv1_voltage", "PV1 Voltage", 3, false, 0.1f, "V", "voltage", "measurement", "mdi:solar-panel"}, - {"pv1_current", "PV1 Current", 4, false, 0.1f, "A", "current", "measurement", "mdi:solar-panel"}, - {"pv1_power", "PV1 Power", 5, true, 0.1f, "W", "power", "measurement", "mdi:solar-panel"}, - {"pv2_voltage", "PV2 Voltage", 7, false, 0.1f, "V", "voltage", "measurement", "mdi:solar-panel"}, - {"pv2_current", "PV2 Current", 8, false, 0.1f, "A", "current", "measurement", "mdi:solar-panel"}, - {"pv2_power", "PV2 Power", 9, true, 0.1f, "W", "power", "measurement", "mdi:solar-panel"}, - {"ac_power_total", "AC Output Power Total", 35, true, 0.1f, "W", "power", "measurement", "mdi:flash"}, - {"grid_frequency", "Grid Frequency", 37, false, 0.01f, "Hz", "frequency", "measurement", "mdi:sine-wave"}, - {"grid_voltage_l1", "Grid Voltage L1", 38, false, 0.1f, "V", "voltage", "measurement", "mdi:flash"}, - {"grid_current_l1", "Grid Current L1", 39, false, 0.1f, "A", "current", "measurement", "mdi:flash"}, - {"grid_voltage_l2", "Grid Voltage L2", 42, false, 0.1f, "V", "voltage", "measurement", "mdi:flash"}, - {"grid_current_l2", "Grid Current L2", 43, false, 0.1f, "A", "current", "measurement", "mdi:flash"}, - {"grid_voltage_l3", "Grid Voltage L3", 46, false, 0.1f, "V", "voltage", "measurement", "mdi:flash"}, - {"grid_current_l3", "Grid Current L3", 47, false, 0.1f, "A", "current", "measurement", "mdi:flash"}, - {"energy_today", "Energy Today", 53, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:solar-power"}, - {"energy_total", "Energy Total", 55, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:solar-power"}, - {"inverter_temp", "Inverter Temperature", 93, false, 0.1f, "°C", "temperature", "measurement", "mdi:thermometer"}, - {"bat_discharge_power", "Battery Discharge Power", 1009, true, 0.1f, "W", "power", "measurement", "mdi:battery-minus"}, - {"bat_charge_power", "Battery Charge Power", 1011, true, 0.1f, "W", "power", "measurement", "mdi:battery-plus"}, - {"bat_voltage", "Battery Voltage", 1013, false, 0.1f, "V", "voltage", "measurement", "mdi:battery"}, - {"bat_soc", "Battery State of Charge", 1014, false, 1.0f, "%", "battery", "measurement", "mdi:battery"}, - {"bat_temperature", "Battery Temperature", 1040, false, 0.1f, "°C", "temperature", "measurement", "mdi:thermometer"}, - {"power_to_grid", "Power To Grid", 1021, true, 0.1f, "W", "power", "measurement", "mdi:transmission-tower-export"}, - {"power_to_user", "Power To User", 1029, true, 0.1f, "W", "power", "measurement", "mdi:transmission-tower-import"}, - {"energy_import_total", "Energy Import Total", 1046, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:transmission-tower-import"}, - {"energy_export_total", "Energy Export Total", 1050, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:transmission-tower-export"}, - {"bat_discharge_total", "Battery Discharge Total", 1054, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:battery-minus"}, - {"bat_charge_total", "Battery Charge Total", 1058, true, 0.1f, "kWh", "energy", "total_increasing", "mdi:battery-plus"}, -}; -#else - #error "Kein Inverter-Modell definiert! INVERTER_MIC1500 oder INVERTER_SPH5000 in config.h setzen." -#endif -const uint8_t SENSOR_COUNT = sizeof(SENSORS) / sizeof(SENSORS[0]); - -// ============================================================ -// Globale Objekte -// ============================================================ -NetConfig cfg; -byte mac[] = {MAC_ADDRESS}; -EthernetClient ethClient; -PubSubClient mqtt(ethClient); -ModbusMaster modbus; -EthernetServer webServer(80); - -uint32_t g_okTotal = 0; -uint32_t g_failTotal = 0; -uint8_t g_lastErr = 0; -uint32_t g_rawTotal = 0; - -// ============================================================ -// Web-Server -// ============================================================ - -static bool webReadLine(EthernetClient& c, char* buf, size_t maxLen) { - size_t i = 0; - uint32_t t = millis(); - while (millis() - t < 1000) { - while (c.available()) { - char ch = c.read(); - if (ch == '\n') { buf[i] = 0; return true; } - if (ch != '\r' && i < maxLen - 1) buf[i++] = ch; - t = millis(); - } - } - buf[i] = 0; - return false; -} - -static void ipToStr(const uint8_t ip[4], char* buf) { - snprintf(buf, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); -} - -static void urlDecode(char* s) { - char* out = s; - while (*s) { - if (*s == '+') { - *out++ = ' '; s++; - } else if (*s == '%' && s[1] && s[2]) { - char h[3] = {s[1], s[2], 0}; - *out++ = (char)strtol(h, nullptr, 16); - s += 3; - } else { - *out++ = *s++; - } - } - *out = 0; -} - -static void parseIP(const char* s, uint8_t out[4]) { - unsigned a = 0, b = 0, c = 0, d = 0; - if (sscanf(s, "%u.%u.%u.%u", &a, &b, &c, &d) == 4) { - out[0] = a; out[1] = b; out[2] = c; out[3] = d; - } -} - -static void parseFormBody(char* body) { - cfg.useDhcp = false; // Checkbox fehlt im POST wenn nicht gesetzt - char* p = body; - while (p && *p) { - char* eq = strchr(p, '='); - char* amp = strchr(p, '&'); - if (!eq) break; - *eq = 0; - if (amp) *amp = 0; - char* key = p; - char* val = eq + 1; - urlDecode(key); - urlDecode(val); - - if (!strcmp(key, "dhcp")) cfg.useDhcp = true; - else if (!strcmp(key, "ip")) parseIP(val, cfg.ip); - else if (!strcmp(key, "gw")) parseIP(val, cfg.gw); - else if (!strcmp(key, "sn")) parseIP(val, cfg.sn); - else if (!strcmp(key, "dns")) parseIP(val, cfg.dns); - else if (!strcmp(key, "broker")) strncpy(cfg.mqttBroker, val, sizeof(cfg.mqttBroker) - 1); - else if (!strcmp(key, "port")) cfg.mqttPort = (uint16_t)atoi(val); - else if (!strcmp(key, "user")) strncpy(cfg.mqttUser, val, sizeof(cfg.mqttUser) - 1); - else if (!strcmp(key, "pass")) strncpy(cfg.mqttPass, val, sizeof(cfg.mqttPass) - 1); - else if (!strcmp(key, "interval")) cfg.updateMs = (uint32_t)atoi(val) * 1000UL; - - p = amp ? amp + 1 : nullptr; - } -} - -static void sendPage(EthernetClient& cl) { - char buf[16]; - - cl.print( - "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n" - "" - "" - "" - "ShineLAN-X" - ); - - // Header - cl.print("

☀ ShineLAN-X

" - "
Growatt Modbus → MQTT Bridge
" - "
Verbunden" : "off'>Getrennt"); - cl.print("
IP: "); - cl.print(Ethernet.localIP()); - cl.print("
"); - - // Statistik - cl.print("
" - "
"); - cl.print(g_okTotal); - cl.print("
OK
" - "
"); - cl.print(g_failTotal); - cl.print("
Fehler
" - "
0x"); - snprintf(buf, sizeof(buf), "%02X", g_lastErr); - cl.print(buf); - cl.print("
Letzter Err
"); - - // Formular — Netzwerk - cl.print("
" - "

Netzwerk

" - "
" - "
"); - - ipToStr(cfg.ip, buf); - cl.print("
" - "
"); - ipToStr(cfg.gw, buf); - cl.print("
" - "
"); - ipToStr(cfg.sn, buf); - cl.print("
" - "
"); - ipToStr(cfg.dns, buf); - cl.print("
" - "
"); - cl.print("
"); - - // Formular — MQTT - cl.print("

MQTT

" - "
" - "
" - "
" - "
" - "
" - "
" - "
" - "
" - "
" - "
"); - - // Buttons + Script - cl.print( - "" - "" - "
" - "" - ); -} - -static void handleWebRequest() { - EthernetClient client = webServer.available(); - if (!client) return; - - char line[80]; - if (!webReadLine(client, line, sizeof(line))) { client.stop(); return; } - - bool isPost = (strncmp(line, "POST", 4) == 0); - bool isReset = (strstr(line, "/reset") != nullptr); - - // Header lesen, Content-Length suchen (case-insensitive via tolower) - int contentLen = 0; - char hdr[80]; - while (webReadLine(client, hdr, sizeof(hdr)) && hdr[0] != '\0') { - for (char* p = hdr; *p; p++) *p = (char)tolower((unsigned char)*p); - if (strncmp(hdr, "content-length:", 15) == 0) - contentLen = atoi(hdr + 15); - } - - if (isReset) { - configDefaults(cfg); - configSave(cfg); - client.print("HTTP/1.1 303 See Other\r\nLocation: /\r\nConnection: close\r\n\r\n"); - client.flush(); client.stop(); - delay(300); - NVIC_SystemReset(); - return; - } - - if (isPost && contentLen > 0 && contentLen < 500) { - char body[500] = {}; - int n = 0; - uint32_t t = millis(); - while (n < contentLen && millis() - t < 3000) { - if (client.available()) { body[n++] = client.read(); t = millis(); } - } - body[n] = 0; - - parseFormBody(body); - cfg.magic = CFG_MAGIC; - configSave(cfg); - - client.print("HTTP/1.1 303 See Other\r\nLocation: /\r\nConnection: close\r\n\r\n"); - client.flush(); client.stop(); - delay(300); - NVIC_SystemReset(); - return; - } - - sendPage(client); - client.flush(); - client.stop(); -} - -// ============================================================ -// LED -// ============================================================ -void ledSet(uint8_t pin, bool on) { digitalWrite(pin, on ? LOW : HIGH); } - -// ============================================================ -// MQTT -// ============================================================ -void publishDiscovery() { - char topic[128]; - char payload[640]; - - for (uint8_t i = 0; i < SENSOR_COUNT; i++) { - const Sensor& s = SENSORS[i]; - snprintf(topic, sizeof(topic), - "homeassistant/sensor/%s_%s/config", DEVICE_ID, s.id); - snprintf(payload, sizeof(payload), - "{" - "\"name\":\"%s\"," - "\"unique_id\":\"%s_%s\"," - "\"state_topic\":\"growatt/shinelan/%s\"," - "\"unit_of_measurement\":\"%s\"," - "\"device_class\":\"%s\"," - "\"state_class\":\"%s\"," - "\"icon\":\"%s\"," - "\"device\":{" - "\"identifiers\":[\"%s\"]," - "\"name\":\"%s\"," - "\"model\":\"%s\"," - "\"manufacturer\":\"%s\"" - "}}", - s.name, - DEVICE_ID, s.id, - s.id, - s.unit, s.deviceClass, s.stateClass, s.icon, - DEVICE_ID, DEVICE_NAME, DEVICE_MODEL, DEVICE_MFR); - mqtt.publish(topic, payload, true); - } -} - -bool mqttReconnect() { - DebugSerial.print("MQTT connecting... "); - ledSet(LED_RED, true); - bool ok = (strlen(cfg.mqttUser) > 0) - ? mqtt.connect(MQTT_CLIENT, cfg.mqttUser, cfg.mqttPass) - : mqtt.connect(MQTT_CLIENT); - if (ok) { - DebugSerial.println("OK"); - ledSet(LED_RED, false); - ledSet(LED_GREEN, true); - publishDiscovery(); - } else { - DebugSerial.print("FAIL rc="); - DebugSerial.println(mqtt.state()); - } - return ok; -} - -// ============================================================ -// Setup -// ============================================================ -void setup() { - DebugSerial.begin(115200); - delay(10); - DebugSerial.println("\r\n=== Growatt ShineLAN-X ==="); - DebugSerial.println("Build: " __DATE__ " " __TIME__); - - configLoad(cfg); - - pinMode(LED_DEBUG, OUTPUT); ledSet(LED_DEBUG, false); - pinMode(LED_RED, OUTPUT); ledSet(LED_RED, false); - pinMode(LED_GREEN, OUTPUT); ledSet(LED_GREEN, false); - pinMode(LED_BLUE, OUTPUT); ledSet(LED_BLUE, false); - ledSet(LED_RED, true); ledSet(LED_GREEN, true); ledSet(LED_BLUE, true); - delay(300); - ledSet(LED_RED, false); ledSet(LED_GREEN, false); ledSet(LED_BLUE, false); - - pinMode(ETH_RST_PIN, OUTPUT); - digitalWrite(ETH_RST_PIN, LOW); delay(20); - digitalWrite(ETH_RST_PIN, HIGH); delay(200); - Ethernet.init(ETH_CS_PIN); - - if (cfg.useDhcp) { - DebugSerial.println("ETH: DHCP..."); - if (Ethernet.begin(mac) == 0) { - // DHCP fehlgeschlagen: Fallback auf gespeicherte statische IP - DebugSerial.println("ETH: DHCP failed, static fallback"); - IPAddress ip (cfg.ip[0], cfg.ip[1], cfg.ip[2], cfg.ip[3]); - IPAddress gw (cfg.gw[0], cfg.gw[1], cfg.gw[2], cfg.gw[3]); - IPAddress sn (cfg.sn[0], cfg.sn[1], cfg.sn[2], cfg.sn[3]); - IPAddress dns(cfg.dns[0], cfg.dns[1], cfg.dns[2], cfg.dns[3]); - Ethernet.begin(mac, ip, dns, gw, sn); - } - } else { - IPAddress ip (cfg.ip[0], cfg.ip[1], cfg.ip[2], cfg.ip[3]); - IPAddress gw (cfg.gw[0], cfg.gw[1], cfg.gw[2], cfg.gw[3]); - IPAddress sn (cfg.sn[0], cfg.sn[1], cfg.sn[2], cfg.sn[3]); - IPAddress dns(cfg.dns[0], cfg.dns[1], cfg.dns[2], cfg.dns[3]); - Ethernet.begin(mac, ip, dns, gw, sn); - } - - DebugSerial.print("ETH: IP="); - DebugSerial.println(Ethernet.localIP()); - if (Ethernet.linkStatus() == LinkON) ledSet(LED_DEBUG, true); - - webServer.begin(); - DebugSerial.print("Web: http://"); - DebugSerial.println(Ethernet.localIP()); - - mqtt.setServer(cfg.mqttBroker, cfg.mqttPort); - mqtt.setBufferSize(768); - - SerialUSB.begin(MODBUS_BAUD); - delay(10000); - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); - // Warte bis Wechselrichter USB-CDC konfiguriert hat - delay(3000); - // SERIAL_STATE(DCD=1,DSR=1) senden — NuttX tut dies beim Öffnen von ttyACM0 - // signalisiert dem Wechselrichter dass das Device bereit ist - sendSerialStateNotification(); - delay(500); - modbus.begin(MODBUS_ADDR, modbusSerial); - - DebugSerial.println("Setup done."); -} - -// ============================================================ -// Loop -// ============================================================ -unsigned long lastUpdate = 0; -static bool g_usbInfoPublished = false; - -void loop() { - handleWebRequest(); - - if (!mqtt.connected()) { - if (!mqttReconnect()) { - delay(5000); - return; - } - } - mqtt.loop(); - handleWebRequest(); - - // usbinfo: initial publish + DTR-Änderungen - { - static bool lastDtr = false; - if (!g_usbInfoPublished || (bool)dtrState != lastDtr) { - g_usbInfoPublished = true; - lastDtr = (bool)dtrState; - char info[80]; - snprintf(info, sizeof(info), "baud=%lu fmt=%u par=%u bits=%u dtr=%d rts=%d", - (unsigned long)linecoding.bitrate, linecoding.format, - linecoding.paritytype, linecoding.datatype, - (int)dtrState, (int)rtsState); - mqtt.publish("growatt/shinelan/usbinfo", info, true); - } - } - - // SERIAL_STATE(DCD=1,DSR=1) alle 5s senden bis DTR vom Wechselrichter gesetzt wird - { - static uint32_t lastNotif = 0; - if (!dtrState && millis() - lastNotif > 5000) { - lastNotif = millis(); - sendSerialStateNotification(); - } - } - - // Raw-RX-Drain: jedes Byte das außerhalb von Modbus-Fenstern ankommt fangen - // Beantwortet: sendet der Inverter JEMALS irgendwas (spontan oder verspätet)? - { - static uint8_t rawBuf[32] = {}; - static uint8_t rawLen = 0; - static uint32_t rawPublish = 0; - while (SerialUSB.available()) { - uint8_t b = (uint8_t)SerialUSB.read(); - g_rawTotal++; - if (rawLen < sizeof(rawBuf)) rawBuf[rawLen++] = b; - } - if (rawLen > 0 && millis() - rawPublish > 1000) { - rawPublish = millis(); - char msg[80]; - size_t p = snprintf(msg, sizeof(msg), "raw=%lu: ", g_rawTotal); - for (uint8_t i = 0; i < rawLen && p < 74; i++) - p += snprintf(msg + p, sizeof(msg) - p, "%02X", rawBuf[i]); - mqtt.publish("growatt/shinelan/rawbytes", msg); - rawLen = 0; - } - } - - if (millis() - lastUpdate < cfg.updateMs) return; - lastUpdate = millis(); - - ledSet(LED_BLUE, true); - - uint32_t okCnt = 0, failCnt = 0; - uint8_t lastErr = 0; - uint16_t lastErrReg = 0; - - for (uint8_t i = 0; i < SENSOR_COUNT; i++) { - const Sensor& s = SENSORS[i]; - modbusSerial.reset(); - - uint8_t res = modbus.readInputRegisters(s.address, s.isDword ? 2 : 1); - - char dbg[80]; - size_t pos = snprintf(dbg, sizeof(dbg), "ok=%lu fail=%lu err=0x%02X@%u avS=%d dtr=%d raw=%lu rx=%u tx=", - g_okTotal + okCnt, g_failTotal + failCnt, - lastErr, lastErrReg, - SerialUSB.availableForWrite(), - (int)dtrState, - g_rawTotal, - modbusSerial.rxLen); - for (uint8_t j = 0; j < modbusSerial.txLen && pos < 74; j++) - pos += snprintf(dbg + pos, sizeof(dbg) - pos, "%02X", modbusSerial.txBuf[j]); - pos += snprintf(dbg + pos, sizeof(dbg) - pos, " rx="); - for (uint8_t j = 0; j < modbusSerial.rxLen && pos < 78; j++) - pos += snprintf(dbg + pos, sizeof(dbg) - pos, "%02X", modbusSerial.rxBuf[j]); - mqtt.publish("growatt/shinelan/debug", dbg); - - delay(10); // mbusd -R10: 10ms Pause zwischen Requests - - if (res != modbus.ku8MBSuccess) { - failCnt++; - lastErr = res; - lastErrReg = s.address; - continue; - } - - okCnt++; - float val; - if (s.isDword) { - uint32_t raw = ((uint32_t)modbus.getResponseBuffer(0) << 16) - | modbus.getResponseBuffer(1); - val = raw * s.scale; - } else { - val = modbus.getResponseBuffer(0) * s.scale; - } - - char topic[64], payload[24]; - snprintf(topic, sizeof(topic), "growatt/shinelan/%s", s.id); - snprintf(payload, sizeof(payload), "%.1f", (double)val); - mqtt.publish(topic, payload); - } - - g_okTotal += okCnt; - g_failTotal += failCnt; - g_lastErr = lastErr; - - ledSet(LED_BLUE, false); -} diff --git a/ShineLAN-X/releases/.gitkeep b/ShineLAN-X/releases/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/ShineLAN-X/releases/nuttx-mbusd-shinelanx.bin b/ShineLAN-X/releases/nuttx-mbusd-shinelanx.bin deleted file mode 100755 index 8e69b46..0000000 Binary files a/ShineLAN-X/releases/nuttx-mbusd-shinelanx.bin and /dev/null differ diff --git a/ShineWifi-X/Growatt MIC 1500 TL-X/Growatt MIC 1500 TL-X.yaml b/ShineWifi-X/Growatt MIC 1500 TL-X/Growatt MIC 1500 TL-X.yaml deleted file mode 100644 index b14b31c..0000000 --- a/ShineWifi-X/Growatt MIC 1500 TL-X/Growatt MIC 1500 TL-X.yaml +++ /dev/null @@ -1,212 +0,0 @@ -esphome: - name: growatt-mic-1500 - friendly_name: Growatt MIC 1500 TL-X - -esp8266: - board: esp07s - -logger: - -api: - encryption: - key: "HIER_API_KEY_EINTRAGEN" # 32-Byte Base64-Key, wird in der ESPHome-UI automatisch generiert - -ota: - - platform: esphome - password: "HIER_OTA_PASSWORT_EINTRAGEN" # Beliebiges Passwort für Over-the-Air Updates - -wifi: - ssid: "HIER_WLAN_NAME_EINTRAGEN" # Name deines WLANs (SSID) - password: "HIER_WLAN_PASSWORT_EINTRAGEN" # Passwort deines WLANs - ap: - ssid: "Growatt MIC 1500 TL-X Fallback Hotspot" - password: "HIER_HOTSPOT_PASSWORT_EINTRAGEN" # Passwort für den Notfall-Hotspot (min. 8 Zeichen) - -captive_portal: - -time: - - platform: homeassistant - id: homeassistant_time - -output: - - id: light_bl # Blaue LED - platform: gpio - pin: 16 - - id: light_gr # Grüne LED - platform: gpio - pin: 0 - - id: light_rd # Rote LED - platform: gpio - pin: 2 - -uart: - id: mod_bus - tx_pin: 1 - rx_pin: 3 - baud_rate: 115200 - -modbus: - id: modbus1 - uart_id: mod_bus - -modbus_controller: - - id: growatt - address: 1 - modbus_id: modbus1 - setup_priority: -10 - on_online: - then: - - output.turn_on: light_gr - on_offline: - then: - - output.turn_off: light_gr - -script: - - id: blink_blue - mode: single - then: - - output.turn_on: light_bl - - delay: 200ms - - output.turn_off: light_bl - -sensor: - # --- PV Eingang --- - - - platform: modbus_controller - name: "PV Voltage" - address: 3 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - on_value: - then: - - script.execute: blink_blue - - - platform: modbus_controller - name: "PV Current" - address: 4 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV Power" - address: 5 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:solar-panel - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- AC Ausgang / Netz --- - - - platform: modbus_controller - name: "Grid Frequency" - address: 37 - register_type: read - unit_of_measurement: Hz - device_class: frequency - state_class: measurement - icon: mdi:sine-wave - value_type: U_WORD - accuracy_decimals: 2 - filters: - - multiply: 0.01 - - - platform: modbus_controller - name: "Grid Voltage" - address: 38 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current" - address: 39 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "AC Output Power" - address: 40 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:flash - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Energie (PV Erzeugung) --- - - - platform: modbus_controller - name: "Energy Today" - address: 53 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Energy Total" - address: 55 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Temperatur --- - - - platform: modbus_controller - name: "Inverter Temperature" - address: 93 - register_type: read - unit_of_measurement: "°C" - device_class: temperature - state_class: measurement - icon: mdi:thermometer - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 diff --git a/ShineWifi-X/Growatt MIC 2000 TL-X/Growatt MIC 2000 TL-X.yaml b/ShineWifi-X/Growatt MIC 2000 TL-X/Growatt MIC 2000 TL-X.yaml deleted file mode 100644 index d028853..0000000 --- a/ShineWifi-X/Growatt MIC 2000 TL-X/Growatt MIC 2000 TL-X.yaml +++ /dev/null @@ -1,212 +0,0 @@ -esphome: - name: growatt-mic-2000 - friendly_name: Growatt MIC 2000 TL-X - -esp8266: - board: esp07s - -logger: - -api: - encryption: - key: "HIER_API_KEY_EINTRAGEN" - -ota: - - platform: esphome - password: "HIER_OTA_PASSWORT_EINTRAGEN" - -wifi: - ssid: "HIER_WLAN_NAME_EINTRAGEN" - password: "HIER_WLAN_PASSWORT_EINTRAGEN" - ap: - ssid: "Growatt MIC 2000 TL-X Fallback Hotspot" - password: "HIER_HOTSPOT_PASSWORT_EINTRAGEN" - -captive_portal: - -time: - - platform: homeassistant - id: homeassistant_time - -output: - - id: light_bl - platform: gpio - pin: 16 - - id: light_gr - platform: gpio - pin: 0 - - id: light_rd - platform: gpio - pin: 2 - -uart: - id: mod_bus - tx_pin: 1 - rx_pin: 3 - baud_rate: 115200 - -modbus: - id: modbus1 - uart_id: mod_bus - -modbus_controller: - - id: growatt - address: 1 - modbus_id: modbus1 - setup_priority: -10 - on_online: - then: - - output.turn_on: light_gr - on_offline: - then: - - output.turn_off: light_gr - -script: - - id: blink_blue - mode: single - then: - - output.turn_on: light_bl - - delay: 200ms - - output.turn_off: light_bl - -sensor: - # --- PV Eingang --- - - - platform: modbus_controller - name: "PV Voltage" - address: 3 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - on_value: - then: - - script.execute: blink_blue - - - platform: modbus_controller - name: "PV Current" - address: 4 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV Power" - address: 5 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:solar-panel - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- AC Ausgang / Netz --- - - - platform: modbus_controller - name: "Grid Frequency" - address: 37 - register_type: read - unit_of_measurement: Hz - device_class: frequency - state_class: measurement - icon: mdi:sine-wave - value_type: U_WORD - accuracy_decimals: 2 - filters: - - multiply: 0.01 - - - platform: modbus_controller - name: "Grid Voltage" - address: 38 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current" - address: 39 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "AC Output Power" - address: 40 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:flash - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Energie (PV Erzeugung) --- - - - platform: modbus_controller - name: "Energy Today" - address: 53 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Energy Total" - address: 55 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Temperatur --- - - - platform: modbus_controller - name: "Inverter Temperature" - address: 93 - register_type: read - unit_of_measurement: "°C" - device_class: temperature - state_class: measurement - icon: mdi:thermometer - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 diff --git a/ShineWifi-X/Growatt MIC 2000 TL-X/README.md b/ShineWifi-X/Growatt MIC 2000 TL-X/README.md deleted file mode 100644 index 26612aa..0000000 --- a/ShineWifi-X/Growatt MIC 2000 TL-X/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Growatt MIC 2000 TL-X — ESPHome Konfiguration - -Modbus-RTU Integration des Growatt MIC 2000 TL-X (einphasiger String-Wechselrichter) über einen Growatt SuniStick mit ESPHome-Firmware. - -Gleiche Registerstruktur wie der MIC 1500 TL-X — die MIC TL-X Familie verwendet ein einheitliches Protokoll. - ---- - -## Modbus-Register Übersicht - -Alle Register sind **Input Register** (Modbus Funktionscode 04, `register_type: "read"`). -Modbus-Adresse des Geräts: `0x01` - -### PV Eingang - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| PV Voltage | 3 | U_WORD | 0.1 | V | -| PV Current | 4 | U_WORD | 0.1 | A | -| PV Power | 5 | U_DWORD | 0.1 | W | - -### AC Ausgang / Netz - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Grid Frequency | 37 | U_WORD | **0.01** | Hz | -| Grid Voltage | 38 | U_WORD | 0.1 | V | -| Grid Current | 39 | U_WORD | 0.1 | A | -| AC Output Power | 40 | U_DWORD | 0.1 | W | - -### Energie (PV Erzeugung) - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Energy Today | 53 | U_DWORD | 0.1 | kWh | -| Energy Total | 55 | U_DWORD | 0.1 | kWh | - -### Temperatur - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Inverter Temperature | 93 | U_WORD | 0.1 | °C | - ---- - -## Hinweise - -- **Einphasig, kein Hybrid, kein Batterie-Interface** — keine Register >100 vorhanden. -- Register identisch mit MIC 1500 TL-X. Andere MIC TL-X Modelle (1000W, 1500W, 2000W) verwenden dieselbe Registerstruktur. -- Passwörter und API-Keys sind durch Platzhalter ersetzt und müssen vor dem Einsatz angepasst werden. diff --git a/ShineWifi-X/Growatt MOD 6000 TL3-XH/Growatt MOD 6000 TL3-XH.yaml b/ShineWifi-X/Growatt MOD 6000 TL3-XH/Growatt MOD 6000 TL3-XH.yaml deleted file mode 100644 index d08939e..0000000 --- a/ShineWifi-X/Growatt MOD 6000 TL3-XH/Growatt MOD 6000 TL3-XH.yaml +++ /dev/null @@ -1,331 +0,0 @@ -esphome: - name: growatt-mod-6000 - friendly_name: Growatt MOD 6000 TL3-XH - -esp8266: - board: esp07s - -logger: - -api: - encryption: - key: "HIER_API_KEY_EINTRAGEN" - -ota: - - platform: esphome - password: "HIER_OTA_PASSWORT_EINTRAGEN" - -wifi: - ssid: "HIER_WLAN_NAME_EINTRAGEN" - password: "HIER_WLAN_PASSWORT_EINTRAGEN" - ap: - ssid: "Growatt MOD 6000 Fallback Hotspot" - password: "HIER_HOTSPOT_PASSWORT_EINTRAGEN" - -captive_portal: - -time: - - platform: homeassistant - id: homeassistant_time - -output: - - id: light_bl - platform: gpio - pin: 16 - - id: light_gr - platform: gpio - pin: 0 - - id: light_rd - platform: gpio - pin: 2 - -uart: - id: mod_bus - tx_pin: 1 - rx_pin: 3 - baud_rate: 115200 - -modbus: - id: modbus1 - uart_id: mod_bus - -modbus_controller: - - id: growatt - address: 1 - modbus_id: modbus1 - setup_priority: -10 - on_online: - then: - - output.turn_on: light_gr - on_offline: - then: - - output.turn_off: light_gr - -script: - - id: blink_blue - mode: single - then: - - output.turn_on: light_bl - - delay: 200ms - - output.turn_off: light_bl - -sensor: - # --- PV Eingang --- - - - platform: modbus_controller - name: "PV1 Voltage" - address: 3003 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - on_value: - then: - - script.execute: blink_blue - - - platform: modbus_controller - name: "PV1 Current" - address: 3004 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV1 Power" - address: 3005 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:solar-panel - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV2 Voltage" - address: 3007 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV2 Current" - address: 3008 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV2 Power" - address: 3009 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:solar-panel - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- AC Ausgang / Netz (dreiphasig) --- - - - platform: modbus_controller - name: "AC Output Power Total" - address: 3023 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:flash - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Frequency" - address: 3025 - register_type: read - unit_of_measurement: Hz - device_class: frequency - state_class: measurement - icon: mdi:sine-wave - value_type: U_WORD - accuracy_decimals: 2 - filters: - - multiply: 0.01 - - - platform: modbus_controller - name: "Grid Voltage L1" - address: 3026 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current L1" - address: 3027 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Voltage L2" - address: 3030 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current L2" - address: 3031 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Voltage L3" - address: 3034 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current L3" - address: 3035 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Energie (PV Erzeugung) --- - - - platform: modbus_controller - name: "Energy Today" - address: 3049 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Energy Total" - address: 3051 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Temperatur --- - - - platform: modbus_controller - name: "Inverter Temperature" - address: 3093 - register_type: read - unit_of_measurement: "°C" - device_class: temperature - state_class: measurement - icon: mdi:thermometer - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Smartmeter (optional, nur wenn Smartmeter angeschlossen) --- - - - platform: modbus_controller - name: "Power To User" - address: 3041 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:transmission-tower-import - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Power To Grid" - address: 3043 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:transmission-tower-export - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 diff --git a/ShineWifi-X/Growatt MOD 6000 TL3-XH/README.md b/ShineWifi-X/Growatt MOD 6000 TL3-XH/README.md deleted file mode 100644 index 86fbd4c..0000000 --- a/ShineWifi-X/Growatt MOD 6000 TL3-XH/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Growatt MOD 6000 TL3-XH — ESPHome Konfiguration - -Modbus-RTU Integration des Growatt MOD 6000 TL3-XH (dreiphasiger String-Wechselrichter, kein Hybrid) über einen Growatt SuniStick mit ESPHome-Firmware. - ---- - -## Modbus-Register Übersicht - -Alle Register sind **Input Register** (Modbus Funktionscode 04, `register_type: "read"`). -Modbus-Adresse des Geräts: `0x01` - -> **Wichtig:** Die MOD TL3-XH Serie verwendet 3000er-Register — nicht die kleinen Register der MIC/MIN-Serie. - -### PV Eingang - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| PV1 Voltage | 3003 | U_WORD | 0.1 | V | -| PV1 Current | 3004 | U_WORD | 0.1 | A | -| PV1 Power | 3005 | U_DWORD | 0.1 | W | -| PV2 Voltage | 3007 | U_WORD | 0.1 | V | -| PV2 Current | 3008 | U_WORD | 0.1 | A | -| PV2 Power | 3009 | U_DWORD | 0.1 | W | - -### AC Ausgang / Netz (dreiphasig) - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| AC Output Power Total | 3023 | U_DWORD | 0.1 | W | -| Grid Frequency | 3025 | U_WORD | **0.01** | Hz | -| Grid Voltage L1 | 3026 | U_WORD | 0.1 | V | -| Grid Current L1 | 3027 | U_WORD | 0.1 | A | -| Grid Voltage L2 | 3030 | U_WORD | 0.1 | V | -| Grid Current L2 | 3031 | U_WORD | 0.1 | A | -| Grid Voltage L3 | 3034 | U_WORD | 0.1 | V | -| Grid Current L3 | 3035 | U_WORD | 0.1 | A | - -### Energie (PV Erzeugung) - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Energy Today | 3049 | U_DWORD | 0.1 | kWh | -| Energy Total | 3051 | U_DWORD | 0.1 | kWh | - -### Temperatur - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Inverter Temperature | 3093 | U_WORD | 0.1 | °C | - -### Smartmeter (optional) - -Nur relevant wenn ein Smartmeter am Wechselrichter angeschlossen ist. - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Power To User (Bezug) | 3041 | U_DWORD | 0.1 | W | -| Power To Grid (Einspeisung) | 3043 | U_DWORD | 0.1 | W | - ---- - -## Hinweise - -- **Dreiphasig, kein Hybrid, kein Batterie-Interface.** -- Registerstruktur verifiziert gegen Growatt MOD TL3-XH Modbus-Protokoll (gleiche Familie wie MOD 7000 TL3-XH). -- Ohne angeschlossenen Smartmeter liefern Register 3041/3043 Nullwerte — diese Sensoren können dann entfernt werden. -- Passwörter und API-Keys sind durch Platzhalter ersetzt und müssen vor dem Einsatz angepasst werden. diff --git a/ShineWifi-X/Growatt SPH 5000 TL3/Growatt SPH 5000 TL3-BH-UP.yaml b/ShineWifi-X/Growatt SPH 5000 TL3/Growatt SPH 5000 TL3-BH-UP.yaml deleted file mode 100644 index 937cf70..0000000 --- a/ShineWifi-X/Growatt SPH 5000 TL3/Growatt SPH 5000 TL3-BH-UP.yaml +++ /dev/null @@ -1,452 +0,0 @@ -esphome: - name: growatt-sph5000 - friendly_name: Growatt SPH 5000 TL3-BH-UP - -esp8266: - board: esp07s - -logger: - -api: - encryption: - key: "HIER_API_KEY_EINTRAGEN" # 32-Byte Base64-Key, wird in der ESPHome-UI automatisch generiert - -ota: - - platform: esphome - password: "HIER_OTA_PASSWORT_EINTRAGEN" # Beliebiges Passwort für Over-the-Air Updates - -wifi: - ssid: "HIER_WLAN_NAME_EINTRAGEN" # Name deines WLANs (SSID) - password: "HIER_WLAN_PASSWORT_EINTRAGEN" # Passwort deines WLANs - ap: - ssid: "Growatt-SPH5000 Fallback Hotspot" - password: "HIER_HOTSPOT_PASSWORT_EINTRAGEN" # Passwort für den Notfall-Hotspot (min. 8 Zeichen) - -captive_portal: - -time: - - platform: homeassistant - id: homeassistant_time - -output: - - id: light_bl - platform: gpio - pin: 16 - - id: light_gr - platform: gpio - pin: 0 - - id: light_rd - platform: gpio - pin: 2 - -uart: - id: mod_bus - tx_pin: 1 - rx_pin: 3 - baud_rate: 115200 - -modbus: - id: modbus1 - uart_id: mod_bus - -modbus_controller: - - id: growatt - address: 1 - modbus_id: modbus1 - setup_priority: -10 - on_online: - then: - - output.turn_on: light_gr - on_offline: - then: - - output.turn_off: light_gr - -script: - - id: blink_blue - mode: single - then: - - output.turn_on: light_bl - - delay: 200ms - - output.turn_off: light_bl - -sensor: - # --- PV Eingang --- - - - platform: modbus_controller - name: "PV1 Voltage" - address: 3 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - on_value: - then: - - script.execute: blink_blue - - - platform: modbus_controller - name: "PV1 Current" - address: 4 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV1 Power" - address: 5 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:solar-panel - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV2 Voltage" - address: 7 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV2 Current" - address: 8 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:solar-panel - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "PV2 Power" - address: 9 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:solar-panel - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- AC Ausgang / Netz --- - - - platform: modbus_controller - name: "AC Output Power Total" - address: 35 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:flash - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Frequency" - address: 37 - register_type: read - unit_of_measurement: Hz - device_class: frequency - state_class: measurement - icon: mdi:sine-wave - value_type: U_WORD - accuracy_decimals: 2 - filters: - - multiply: 0.01 - - - platform: modbus_controller - name: "Grid Voltage L1" - address: 38 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current L1" - address: 39 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Voltage L2" - address: 42 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current L2" - address: 43 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Voltage L3" - address: 46 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Grid Current L3" - address: 47 - register_type: read - unit_of_measurement: A - device_class: current - state_class: measurement - icon: mdi:flash - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Energie (PV Erzeugung) --- - - - platform: modbus_controller - name: "Energy Today" - address: 53 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Energy Total" - address: 55 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:solar-power - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Temperatur --- - - - platform: modbus_controller - name: "Inverter Temperature" - address: 93 - register_type: read - unit_of_measurement: "°C" - device_class: temperature - state_class: measurement - icon: mdi:thermometer - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Batterie --- - - - platform: modbus_controller - name: "Battery Discharge Power" - address: 1009 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:battery-minus - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Battery Charge Power" - address: 1011 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:battery-plus - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Battery Voltage" - address: 1013 - register_type: read - unit_of_measurement: V - device_class: voltage - state_class: measurement - icon: mdi:battery - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Battery State of Charge" - address: 1014 - register_type: read - unit_of_measurement: "%" - device_class: battery - state_class: measurement - icon: mdi:battery - value_type: U_WORD - accuracy_decimals: 0 - - - platform: modbus_controller - name: "Battery Temperature" - address: 1040 - register_type: read - unit_of_measurement: "°C" - device_class: temperature - state_class: measurement - icon: mdi:thermometer - value_type: U_WORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Batterie Energie (kWh Zähler für Energie-Dashboard) --- - - - platform: modbus_controller - name: "Battery Discharge Total" - address: 1054 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:battery-minus - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Battery Charge Total" - address: 1058 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:battery-plus - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Smartmeter Momentanleistung --- - - - platform: modbus_controller - name: "Power To Grid" - address: 1021 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:transmission-tower-export - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Power To User" - address: 1029 - register_type: read - unit_of_measurement: W - device_class: power - state_class: measurement - icon: mdi:transmission-tower-import - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - # --- Netzenergie Import / Export (kWh Zähler für Energie-Dashboard) --- - - - platform: modbus_controller - name: "Energy Import Total" - address: 1046 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:transmission-tower-import - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 - - - platform: modbus_controller - name: "Energy Export Total" - address: 1050 - register_type: read - unit_of_measurement: kWh - device_class: energy - state_class: total_increasing - icon: mdi:transmission-tower-export - value_type: U_DWORD - accuracy_decimals: 1 - filters: - - multiply: 0.1 diff --git a/ShineWifi-X/Growatt SPH 5000 TL3/README.md b/ShineWifi-X/Growatt SPH 5000 TL3/README.md deleted file mode 100644 index e85b6aa..0000000 --- a/ShineWifi-X/Growatt SPH 5000 TL3/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# Growatt SPH 5000 TL3-BH-UP — ESPHome Konfiguration - -Modbus-RTU Integration des Growatt SPH 5000 TL3-BH-UP (3-phasiger Hybrid-Wechselrichter mit Batterie) über einen Growatt SuniStick mit ESPHome-Firmware. - ---- - -## Modbus-Register Übersicht - -Alle Register sind **Input Register** (Modbus Funktionscode 04, `register_type: "read"`). -Modbus-Adresse des Geräts: `0x01` - -### PV Eingang - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| PV1 Voltage | 3 | U_WORD | 0.1 | V | -| PV1 Current | 4 | U_WORD | 0.1 | A | -| PV1 Power | 5 | U_DWORD | 0.1 | W | -| PV2 Voltage | 7 | U_WORD | 0.1 | V | -| PV2 Current | 8 | U_WORD | 0.1 | A | -| PV2 Power | 9 | U_DWORD | 0.1 | W | - -### AC Ausgang / Netz - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| AC Output Power Total | 35 | U_DWORD | 0.1 | W | -| Grid Frequency | 37 | U_WORD | **0.01** | Hz | -| Grid Voltage L1 | 38 | U_WORD | 0.1 | V | -| Grid Current L1 | 39 | U_WORD | 0.1 | A | -| Grid Voltage L2 | 42 | U_WORD | 0.1 | V | -| Grid Current L2 | 43 | U_WORD | 0.1 | A | -| Grid Voltage L3 | 46 | U_WORD | 0.1 | V | -| Grid Current L3 | 47 | U_WORD | 0.1 | A | - -> **Wichtig:** Grid Frequency hat Multiplikator `0.01` — der Rohwert ist z.B. `5000` = 50,00 Hz. - -### Energie (PV Erzeugung) - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Energy Today | 53 | U_DWORD | 0.1 | kWh | -| Energy Total | 55 | U_DWORD | 0.1 | kWh | - -### Temperatur - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Inverter Temperature | 93 | U_WORD | 0.1 | °C | - -### Batterie — Momentanleistung - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Battery Discharge Power | 1009 | U_DWORD | 0.1 | W | -| Battery Charge Power | 1011 | U_DWORD | 0.1 | W | -| Battery Voltage | 1013 | U_WORD | 0.1 | V | -| Battery State of Charge | 1014 | U_WORD | 1 | % | -| Battery Temperature | 1040 | U_WORD | 0.1 | °C | - -### Batterie — Energie (für Energie-Dashboard) - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Battery Discharge Total | 1054 | U_DWORD | 0.1 | kWh | -| Battery Charge Total | 1058 | U_DWORD | 0.1 | kWh | - -> **Wichtig:** 1009/1011 = Momentanleistung in **Watt**. 1054/1058 = kumulierte Energie in **kWh** für das HA Energie-Dashboard. - -### Smartmeter — Momentanleistung - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Power To Grid | 1021 | U_DWORD | 0.1 | W | -| Power To User | 1029 | U_DWORD | 0.1 | W | - -> **Hinweis:** Beide Werte sind immer positiv (unsigned). "To Grid" = Einspeisung, "To User" = Bezug vom Netz. - -### Netzenergie Import / Export (für Energie-Dashboard) - -| Name | Adresse | Typ | Multiplikator | Einheit | -|------|---------|-----|---------------|---------| -| Energy Import Total | 1046 | U_DWORD | 0.1 | kWh | -| Energy Export Total | 1050 | U_DWORD | 0.1 | kWh | - ---- - -## Hinweise - -- **U_DWORD** = 32-Bit-Wert über 2 aufeinanderfolgende Register. ESPHome liest diese automatisch korrekt, wenn `value_type: U_DWORD` gesetzt ist. -- Passwörter und API-Keys sind durch `#` ersetzt und müssen vor dem Einsatz angepasst werden. -- Diese Config wurde für den SPH 5000 TL3-BH-UP verifiziert. Andere SPH-Modelle (SPH 3000, SPH 6000 usw.) verwenden dieselbe Registerstruktur. diff --git a/tools/shinediag/diagnose.py b/tools/shinediag/diagnose.py deleted file mode 100644 index 6c86f02..0000000 --- a/tools/shinediag/diagnose.py +++ /dev/null @@ -1,278 +0,0 @@ -#!/usr/bin/env python3 -"""ShineDiag — Vor-Ort-Diagnose für Growatt-Wechselrichter via ShineLAN-X.""" - -import json -import logging -import os -import sqlite3 -import sys -import threading -import time -from typing import Dict, List, Optional - -from flask import Flask, jsonify, request, send_from_directory - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../../haos-addon/src")) -from inverters import INVERTERS -from modbus_client import ModbusReader - -logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s: %(message)s") -log = logging.getLogger(__name__) - -WEB_DIR = os.path.join(os.path.dirname(__file__), "web") -DB_PATH = os.environ.get("DB_PATH", "/var/lib/shinediag/history.db") -POLL_SEC = int(os.environ.get("POLL_SEC", "30")) - -app = Flask(__name__, static_folder=WEB_DIR) - -# ── SQLite ──────────────────────────────────────────────────── - -_db_lock = threading.Lock() -_db_conn: Optional[sqlite3.Connection] = None - - -def _db() -> sqlite3.Connection: - global _db_conn - if _db_conn is None: - os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) - _db_conn = sqlite3.connect(DB_PATH, check_same_thread=False) - _db_conn.execute("PRAGMA journal_mode=WAL") - _db_conn.execute("PRAGMA synchronous=NORMAL") - _db_conn.execute(""" - CREATE TABLE IF NOT EXISTS measurements ( - inv_key TEXT NOT NULL, - sensor_id TEXT NOT NULL, - ts REAL NOT NULL, - value REAL NOT NULL - )""") - _db_conn.execute(""" - CREATE INDEX IF NOT EXISTS idx_inv_sensor_ts - ON measurements(inv_key, sensor_id, ts)""") - _db_conn.commit() - return _db_conn - - -def db_write(inv_key: str, ts: float, values: Dict[str, float]): - rows = [(inv_key, sid, ts, v) for sid, v in values.items()] - with _db_lock: - _db().executemany( - "INSERT INTO measurements(inv_key,sensor_id,ts,value) VALUES(?,?,?,?)", rows) - _db().commit() - - -def db_query(inv_key: str, sensor_ids: List[str], - from_ts: float, to_ts: float) -> Dict[str, List]: - result = {sid: [] for sid in sensor_ids} - placeholders = ",".join("?" * len(sensor_ids)) - with _db_lock: - rows = _db().execute(f""" - SELECT sensor_id, ts, value FROM measurements - WHERE inv_key=? AND sensor_id IN ({placeholders}) - AND ts BETWEEN ? AND ? - ORDER BY ts ASC - """, [inv_key] + sensor_ids + [from_ts, to_ts]).fetchall() - for sid, ts, val in rows: - if sid in result: - result[sid].append({"ts": ts, "v": val}) - return result - - -def db_cleanup(days: int = 7): - cutoff = time.time() - days * 86400 - with _db_lock: - n = _db().execute("DELETE FROM measurements WHERE ts> /etc/dhcpcd.conf - -# DHCP-Server für eth0 -cp setup/dnsmasq.conf /etc/dnsmasq.conf -systemctl enable dnsmasq - -# WiFi-Hotspot -cp setup/hostapd.conf /etc/hostapd/hostapd.conf -echo 'DAEMON_CONF="/etc/hostapd/hostapd.conf"' >> /etc/default/hostapd -systemctl unmask hostapd -systemctl enable hostapd - -# Wlan0 IP -cat >> /etc/dhcpcd.conf << 'EOF' - -interface wlan0 -static ip_address=10.0.1.1/24 -nohook wpa_supplicant -EOF - -# DHCP auch für wlan0 (MacBook-Verbindung) -cat >> /etc/dnsmasq.conf << 'EOF' - -interface=wlan0 -dhcp-range=10.0.1.100,10.0.1.200,1h -EOF - -# systemd-Service für ShineDiag -INSTALL_DIR="$(pwd)" -cat > /etc/systemd/system/shinediag.service << EOF -[Unit] -Description=ShineDiag Diagnose-Tool -After=network.target - -[Service] -ExecStart=/usr/bin/python3 ${INSTALL_DIR}/diagnose.py -WorkingDirectory=${INSTALL_DIR} -Environment=PORT=80 -Environment=SHINELANX_IP=10.0.0.100 -Restart=always -User=root - -[Install] -WantedBy=multi-user.target -EOF - -systemctl daemon-reload -systemctl enable shinediag - -echo "" -echo "=== Fertig! Bitte neu starten: sudo reboot ===" -echo "" -echo "Nach dem Neustart:" -echo " WiFi: 'ShineDiag' | Passwort: shinelanx" -echo " Browser: http://10.0.1.1" diff --git a/tools/shinediag/web/index.html b/tools/shinediag/web/index.html deleted file mode 100644 index 9aa23ce..0000000 --- a/tools/shinediag/web/index.html +++ /dev/null @@ -1,601 +0,0 @@ - - - - - -ShineDiag - - - - -
-
- - - - - - - -

ShineDiag

Nicht verbunden

-
-
-
- -
- - - - -
- -
- - -
- -
-
Verbindung
- - -
-
-
-
- - - -
- - - -
- - - - - - - - - - -
- - - -