From 727c61efe2ee945ad90cfb3e6119f08d8277ee0b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 28 Apr 2015 00:00:15 +0800 Subject: [PATCH] UDP multicast APIs fix fix #74, fix #7 --- libraries/ESP8266WiFi/keywords.txt | 2 ++ libraries/ESP8266WiFi/src/WiFiUdp.cpp | 31 +++++++++++++------ libraries/ESP8266WiFi/src/WiFiUdp.h | 23 ++++++++++---- .../ESP8266WiFi/src/include/UdpContext.h | 15 +++++++++ libraries/ESP8266mDNS/ESP8266mDNS.cpp | 4 ++- libraries/ESP8266mDNS/ESP8266mDNS.h | 2 ++ .../mDNS_Web_Server/mDNS_Web_Server.ino | 1 - 7 files changed, 60 insertions(+), 18 deletions(-) diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index 5887f9958..f64dd135c 100644 --- a/libraries/ESP8266WiFi/keywords.txt +++ b/libraries/ESP8266WiFi/keywords.txt @@ -33,6 +33,7 @@ flush KEYWORD2 stop KEYWORD2 connected KEYWORD2 begin KEYWORD2 +beginMulticast KEYWORD2 disconnect KEYWORD2 macAddress KEYWORD2 localIP KEYWORD2 @@ -43,6 +44,7 @@ BSSID KEYWORD2 RSSI KEYWORD2 encryptionType KEYWORD2 beginPacket KEYWORD2 +beginPacketMulticast KEYWORD2 endPacket KEYWORD2 parsePacket KEYWORD2 remoteIP KEYWORD2 diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/libraries/ESP8266WiFi/src/WiFiUdp.cpp index bf7e6c881..100bc1a60 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -142,22 +142,33 @@ int WiFiUDP::beginPacket(IPAddress ip, uint16_t port) return (_ctx->connect(addr, port)) ? 1 : 0; } +int WiFiUDP::beginPacketMulticast(IPAddress multicastAddress, uint16_t port, + IPAddress interfaceAddress, int ttl) +{ + ip_addr_t mcastAddr; + mcastAddr.addr = multicastAddress; + ip_addr_t ifaceAddr; + ifaceAddr.addr = interfaceAddress; + + if (!_ctx) { + _ctx = new UdpContext; + _ctx->ref(); + } + if (!_ctx->connect(mcastAddr, port)) { + return 0; + } + _ctx->setMulticastInterface(ifaceAddr); + _ctx->setMulticastTTL(ttl); + return 1; +} + int WiFiUDP::endPacket() { if (!_ctx) return 0; _ctx->send(); - return 1; -} - -int WiFiUDP::endPacketMulticast(IPAddress ip, uint16_t port) -{ - if (!_ctx) - return 0; - ip_addr_t addr; - addr.addr = (uint32_t) ip; - _ctx->send(&addr, port); + _ctx->disconnect(); return 1; } diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.h b/libraries/ESP8266WiFi/src/WiFiUdp.h index 4f0941af1..d06d3c194 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.h +++ b/libraries/ESP8266WiFi/src/WiFiUdp.h @@ -40,9 +40,13 @@ public: operator bool() const { return _ctx != 0; } - virtual uint8_t begin(uint16_t port); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use - virtual void stop(); // Finish with the UDP socket - uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port); // connect to a multicast group and listen on the given port + // initialize, start listening on specified port. + // Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t begin(uint16_t port); + // Finish with the UDP connetion + virtual void stop(); + // join a multicast group and listen on the given port + uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port); // Sending UDP packets @@ -52,12 +56,19 @@ public: // 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 virtual int beginPacket(const char *host, uint16_t port); + // Start building up a packet to send to the multicast address + // multicastAddress - muticast address to send to + // interfaceAddress - the local IP address of the interface that should be used + // use WiFi.localIP() or WiFi.softAPIP() depending on the interface you need + // ttl - multicast packet TTL (default is 1) + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacketMulticast(IPAddress multicastAddress, + uint16_t port, + IPAddress interfaceAddress, + int ttl = 1); // Finish off this packet and send it // Returns 1 if the packet was sent successfully, 0 if there was an error virtual int endPacket(); - // Send the packet to a multicast address - // Returns 1 if the packet was sent successfully, 0 if there was an error - int endPacketMulticast(IPAddress ip, uint16_t port); // Write a single byte into the packet virtual size_t write(uint8_t); // Write size bytes from buffer into the packet diff --git a/libraries/ESP8266WiFi/src/include/UdpContext.h b/libraries/ESP8266WiFi/src/include/UdpContext.h index 216c53928..dcf585639 100644 --- a/libraries/ESP8266WiFi/src/include/UdpContext.h +++ b/libraries/ESP8266WiFi/src/include/UdpContext.h @@ -94,6 +94,21 @@ public: udp_disconnect(_pcb); } + void setMulticastInterface(ip_addr_t addr) + { + // newer versions of lwip have a macro to set the multicast ip + // udp_set_multicast_netif_addr(_pcb, addr); + _pcb->multicast_ip = addr; + } + + void setMulticastTTL(int ttl) + { + // newer versions of lwip have an additional field (mcast_ttl) for this purpose + // and a macro to set it instead of direct field access + // udp_set_multicast_ttl(_pcb, ttl); + _pcb->ttl = ttl; + } + size_t getSize() const { if (!_rx_buf) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 5866ab169..14ff6bcf8 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -62,6 +62,7 @@ MDNSResponder::~MDNSResponder() { bool MDNSResponder::begin(const char* domain, IPAddress addr, uint32_t ttlSeconds) { + _localAddr = addr; // Construct DNS request/response fully qualified domain name of form: // , , 5, "local" size_t n = strlen(domain); @@ -190,8 +191,9 @@ void MDNSResponder::update() { Serial.print("responding, i="); Serial.println(i); #endif + _mdnsConn.beginPacketMulticast(IPAddress(224, 0, 0, 251), 5353, _localAddr); _mdnsConn.write(_response, _responseLen); - _mdnsConn.endPacketMulticast(IPAddress(224, 0, 0, 251), 5353); + _mdnsConn.endPacket(); _index = 0; } } diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index 560a0336f..65dd491ec 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -64,6 +64,8 @@ private: int _responseLen; // Socket for MDNS communication WiFiUDP _mdnsConn; + // local IP Address + IPAddress _localAddr; }; #endif //ESP8266MDNS_H diff --git a/libraries/ESP8266mDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino b/libraries/ESP8266mDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino index 4cc39ab7a..c174f4638 100644 --- a/libraries/ESP8266mDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino +++ b/libraries/ESP8266mDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino @@ -53,7 +53,6 @@ void setup(void) // the fully-qualified domain name is "esp8266.local" // - second argument is the IP address to advertise // we send our IP address on the WiFi network - // Note: for AP mode we would use WiFi.softAPIP()! if (!mdns.begin("esp8266", WiFi.localIP())) { Serial.println("Error setting up MDNS responder!"); while(1) {