Reputation: 279
I'm attempting to configure a number of connected ESP32 stations via a single ESP32 AP. The easiest way for me to do this would be to send a single broadcast UDP packet to 255.255.255.255. However, my stations which are listening with an open UDP port are not receiving broadcast data at all. Is there something else I need to configure on the station/AP for this to be possible?
I've done a bit of reading and it seems like lwip/opt.h may have been prohibiting detecting broadcast packets, but after setting IP_SOF_BROADCAST
and IP_SOF_BROADCAST_RECV
I've seen no difference.
Here's my current station UDP listening task:
static void udp_listen_task(void *pvParameters)
{
while (1) {
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
int addr_family = AF_INET;
int ip_protocol = IPPROTO_IP;
inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1);
int sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
if (sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
break;
}
//ESP_LOGI(TAG, "Socket created");
int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err < 0) {
ESP_LOGE(TAG, "Socket unable to bind: err %d", err);
}
while (1) {
struct sockaddr_in6 source_addr;
socklen_t socklen = sizeof(source_addr);
int len = recvfrom(sock, &controller_msg, sizeof(controller_msg), 0, (struct sockaddr *)&source_addr, &socklen);
//Error occurred during receiving
if (len < 0) {
ESP_LOGE(TAG, "recvfrom failed: errno %d", errno);
break;
}
// Data received
else {
// Get the sender's ip address as string
if (source_addr.sin6_family == PF_INET) {
inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
} else if (source_addr.sin6_family == PF_INET6) {
inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1);
}
// Post event to act on message
xEventGroupSetBits(conn_evt, CONN_EVT_UDP_RECEIVED);
}
}
if (sock != -1) {
ESP_LOGE(TAG, "Shutting down socket and restarting...");
shutdown(sock, 0);
close(sock);
}
}
vTaskDelete(NULL);
}
Upvotes: 2
Views: 2450
Reputation: 4762
Looks like your listening socket is missing the SO_BROADCAST
option. You need something like this after creating the socket:
int bc = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bc, sizeof(bc)) < 0) {
ESP_LOGE(TAG, "Failed to set sock options: errno %d", errno);
closesocket(sock);
break;
}
Have a look at this example
Hint: if this doesn't help, then perhaps you also need a quick check to verify that the sender is actually broadcasting. Hook a computer to the same WiFi network and run WireShark to see the UDP packets in the air.
Upvotes: 2