Chat freely about anything...

User avatar
By davidgraeff
#12741 Hi community,

originally I've used the ESP8266 only by the AT commands in combination with an Arduino board.
For my usecase I only need two GPIOs so I ported my app to be run by the ESP8266 directly. I'm
using the official SDK 1.0 for this and started with the AT example.

But there is one think that does not work for me:
Receive UDP broadcast packets. Sending broadcast packets works well.

Here is a minimal code example that should create an udp socket on port 3338
and ack every received packet on UART as well as via UDP.
I'm using nc -u 255.255.255.255 3338 to test (no output).
If I use nc -u 192.168.0.118 3338 (replace with the assigned IP) I get the expected output.

Do I miss anything here or is this an API limitation?

GIST: https://gist.github.com/davidgraeff/a9e5900611c7a10c6729

Code: Select all#include "c_types.h"
#include "user_interface.h"
#include "espconn.h"
#include "mem.h"
#include "gpio.h"
#include "at_custom.h"
#include "osapi.h"
 
/**
 * Minimal example: Setup wifi for station mode, setup connection, wait for an IP.
 * If an IP has been assigned (we poll for that every 3s), start a udp socket. No remote
 * IP set, only local port set.
 * Expected: Broadcast UDP works.
 * Current behaviour: Only unicast traffic is accepted, no broadcast packets.
 */
 
static struct espconn* pUdpServer;
static os_timer_t timer_check_connection;
 
static void ICACHE_FLASH_ATTR network_received(void *arg, char *data, unsigned short len) ;
static void ICACHE_FLASH_ATTR network_udp_start(void) ;
static void ICACHE_FLASH_ATTR timeout_func(void *arg);
static void ICACHE_FLASH_ATTR init_check_timer();
extern void uart_init(int uart0_br, int uart1_br);
 
void user_init(void)

    uart_init(115200, 115200);
    at_init();
 
    //Set station mode
    wifi_set_opmode( 0x1 );
 
    //Set ap settings
    char ssid[32] = "AP_NAME";
    char password[64] = "AP_PWD";
    struct station_config stationConf;
    os_memcpy(&stationConf.ssid, ssid, sizeof(ssid));
    os_memcpy(&stationConf.password, password, sizeof(password));
    wifi_station_set_config(&stationConf);
   
    init_check_timer();
}
 
static void ICACHE_FLASH_ATTR init_check_timer() {
    //Disarm timer
    os_timer_disarm(&timer_check_connection);
 
    //Setup and arm timer
    os_timer_setfn(&timer_check_connection, (os_timer_func_t *)timeout_func, 0);
    os_timer_arm(&timer_check_connection, 3000, 1);
 
    timeout_func(0);
}
 
static void ICACHE_FLASH_ATTR timeout_func(void *arg)
{
    // We execute this timer function as long as we do not have an IP assigned
    struct ip_info info;
    wifi_get_ip_info(STATION_IF, &info);
   
    at_port_print("...\n\r");
   
    if (wifi_station_get_connect_status() != STATION_GOT_IP || info.ip.addr == 0)
      return;
 
    // IP assigned, disarm timer
    os_timer_disarm(&timer_check_connection);
   
    network_udp_start();
}
 
static void ICACHE_FLASH_ATTR network_udp_start(void)
{   
    pUdpServer = (struct espconn *)os_zalloc(sizeof(struct espconn));
    pUdpServer->type=ESPCONN_UDP;
    pUdpServer->state=ESPCONN_NONE;
    pUdpServer->proto.udp= (esp_udp *)os_zalloc(sizeof(esp_udp));
    pUdpServer->proto.udp->local_port=3338;                          // Set local port to 2222
    //pUdpServer->proto.udp->remote_port=3338;                         // Set remote port
    if(espconn_create(pUdpServer) == 0)
    {
        espconn_regist_recvcb(pUdpServer, network_received);
        at_port_print("UDP OK\n\r");
    }
}
 
static void ICACHE_FLASH_ATTR network_received(void *arg, char *data, unsigned short len)
{
    // print ACK on UART
    at_port_print("UDP received\n\r");
 
    // send ACK to sender via udp
    struct espconn *udpconn=(struct espconn *)arg;
    static const char msg[] = "REC\n";
    espconn_sent(udpconn, (uint8 *)msg, sizeof(msg));
}
User avatar
By eriksl
#28961 Are you sure the UDP broadcast packets are actually sent? On Unix (Linux) you need to explicitly enable broadcasting on an UDP socket, otherwise it will be denied.