2019/02/24

ESP8266 - Receive broadcast UDP packets sent from Packet Sender

This post is about how to use ESP8266 to receive incoming UDP broadcast message.

Schematic


Note,
- 2 NodeMCUs are connected to a laptop via 2 USB-UART Cables;
- 2 NodeMCUs and 1 Laptop are connected to the same wireless router (in this case, a Xiaomi Ethernet Over Power Line Device) via WiFi;
- The 3 IPs shown above are assigned via DHCP.

Additional Software Needed

1. Download and install Packet Sender from the link below:
https://packetsender.com/

2. Download and install Wireshark from the link below:
https://www.wireshark.org/

Note, Wireshare is optional.

The Code

Note, Load the code below to the 2 NodeMCU boards.

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "SSID";
const char* password = "SSID_PASSWORD";

WiFiUDP Udp;
unsigned int localUdpPort = 4210;     // local port to listen on
char incomingPacket[255];             // buffer for incoming packets
char replyPacket[] = "Hi there! Got the message :-)";   // a reply string to send back

void setup()
{
  Serial.begin(115200);
  Serial.println();

  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" connected");

  Udp.begin(localUdpPort);
  Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}


void loop()
{
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    // receive incoming UDP packets
    Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(incomingPacket, 255);
    if (len > 0)
    {
      incomingPacket[len] = 0;
    }
    Serial.printf("UDP packet contents: %s\n", incomingPacket);

    // send back a reply, to the IP address and port we got the packet from
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(replyPacket);
    Udp.endPacket();
  }
}

Test Procedures

1. Launch serial monitor and reset the 2 NodeMCU boards.

The IP address of the 2 NodeMCU modules as well as the port no.


2. Launch Packet Sender

3. Enter the needed info. as shown below.

Note,
- The address entered needs to match the address assigned by the router. For instance, if the address assigned by the router is "192.168.0.xxx", use "192.168.0.255" instead of the "192.168.31.255" shown below;
- The port no. entered (4210 in this case) needs to match the port no. specified in the code.


4. Click the Send button to send the packets.

5. The sent packets are received by both NodeMCU boards and the contents are display in the 2 Serial Monitors.


6. Packet Sender receives the reply from the 2 NodeMCU boards.


--------------------------------------------------------------------------------------------------------------------------

Monitor the packets sent using Wireshark

1. Launch Wireshark.

2. Select the network interface for capturing packets.

For my case, it's WiFi.


3. Select "Capture" from the pull down menu, then select "Options".

Select only WiFi.


Click the "Start" button to start capturing packets.


4. From the laptop, use Packet Sender to send UDP packets to the 2 NodeMCU boards.


5. After the packets are sent from Packet Sender, switch to Wireshark then click the red square on the upper left hand corner to stop packet capture.


6. Click on "Destination" to sort the data according to Destination address.

What we want to see in the captured packets is UDP packets sent from a laptop (192.168.31.178) to a broadcast address (192.168.31.255) that contains the key phrase "Hello World 123". The finding below matches our search criteria.


7. Alternatively, we could click on "Protocol" to sort the captured packets by their protocol.

In the photo below, there are 3 UDP packets. One of them is from the laptop to the 2 NodeMCU boards (which contains the text "Hello World 123"). The other 2 are from the 2 NodeMCU boards to the laptop which contains the "Hi there! Got the message :-)" text).


Reference:

esp8266 udp broadcast
https://www.youtube.com/watch?v=VwEHfQNA4go

ESP8266 Arduino UDP Example
https://github.com/esp8266/Arduino/blob/master/doc/esp8266wifi/udp-examples.rst

FINDING AN ESP8266 ON A NETWORK
https://www.esp8266.com/viewtopic.php?f=29&t=4209

Q.:
I'm wondering if anyone has something that can find the ESP8266 on the network? I'm thinking something along the lines of sending a ping on a specific port to every device on the network and having the ESP listen on that port and reply with a magic packet or something?

A1.:
One possible way would be to have your ESPs listen on a specific UDP port and then the device which wants to find them could execute a UDP broadcast on that port. The ESPs should receive and it and respond.

A2.:
Alright I have it responding to broadcast UDP packets. There was some misunderstanding by me of where to send the broadcast packet to, but it's working now.

I'll have to now write up a little java applet or something that can send these out, find the reply, check it's magic packet and launch the web-browser to connect. Code here is very slightly modified from the Arduino example here: https://www.arduino.cc/en/Tutorial/WiFiSendReceiveUDPString

#include <Time.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <NeoPixelBus.h>
#include <EEPROM.h>
#include <ntp.h>
#include <Ticker.h>

int status = WL_IDLE_STATUS;
char ssid[] = "SSID"; //  your network SSID (name)
char pass[] = "pass";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

unsigned int localPort = 2390;      // local port to listen on

char packetBuffer[255]; //buffer to hold incoming packet
char  ReplyBuffer[] = "acknowledged";       // a string to send back

WiFiUDP Udp;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);


  Serial.println("I'm awake");
  // attempt to connect to Wifi network:
  WiFi.begin(ssid, pass);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to wifi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  Udp.begin(localPort);
}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

}

--------------------------------------------------------------------------------------------------------------------------

How to use Wireshark to Monitor Network Traffic
https://www.computerperformance.co.uk/network-tools/how-to-use-wireshark-to-monitor-network-traffic/

No comments:

Post a Comment