diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/libraries/ESP8266WiFi/src/WiFiUdp.cpp index 94e5339ab..ecf3f858f 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -35,6 +35,7 @@ extern "C" #include "lwip/opt.h" #include "lwip/udp.h" #include "lwip/inet.h" +#include "lwip/igmp.h" #include "include/UdpContext.h" /* Constructor */ @@ -73,6 +74,32 @@ uint8_t WiFiUDP::begin(uint16_t port) return (_ctx->listen(addr, port)) ? 1 : 0; } +uint8_t WiFiUDP::beginMulticast(IPAddress multicast, uint16_t port) +{ + if (_ctx) + { + _ctx->unref(); + _ctx = 0; + } + + + ip_addr_t ifaddr; + ifaddr.addr = (uint32_t) WiFi.localIP(); + ip_addr_t multicast_addr; + multicast_addr.addr = (uint32_t) multicast; + + if (igmp_joingroup(&ifaddr, &multicast_addr)!= ERR_OK) { + return 0; + } + + _ctx = new UdpContext; + if (!_ctx->listen(*IP_ADDR_ANY, port)) { + return 0; + } + + return 1; +} + /* return number of bytes available in the current packet, will return zero if parsePacket hasn't been called yet */ int WiFiUDP::available() { @@ -117,6 +144,17 @@ int WiFiUDP::endPacket() 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); + return 1; } size_t WiFiUDP::write(uint8_t byte) diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.h b/libraries/ESP8266WiFi/src/WiFiUdp.h index ce1cf8ef0..a5d5586d5 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.h +++ b/libraries/ESP8266WiFi/src/WiFiUdp.h @@ -38,8 +38,11 @@ public: WiFiUDP& operator=(const WiFiUDP& rhs); ~WiFiUDP(); + 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 multicast, uint16_t port); // connect to a multicast group and listen on the given port // Sending UDP packets @@ -52,6 +55,9 @@ public: // 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 4efcaf10f..33b2d36d7 100644 --- a/libraries/ESP8266WiFi/src/include/UdpContext.h +++ b/libraries/ESP8266WiFi/src/include/UdpContext.h @@ -194,7 +194,7 @@ public: return size; } - void send() + void send(ip_addr_t* addr = 0, uint16_t port = 0) { size_t orig_size = _tx_buf_head->tot_len; @@ -209,7 +209,10 @@ public: } } - udp_send(_pcb, _tx_buf_head); + if (addr) + udp_sendto(_pcb, _tx_buf_head, addr, port); + else + udp_send(_pcb, _tx_buf_head); for (pbuf* p = _tx_buf_head; p; p = p->next) {