Fix UDP on Ethernet gateway (#858)

- Fix UDP send
- Add a default value for MY_IP_GATEWAY_ADDRESS and
  MY_IP_SUBNET_ADDRESS, making them optional when using MY_IP_ADDRESS
- Add support for MY_IP_GATEWAY_ADDRESS and MY_IP_SUBNET_ADDRESS to
  W5100
This commit is contained in:
Marcelo Aquino
2017-06-13 22:59:01 +02:00
committed by Henrik Ekblad
parent 4820475e5c
commit 95d7c003cb
7 changed files with 181 additions and 154 deletions
+75 -60
View File
@@ -28,7 +28,20 @@ IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
#if defined(MY_IP_ADDRESS)
IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
#endif
#if defined(MY_IP_GATEWAY_ADDRESS)
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_GATEWAY_ADDRESS */
// Assume the gateway will be the machine on the same network as the local IP
// but with last octet being '1'
IPAddress _gatewayIp(_ethernetGatewayIP[0], _ethernetGatewayIP[1], _ethernetGatewayIP[2], 1);
#endif /* End of MY_IP_GATEWAY_ADDRESS */
#if defined(MY_IP_SUBNET_ADDRESS)
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_SUBNET_ADDRESS */
IPAddress _subnetIp(255, 255, 255, 0);
#endif /* End of MY_IP_SUBNET_ADDRESS */
#endif /* End of MY_IP_ADDRESS */
uint8_t _ethernetGatewayMAC[] = { MY_MAC_ADDRESS };
uint16_t _ethernetGatewayPort = MY_PORT;
MyMessage _ethernetMsg;
@@ -45,34 +58,33 @@ typedef struct {
#define EthernetServer WiFiServer
#define EthernetClient WiFiClient
#define EthernetUDP WiFiUDP
#endif /* End of MY_GATEWAY_ESP8266 */
#if defined(MY_IP_ADDRESS)
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
#endif
#endif
#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
EthernetUDP _ethernetServer;
#elif defined(MY_GATEWAY_LINUX)
#endif /* End of MY_USE_UDP */
#elif defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_CLIENT_MODE */
EthernetServer _ethernetServer(_ethernetGatewayPort, MY_GATEWAY_MAX_CLIENTS);
#elif defined(MY_GATEWAY_CLIENT_MODE)
// Nothing to do here
#else
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
EthernetServer _ethernetServer(_ethernetGatewayPort);
#endif
#endif /* End of MY_GATEWAY_CLIENT_MODE */
#if defined(MY_GATEWAY_CLIENT_MODE)
static EthernetClient client = EthernetClient();
static inputBuffer inputString;
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)
#if defined(MY_USE_UDP)
// Nothing to do here
#else
static EthernetClient client = EthernetClient();
#endif /* End of MY_USE_UDP */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_CLIENT_MODE */
static EthernetClient clients[MY_GATEWAY_MAX_CLIENTS];
static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS];
static inputBuffer inputString[MY_GATEWAY_MAX_CLIENTS];
#else
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
static EthernetClient client = EthernetClient();
static inputBuffer inputString;
#endif
#endif /* End of MY_GATEWAY_CLIENT_MODE */
#ifndef MY_IP_ADDRESS
void gatewayTransportRenewIP();
@@ -80,7 +92,7 @@ void gatewayTransportRenewIP();
// On W5100 boards with SPI_EN exposed we can use the real SPI bus together with radio
// (if we enable it during usage)
#ifdef MY_W5100_SPI_EN
#if defined(MY_W5100_SPI_EN)
void _w5100_spi_en(bool enable)
{
if (enable) {
@@ -103,13 +115,13 @@ bool gatewayTransportInit(void)
#if defined(MY_GATEWAY_ESP8266)
#if defined(MY_ESP8266_SSID)
// Turn off access point
WiFi.mode (WIFI_STA);
WiFi.mode(WIFI_STA);
#if defined(MY_ESP8266_HOSTNAME)
WiFi.hostname(MY_ESP8266_HOSTNAME);
#endif
#ifdef MY_IP_ADDRESS
#endif /* End of MY_ESP8266_HOSTNAME */
#if defined(MY_IP_ADDRESS)
WiFi.config(_ethernetGatewayIP, _gatewayIp, _subnetIp);
#endif
#endif /* End of MY_IP_ADDRESS */
(void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
wait(500);
@@ -117,35 +129,41 @@ bool gatewayTransportInit(void)
}
MY_SERIALDEVICE.print(F("IP: "));
MY_SERIALDEVICE.println(WiFi.localIP());
#endif
#elif defined(MY_GATEWAY_LINUX)
#endif /* End of MY_ESP8266_SSID */
#elif defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_ESP8266 */
// Nothing to do here
#else
#ifdef MY_IP_ADDRESS
#else /* Else part of MY_GATEWAY_ESP8266 */
#if defined(MY_IP_GATEWAY_ADDRESS) && defined(MY_IP_SUBNET_ADDRESS)
// DNS server set to gateway ip
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP, _gatewayIp, _gatewayIp, _subnetIp);
#elif defined(MY_IP_ADDRESS)
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP);
#else
#else /* Else part of MY_IP_GATEWAY_ADDRESS && MY_IP_SUBNET_ADDRESS */
// Get IP address from DHCP
if (!Ethernet.begin(_ethernetGatewayMAC)) {
MY_SERIALDEVICE.print(F("DHCP FAILURE..."));
_w5100_spi_en(false);
return false;
}
#endif
#endif /* End of MY_IP_GATEWAY_ADDRESS && MY_IP_SUBNET_ADDRESS */
MY_SERIALDEVICE.print(F("IP: "));
MY_SERIALDEVICE.println(Ethernet.localIP());
// give the Ethernet interface a second to initialize
delay(1000);
#endif /* MY_GATEWAY_ESP8266 */
#endif /* End of MY_GATEWAY_ESP8266 */
#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
_ethernetServer.begin(_ethernetGatewayPort);
#else /* Else part of MY_USE_UDP */
#if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
client.bind(_ethernetGatewayIP);
#endif
#endif /* End of MY_GATEWAY_LINUX && MY_IP_ADDRESS */
#if defined(MY_CONTROLLER_URL_ADDRESS)
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
#else
if (client.connect(_ethernetControllerIP, MY_PORT)) {
#endif
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
debug(PSTR("Eth: connect\n"));
_w5100_spi_en(false);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
@@ -155,16 +173,15 @@ bool gatewayTransportInit(void)
client.stop();
debug(PSTR("Eth: Failed to connect\n"));
}
#elif defined(MY_USE_UDP)
_ethernetServer.begin(_ethernetGatewayPort);
#else
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
#if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
_ethernetServer.begin(_ethernetGatewayIP);
#else
// we have to use pointers due to the constructor of EthernetServer
_ethernetServer.begin();
#endif
#endif /* USE_UDP */
#endif /* End of MY_GATEWAY_LINUX && MY_IP_ADDRESS */
#endif /* End of MY_GATEWAY_CLIENT_MODE */
_w5100_spi_en(false);
return true;
@@ -184,18 +201,18 @@ bool gatewayTransportSend(MyMessage &message)
_ethernetServer.beginPacket(MY_CONTROLLER_URL_ADDRESS, MY_PORT);
#else
_ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
#endif
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
_ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
// returns 1 if the packet was sent successfully
nbytes = _ethernetServer.endPacket();
#else
#else /* Else part of MY_USE_UDP */
if (!client.connected()) {
client.stop();
#if defined(MY_CONTROLLER_URL_ADDRESS)
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
#else
if (client.connect(_ethernetControllerIP, MY_PORT)) {
#endif
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
debug(PSTR("Eth: connect\n"));
_w5100_spi_en(false);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
@@ -209,8 +226,8 @@ bool gatewayTransportSend(MyMessage &message)
}
}
nbytes = client.write((const uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
#endif
#else
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
// Send message to connected clients
#if defined(MY_GATEWAY_ESP8266)
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
@@ -218,14 +235,17 @@ bool gatewayTransportSend(MyMessage &message)
nbytes += clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
}
}
#else
#else /* Else part of MY_GATEWAY_ESP8266 */
nbytes = _ethernetServer.write(_ethernetMsg);
#endif
#endif /* MY_GATEWAY_CLIENT_MODE */
#endif /* End of MY_GATEWAY_ESP8266 */
#endif /* End of MY_GATEWAY_CLIENT_MODE */
_w5100_spi_en(false);
return (nbytes > 0);
}
#if defined(MY_USE_UDP)
// Nothing to do here
#else
#if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE)
bool _readFromClient(uint8_t i)
{
@@ -256,7 +276,7 @@ bool _readFromClient(uint8_t i)
}
return false;
}
#else
#else /* Else part of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX || !MY_GATEWAY_CLIENT_MODE */
bool _readFromClient(void)
{
while (client.connected() && client.available()) {
@@ -286,8 +306,8 @@ bool _readFromClient(void)
}
return false;
}
#endif
#endif /* End of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX || !MY_GATEWAY_CLIENT_MODE */
#endif /* End of MY_USE_UDP */
bool gatewayTransportAvailable(void)
{
@@ -297,36 +317,30 @@ bool gatewayTransportAvailable(void)
gatewayTransportRenewIP();
#endif
#ifdef MY_USE_UDP
#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
int packet_size = _ethernetServer.parsePacket();
if (packet_size) {
//debug(PSTR("UDP packet available. Size:%d\n"), packet_size);
#if defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_CLIENT_MODE)
_ethernetServer.read(inputString[0].string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
inputString[0].string[packet_size] = 0;
debug(PSTR("UDP packet received: %s\n"), inputString[0].string);
const bool ok = protocolParse(_ethernetMsg, inputString[0].string);
#else
_ethernetServer.read(inputString.string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
inputString.string[packet_size] = 0;
debug(PSTR("UDP packet received: %s\n"), inputString.string);
_w5100_spi_en(false);
const bool ok = protocolParse(_ethernetMsg, inputString.string);
#endif
if (ok) {
setIndication(INDICATION_GW_RX);
}
return ok;
}
#elif defined(MY_GATEWAY_CLIENT_MODE)
#else /* Else part of MY_USE_UDP */
if (!client.connected()) {
client.stop();
#if defined(MY_CONTROLLER_URL_ADDRESS)
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
#else
if (client.connect(_ethernetControllerIP, MY_PORT)) {
#endif
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
debug(PSTR("Eth: connect\n"));
_w5100_spi_en(false);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
@@ -343,7 +357,8 @@ bool gatewayTransportAvailable(void)
_w5100_spi_en(false);
return true;
}
#else
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)
// ESP8266: Go over list of clients and stop any that are no longer connected.
// If the server has a new client connection it will be assigned to a free slot.
@@ -382,7 +397,7 @@ bool gatewayTransportAvailable(void)
return true;
}
}
#else
#else /* Else part of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX */
// W5100/ENC module does not have hasClient-method. We can only serve one client at the time.
EthernetClient newclient = _ethernetServer.available();
// if a new client connects make sure to dispose any previous existing sockets
@@ -409,8 +424,8 @@ bool gatewayTransportAvailable(void)
}
}
}
#endif /* MY_GATEWAY_ESP8266 */
#endif
#endif /* End of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX */
#endif /* End of MY_GATEWAY_CLIENT_MODE */
_w5100_spi_en(false);
return false;
}