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
#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));
}