Skip to content

AsyncUDP listenMulticast not binding to a specific TCPIP Interface #7328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
me-no-dev opened this issue Oct 6, 2022 Discussed in #7327 · 1 comment
Open

AsyncUDP listenMulticast not binding to a specific TCPIP Interface #7328

me-no-dev opened this issue Oct 6, 2022 Discussed in #7327 · 1 comment
Assignees
Labels
Status: Needs investigation We need to do some research before taking next steps on this issue
Milestone

Comments

@me-no-dev
Copy link
Member

Discussed in #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.

//=================Code Begin=================


#include <WiFi.h>
#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.

@me-no-dev me-no-dev self-assigned this Oct 6, 2022
@me-no-dev me-no-dev added the Status: Needs investigation We need to do some research before taking next steps on this issue label Oct 6, 2022
@VojtechBartoska VojtechBartoska added this to the 2.0.6 milestone Oct 10, 2022
@VojtechBartoska VojtechBartoska modified the milestones: 2.0.6, 3.0.0 Nov 21, 2022
@VojtechBartoska VojtechBartoska modified the milestones: 3.0.0, 3.1.0 Feb 20, 2024
@VojtechBartoska
Copy link
Contributor

Changing this to 3.1.0 milestone.

@rftafas rftafas modified the milestones: 3.1.0, 3.1.1 Jan 6, 2025
@rftafas rftafas modified the milestones: 3.1.1, 3.2.0 Jan 14, 2025
@Parsaabasi Parsaabasi modified the milestones: 3.2.0, 3.3.0 Mar 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Needs investigation We need to do some research before taking next steps on this issue
Projects
Development

No branches or pull requests

4 participants