espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
12.99k stars 7.29k forks source link

AsyncUDP listenMulticast not binding to a specific TCPIP Interface #7328

Open me-no-dev opened 1 year ago

me-no-dev commented 1 year ago

Discussed in https://github.com/espressif/arduino-esp32/discussions/7327

Originally posted by **babushona** October 6, 2022 Hello, What is the 3rd argument of this function for? _bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl, **tcpip_adapter_if_t tcpip_if**)_ I have started ESP32 in AP+STA mode. AP got the address 192.168.4.1. STA connected to my home network and got IP address 192.168.5.188. I wanted the UDP multicast to be listened for only on my AP interface (not on STA interface). Following is my test code, mostly borrowed from Multicast Example of AsyncUDP library. ```cpp //=================Code Begin================= #include #include "AsyncUDP.h" #define debug Serial //Wifi Network Connection Parameters for STA interface const char* wifi_network_ssid = "My_Home_Network"; const char* wifi_network_password = "My_Home_Network_Pass"; //Wifi Network Connection Parameters for STA interface const char *soft_ap_ssid = "My_Esp_AP"; const char *soft_ap_password = "My_Esp_AP_Pass"; AsyncUDP udp; volatile boolean pkt_received=false; unsigned long time_last, time_now; void setup() { debug.begin(115200); WiFi.mode(WIFI_MODE_APSTA); debug.printf("Starting AP: '%s' \n", soft_ap_ssid); WiFi.softAP(soft_ap_ssid, soft_ap_password); debug.printf("Connecting to WiFi over STA I/F to network '%s'\n", wifi_network_ssid); WiFi.begin(wifi_network_ssid, wifi_network_password); //TODO: Add a timeout logic while (WiFi.status() != WL_CONNECTED) { delay(500); debug.print("."); } debug.printf("\nConnected to WiFi Station network '%s'. IP: %s\n", wifi_network_ssid, WiFi.localIP().toString().c_str()); debug.printf("AP Interface IP Address: '%s'\n", WiFi.softAPIP().toString().c_str()); debug.print("TCPIP_ADAPTER_IF_STA="); debug.println(TCPIP_ADAPTER_IF_STA); debug.print("TCPIP_ADAPTER_IF_AP="); debug.println(TCPIP_ADAPTER_IF_AP); debug.print("TCPIP_ADAPTER_IF_ETH="); debug.println(TCPIP_ADAPTER_IF_ETH); debug.print("TCPIP_ADAPTER_IF_TEST="); debug.println(TCPIP_ADAPTER_IF_TEST); debug.print("TCPIP_ADAPTER_IF_MAX="); debug.println(TCPIP_ADAPTER_IF_MAX); if(udp.listenMulticast(IPAddress(239,1,2,3), 1234, TCPIP_ADAPTER_IF_AP)) { //Start listening for UDP Multicast on AP interface only debug.printf("UDP Listening on IP: '%s'\n", WiFi.softAPIP().toString().c_str()); udp.onPacket([](AsyncUDPPacket packet) { pkt_received=true; Serial.printf("%lu ms:", millis()); Serial.print("UDP Packet Received. Type: "); Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast"); Serial.print(", Received at i/f: "); Serial.print(packet.interface()); //0: STA Interface. 1: AP Interface Serial.print(", From: "); Serial.print(packet.remoteIP()); Serial.print(":"); Serial.print(packet.remotePort()); Serial.print(", To: "); Serial.print(packet.localIP()); Serial.print(":"); Serial.print(packet.localPort()); Serial.print(", Length: "); Serial.print(packet.length()); Serial.print(", Data: "); Serial.write(packet.data(), packet.length()); Serial.println(); //reply to the client packet.printf("Got %u bytes of data", packet.length()); }); } } void loop() { unsigned long time_diff; //Switch on LED when UDP multicast packet is received if (pkt_received) { digitalWrite(LED_BUILTIN, HIGH); time_last = millis(); pkt_received=false; } //Switch off the LED after 2 seconds time_now = millis(); time_diff = time_now - time_last; if (time_diff > 2000){ digitalWrite(LED_BUILTIN, LOW); } } //=================Code End================= ``` After booting ESP32 with this code, I connect my laptop to ESP AP and get IP address 192.168.4.2. Now my laptop and ESP AP interface are on same network. I used PacketSender to send a UDP packet to 239.1.2.3:1234. It gets received by ESP32, as expected. Then I disconnect my laptop from ESP AP, and connect to my home network. It gets IP address 192.168.5.165. Now my laptop and ESP STA interface are on same network. Using PacketSender, I again send same multicast packet to 239.1.2.3.4:1234. This time, I wasn't expecting this multicast packet to be received by ESP32. But, it received the packet. And surprisingly, it received it on STA interface where there should not be any listener at all. This is the Serial monitor output. ``` //=================Output Begin================= Starting AP: 'My_Esp_AP' Connecting to WiFi Station network 'My_Home_Network' Connected to WiFi Station network 'My_Home_Network'. IP: 192.168.5.188 AP Interface IP Address: '192.168.4.1' TCPIP_ADAPTER_IF_STA=0 TCPIP_ADAPTER_IF_AP=1 TCPIP_ADAPTER_IF_ETH=2 TCPIP_ADAPTER_IF_TEST=3 TCPIP_ADAPTER_IF_MAX=4 UDP Listening on IP: '192.168.4.1' 13859ms: UDP Packet Received. Type: Multicast, Received at i/f: 1, From: 192.168.4.2:49795, To: 239.1.2.3:1234, Length: 6, Data: hello 31183ms: UDP Packet Received. Type: Multicast, Received at i/f: 0, From: 192.168.5.165:49795, To: 239.1.2.3:1234, Length: 6, Data: hello //=================Output End================= ``` I am not sure whether this is a bug in the AsynUDP library or I am misinterpreting the multicast behavior. What I expect is, by specifying the 3rd argument of ListenMulticast as "AP", multicast will be listened for **only** at AP interface. Is this correct expectation? Thanks for any help.
VojtechBartoska commented 4 months ago

Changing this to 3.1.0 milestone.