Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MyGatewayTransportEthernet.cpp 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /*
  2. * The MySensors Arduino library handles the wireless radio link and protocol
  3. * between your home built sensors/actuators and HA controller of choice.
  4. * The sensors forms a self healing radio network with optional repeaters. Each
  5. * repeater and gateway builds a routing tables in EEPROM which keeps track of the
  6. * network topology allowing messages to be routed to nodes.
  7. *
  8. * Created by Tomas Hozza <thozza@gmail.com>
  9. * Copyright (C) 2015 Tomas Hozza
  10. * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
  11. *
  12. * Documentation: http://www.mysensors.org
  13. * Support Forum: http://forum.mysensors.org
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License
  17. * version 2 as published by the Free Software Foundation.
  18. */
  19. #include "MyGatewayTransport.h"
  20. // global variables
  21. extern MyMessage _msgTmp;
  22. // housekeeping, remove for 3.0.0
  23. #ifdef MY_ESP8266_SSID
  24. #warning MY_ESP8266_SSID is deprecated, use MY_WIFI_SSID instead!
  25. #define MY_WIFI_SSID MY_ESP8266_SSID
  26. #undef MY_ESP8266_SSID // cleanup
  27. #endif
  28. #ifdef MY_ESP8266_PASSWORD
  29. #warning MY_ESP8266_PASSWORD is deprecated, use MY_WIFI_PASSWORD instead!
  30. #define MY_WIFI_PASSWORD MY_ESP8266_PASSWORD
  31. #undef MY_ESP8266_PASSWORD // cleanup
  32. #endif
  33. #ifdef MY_ESP8266_BSSID
  34. #warning MY_ESP8266_BSSID is deprecated, use MY_WIFI_BSSID instead!
  35. #define MY_WIFI_BSSID MY_ESP8266_BSSID
  36. #undef MY_ESP8266_BSSID // cleanup
  37. #endif
  38. #ifdef MY_ESP8266_HOSTNAME
  39. #warning MY_ESP8266_HOSTNAME is deprecated, use MY_HOSTNAME instead!
  40. #define MY_HOSTNAME MY_ESP8266_HOSTNAME
  41. #undef MY_ESP8266_HOSTNAME // cleanup
  42. #endif
  43. #ifndef MY_WIFI_BSSID
  44. #define MY_WIFI_BSSID NULL
  45. #endif
  46. #if defined(MY_CONTROLLER_IP_ADDRESS)
  47. IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
  48. #endif
  49. #if defined(MY_IP_ADDRESS)
  50. IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
  51. #if defined(MY_IP_GATEWAY_ADDRESS)
  52. IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
  53. #elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
  54. // Assume the gateway will be the machine on the same network as the local IP
  55. // but with last octet being '1'
  56. IPAddress _gatewayIp(_ethernetGatewayIP[0], _ethernetGatewayIP[1], _ethernetGatewayIP[2], 1);
  57. #endif /* End of MY_IP_GATEWAY_ADDRESS */
  58. #if defined(MY_IP_SUBNET_ADDRESS)
  59. IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
  60. #elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
  61. IPAddress _subnetIp(255, 255, 255, 0);
  62. #endif /* End of MY_IP_SUBNET_ADDRESS */
  63. #endif /* End of MY_IP_ADDRESS */
  64. uint8_t _ethernetGatewayMAC[] = { MY_MAC_ADDRESS };
  65. uint16_t _ethernetGatewayPort = MY_PORT;
  66. MyMessage _ethernetMsg;
  67. #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
  68. typedef struct {
  69. // Suppress the warning about unused members in this struct because it is used through a complex
  70. // set of preprocessor directives
  71. // cppcheck-suppress unusedStructMember
  72. char string[MY_GATEWAY_MAX_RECEIVE_LENGTH];
  73. // cppcheck-suppress unusedStructMember
  74. uint8_t idx;
  75. } inputBuffer;
  76. #if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
  77. // Some re-defines to make code more readable below
  78. #define EthernetServer WiFiServer
  79. #define EthernetClient WiFiClient
  80. #define EthernetUDP WiFiUDP
  81. #endif
  82. #if defined(MY_GATEWAY_CLIENT_MODE)
  83. #if defined(MY_USE_UDP)
  84. EthernetUDP _ethernetServer;
  85. #endif /* End of MY_USE_UDP */
  86. #elif defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_CLIENT_MODE */
  87. EthernetServer _ethernetServer(_ethernetGatewayPort, MY_GATEWAY_MAX_CLIENTS);
  88. #else /* Else part of MY_GATEWAY_CLIENT_MODE */
  89. EthernetServer _ethernetServer(_ethernetGatewayPort);
  90. #endif /* End of MY_GATEWAY_CLIENT_MODE */
  91. #if defined(MY_GATEWAY_CLIENT_MODE)
  92. static inputBuffer inputString;
  93. #if defined(MY_USE_UDP)
  94. // Nothing to do here
  95. #else
  96. static EthernetClient client = EthernetClient();
  97. #endif /* End of MY_USE_UDP */
  98. #elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)
  99. static EthernetClient clients[MY_GATEWAY_MAX_CLIENTS];
  100. static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS];
  101. static inputBuffer inputString[MY_GATEWAY_MAX_CLIENTS];
  102. #else /* Else part of MY_GATEWAY_CLIENT_MODE */
  103. static EthernetClient client = EthernetClient();
  104. static inputBuffer inputString;
  105. #endif /* End of MY_GATEWAY_CLIENT_MODE */
  106. #ifndef MY_IP_ADDRESS
  107. void gatewayTransportRenewIP();
  108. #endif
  109. // On W5100 boards with SPI_EN exposed we can use the real SPI bus together with radio
  110. // (if we enable it during usage)
  111. #if defined(MY_W5100_SPI_EN)
  112. void _w5100_spi_en(bool enable)
  113. {
  114. if (enable) {
  115. // Pull up pin
  116. hwPinMode(MY_W5100_SPI_EN, INPUT);
  117. hwDigitalWrite(MY_W5100_SPI_EN, HIGH);
  118. } else {
  119. // Ground pin
  120. hwPinMode(MY_W5100_SPI_EN, OUTPUT);
  121. hwDigitalWrite(MY_W5100_SPI_EN, LOW);
  122. }
  123. }
  124. #else
  125. #define _w5100_spi_en(x)
  126. #endif
  127. bool gatewayTransportInit(void)
  128. {
  129. _w5100_spi_en(true);
  130. #if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
  131. #if defined(MY_WIFI_SSID)
  132. // Turn off access point
  133. WiFi.mode(WIFI_STA);
  134. #if defined(MY_HOSTNAME)
  135. #if defined(MY_GATEWAY_ESP8266)
  136. WiFi.hostname(MY_HOSTNAME);
  137. #elif defined(MY_GATEWAY_ESP32)
  138. WiFi.setHostname(MY_HOSTNAME);
  139. #endif
  140. #endif
  141. #ifdef MY_IP_ADDRESS
  142. WiFi.config(_ethernetGatewayIP, _gatewayIp, _subnetIp);
  143. #endif
  144. (void)WiFi.begin(MY_WIFI_SSID, MY_WIFI_PASSWORD, 0, MY_WIFI_BSSID);
  145. while (WiFi.status() != WL_CONNECTED) {
  146. wait(500);
  147. GATEWAY_DEBUG(PSTR("GWT:TIN:CONNECTING...\n"));
  148. }
  149. GATEWAY_DEBUG(PSTR("GWT:TIN:IP: %s\n"), WiFi.localIP().toString().c_str());
  150. #endif
  151. #elif defined(MY_GATEWAY_LINUX)
  152. // Nothing to do here
  153. #else
  154. #if defined(MY_IP_GATEWAY_ADDRESS) && defined(MY_IP_SUBNET_ADDRESS)
  155. // DNS server set to gateway ip
  156. Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP, _gatewayIp, _gatewayIp, _subnetIp);
  157. #elif defined(MY_IP_ADDRESS)
  158. Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP);
  159. #else /* Else part of MY_IP_GATEWAY_ADDRESS && MY_IP_SUBNET_ADDRESS */
  160. // Get IP address from DHCP
  161. if (!Ethernet.begin(_ethernetGatewayMAC)) {
  162. GATEWAY_DEBUG(PSTR("!GWT:TIN:DHCP FAIL\n"));
  163. _w5100_spi_en(false);
  164. return false;
  165. }
  166. #endif /* End of MY_IP_GATEWAY_ADDRESS && MY_IP_SUBNET_ADDRESS */
  167. GATEWAY_DEBUG(PSTR("GWT:TIN:IP=%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "\n"),
  168. Ethernet.localIP()[0],
  169. Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
  170. // give the Ethernet interface a second to initialize
  171. delay(1000);
  172. #endif /* MY_GATEWAY_ESP8266 / MY_GATEWAY_ESP32 */
  173. #if defined(MY_GATEWAY_CLIENT_MODE)
  174. #if defined(MY_USE_UDP)
  175. _ethernetServer.begin(_ethernetGatewayPort);
  176. #else /* Else part of MY_USE_UDP */
  177. #if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
  178. client.bind(_ethernetGatewayIP);
  179. #endif /* End of MY_GATEWAY_LINUX && MY_IP_ADDRESS */
  180. #if defined(MY_CONTROLLER_URL_ADDRESS)
  181. if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
  182. #else
  183. if (client.connect(_ethernetControllerIP, MY_PORT)) {
  184. #endif /* End of MY_CONTROLLER_URL_ADDRESS */
  185. GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));
  186. _w5100_spi_en(false);
  187. gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
  188. _w5100_spi_en(true);
  189. presentNode();
  190. } else {
  191. client.stop();
  192. GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
  193. }
  194. #endif /* End of MY_USE_UDP */
  195. #else /* Else part of MY_GATEWAY_CLIENT_MODE */
  196. #if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
  197. _ethernetServer.begin(_ethernetGatewayIP);
  198. #else
  199. // we have to use pointers due to the constructor of EthernetServer
  200. _ethernetServer.begin();
  201. #endif /* End of MY_GATEWAY_LINUX && MY_IP_ADDRESS */
  202. #endif /* End of MY_GATEWAY_CLIENT_MODE */
  203. _w5100_spi_en(false);
  204. return true;
  205. }
  206. bool gatewayTransportSend(MyMessage &message)
  207. {
  208. int nbytes = 0;
  209. char *_ethernetMsg = protocolFormat(message);
  210. setIndication(INDICATION_GW_TX);
  211. _w5100_spi_en(true);
  212. #if defined(MY_GATEWAY_CLIENT_MODE)
  213. #if defined(MY_USE_UDP)
  214. #if defined(MY_CONTROLLER_URL_ADDRESS)
  215. _ethernetServer.beginPacket(MY_CONTROLLER_URL_ADDRESS, MY_PORT);
  216. #else
  217. _ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
  218. #endif /* End of MY_CONTROLLER_URL_ADDRESS */
  219. _ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
  220. // returns 1 if the packet was sent successfully
  221. nbytes = _ethernetServer.endPacket();
  222. #else /* Else part of MY_USE_UDP */
  223. if (!client.connected()) {
  224. client.stop();
  225. #if defined(MY_CONTROLLER_URL_ADDRESS)
  226. if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
  227. #else
  228. if (client.connect(_ethernetControllerIP, MY_PORT)) {
  229. #endif /* End of MY_CONTROLLER_URL_ADDRESS */
  230. GATEWAY_DEBUG(PSTR("GWT:TPS:ETH OK\n"));
  231. _w5100_spi_en(false);
  232. gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
  233. _w5100_spi_en(true);
  234. presentNode();
  235. } else {
  236. // connecting to the server failed!
  237. GATEWAY_DEBUG(PSTR("!GWT:TPS:ETH FAIL\n"));
  238. _w5100_spi_en(false);
  239. return false;
  240. }
  241. }
  242. nbytes = client.write((const uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
  243. #endif /* End of MY_USE_UDP */
  244. #else /* Else part of MY_GATEWAY_CLIENT_MODE */
  245. // Send message to connected clients
  246. #if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
  247. for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
  248. if (clients[i] && clients[i].connected()) {
  249. nbytes += clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
  250. }
  251. }
  252. #else /* Else part of MY_GATEWAY_ESP8266 */
  253. nbytes = _ethernetServer.write(_ethernetMsg);
  254. #endif /* End of MY_GATEWAY_ESP8266 */
  255. #endif /* End of MY_GATEWAY_CLIENT_MODE */
  256. _w5100_spi_en(false);
  257. return (nbytes > 0);
  258. }
  259. #if defined(MY_USE_UDP)
  260. // Nothing to do here
  261. #else
  262. #if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE)
  263. bool _readFromClient(uint8_t i)
  264. {
  265. while (clients[i].connected() && clients[i].available()) {
  266. const char inChar = clients[i].read();
  267. if (inputString[i].idx < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
  268. // if newline then command is complete
  269. if (inChar == '\n' || inChar == '\r') {
  270. // Add string terminator and prepare for the next message
  271. inputString[i].string[inputString[i].idx] = 0;
  272. GATEWAY_DEBUG(PSTR("GWT:RFC:C=%" PRIu8 ",MSG=%s\n"), i, inputString[i].string);
  273. inputString[i].idx = 0;
  274. if (protocolParse(_ethernetMsg, inputString[i].string)) {
  275. return true;
  276. }
  277. } else {
  278. // add it to the inputString:
  279. inputString[i].string[inputString[i].idx++] = inChar;
  280. }
  281. } else {
  282. // Incoming message too long. Throw away
  283. GATEWAY_DEBUG(PSTR("!GWT:RFC:C=%" PRIu8 ",MSG TOO LONG\n"), i);
  284. inputString[i].idx = 0;
  285. // Finished with this client's message. Next loop() we'll see if there's more to read.
  286. break;
  287. }
  288. }
  289. return false;
  290. }
  291. #else /* Else part of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX || !MY_GATEWAY_CLIENT_MODE */
  292. bool _readFromClient(void)
  293. {
  294. while (client.connected() && client.available()) {
  295. const char inChar = client.read();
  296. if (inputString.idx < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
  297. // if newline then command is complete
  298. if (inChar == '\n' || inChar == '\r') {
  299. // Add string terminator and prepare for the next message
  300. inputString.string[inputString.idx] = 0;
  301. GATEWAY_DEBUG(PSTR("GWT:RFC:MSG=%s\n"), inputString.string);
  302. inputString.idx = 0;
  303. if (protocolParse(_ethernetMsg, inputString.string)) {
  304. return true;
  305. }
  306. } else {
  307. // add it to the inputString:
  308. inputString.string[inputString.idx++] = inChar;
  309. }
  310. } else {
  311. // Incoming message too long. Throw away
  312. GATEWAY_DEBUG(PSTR("!GWT:RFC:MSG TOO LONG\n"));
  313. inputString.idx = 0;
  314. // Finished with this client's message. Next loop() we'll see if there's more to read.
  315. break;
  316. }
  317. }
  318. return false;
  319. }
  320. #endif /* End of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX || !MY_GATEWAY_CLIENT_MODE */
  321. #endif /* End of MY_USE_UDP */
  322. bool gatewayTransportAvailable(void)
  323. {
  324. _w5100_spi_en(true);
  325. #if !defined(MY_IP_ADDRESS) && defined(MY_GATEWAY_W5100)
  326. // renew IP address using DHCP
  327. gatewayTransportRenewIP();
  328. #endif
  329. #if defined(MY_GATEWAY_CLIENT_MODE)
  330. #if defined(MY_USE_UDP)
  331. int packet_size = _ethernetServer.parsePacket();
  332. if (packet_size) {
  333. //GATEWAY_DEBUG(PSTR("UDP packet available. Size:%" PRIu8 "\n"), packet_size);
  334. _ethernetServer.read(inputString.string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
  335. inputString.string[packet_size] = 0;
  336. GATEWAY_DEBUG(PSTR("GWT:TSA:UDP MSG=%s\n"), inputString.string);
  337. _w5100_spi_en(false);
  338. const bool ok = protocolParse(_ethernetMsg, inputString.string);
  339. if (ok) {
  340. setIndication(INDICATION_GW_RX);
  341. }
  342. return ok;
  343. }
  344. #else /* Else part of MY_USE_UDP */
  345. if (!client.connected()) {
  346. client.stop();
  347. #if defined(MY_CONTROLLER_URL_ADDRESS)
  348. if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
  349. #else
  350. if (client.connect(_ethernetControllerIP, MY_PORT)) {
  351. #endif /* End of MY_CONTROLLER_URL_ADDRESS */
  352. GATEWAY_DEBUG(PSTR("GWT:TSA:ETH OK\n"));
  353. _w5100_spi_en(false);
  354. gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
  355. _w5100_spi_en(true);
  356. presentNode();
  357. } else {
  358. GATEWAY_DEBUG(PSTR("!GWT:TSA:ETH FAIL\n"));
  359. _w5100_spi_en(false);
  360. return false;
  361. }
  362. }
  363. if (_readFromClient()) {
  364. setIndication(INDICATION_GW_RX);
  365. _w5100_spi_en(false);
  366. return true;
  367. }
  368. #endif /* End of MY_USE_UDP */
  369. #else /* Else part of MY_GATEWAY_CLIENT_MODE */
  370. #if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)
  371. // ESP8266: Go over list of clients and stop any that are no longer connected.
  372. // If the server has a new client connection it will be assigned to a free slot.
  373. bool allSlotsOccupied = true;
  374. for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
  375. if (!clients[i].connected()) {
  376. if (clientsConnected[i]) {
  377. GATEWAY_DEBUG(PSTR("GWT:TSA:C=%" PRIu8 ",DISCONNECTED\n"), i);
  378. clients[i].stop();
  379. }
  380. //check if there are any new clients
  381. if (_ethernetServer.hasClient()) {
  382. clients[i] = _ethernetServer.available();
  383. inputString[i].idx = 0;
  384. GATEWAY_DEBUG(PSTR("GWT:TSA:C=%" PRIu8 ",CONNECTED\n"), i);
  385. gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
  386. // Send presentation of locally attached sensors (and node if applicable)
  387. presentNode();
  388. }
  389. }
  390. bool connected = clients[i].connected();
  391. clientsConnected[i] = connected;
  392. allSlotsOccupied &= connected;
  393. }
  394. if (allSlotsOccupied && _ethernetServer.hasClient()) {
  395. //no free/disconnected spot so reject
  396. GATEWAY_DEBUG(PSTR("!GWT:TSA:NO FREE SLOT\n"));
  397. EthernetClient c = _ethernetServer.available();
  398. c.stop();
  399. }
  400. // Loop over clients connect and read available data
  401. for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
  402. if (_readFromClient(i)) {
  403. setIndication(INDICATION_GW_RX);
  404. _w5100_spi_en(false);
  405. return true;
  406. }
  407. }
  408. #else /* Else part of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX */
  409. // W5100/ENC module does not have hasClient-method. We can only serve one client at the time.
  410. EthernetClient newclient = _ethernetServer.available();
  411. // if a new client connects make sure to dispose any previous existing sockets
  412. if (newclient) {
  413. if (client != newclient) {
  414. client.stop();
  415. client = newclient;
  416. GATEWAY_DEBUG(PSTR("GWT:TSA:ETH OK\n"));
  417. _w5100_spi_en(false);
  418. gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
  419. _w5100_spi_en(true);
  420. presentNode();
  421. }
  422. }
  423. if (client) {
  424. if (!client.connected()) {
  425. GATEWAY_DEBUG(PSTR("!GWT:TSA:ETH FAIL\n"));
  426. client.stop();
  427. } else {
  428. if (_readFromClient()) {
  429. setIndication(INDICATION_GW_RX);
  430. _w5100_spi_en(false);
  431. return true;
  432. }
  433. }
  434. }
  435. #endif /* End of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX */
  436. #endif /* End of MY_GATEWAY_CLIENT_MODE */
  437. _w5100_spi_en(false);
  438. return false;
  439. }
  440. MyMessage& gatewayTransportReceive(void)
  441. {
  442. // Return the last parsed message
  443. return _ethernetMsg;
  444. }
  445. #if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_ESP32) && !defined(MY_GATEWAY_LINUX)
  446. void gatewayTransportRenewIP(void)
  447. {
  448. /* renew/rebind IP address
  449. 0 - nothing happened
  450. 1 - renew failed
  451. 2 - renew success
  452. 3 - rebind failed
  453. 4 - rebind success
  454. */
  455. static unsigned long next_time = hwMillis() + MY_IP_RENEWAL_INTERVAL_MS;
  456. unsigned long now = hwMillis();
  457. // http://playground.arduino.cc/Code/TimingRollover
  458. if ((long)(now - next_time) < 0) {
  459. return;
  460. }
  461. if (Ethernet.maintain() & ~(0x06)) {
  462. GATEWAY_DEBUG(PSTR("!GWT:TRC:IP RENEW FAIL\n"));
  463. /* Error occurred -> IP was not renewed */
  464. return;
  465. }
  466. _w5100_spi_en(false);
  467. next_time = now + MY_IP_RENEWAL_INTERVAL_MS;
  468. }
  469. #endif