Skip to content

Concepts First

  • UDP broadcast: sends a datagram to all devices on the same LAN; the destination is 255.255.255.255 (subnet-wide) or a subnet broadcast address like 192.168.1.255.
  • Use cases: LAN device discovery ("who is online?"), service announcements, LAN time sync. Broadcasts are not forwarded across routers.
  • SO_BROADCAST: for safety, lwIP denies broadcast by default; you must enable it with setsockopt(SOL_SOCKET, SO_BROADCAST).
  • Receiving broadcasts: bind the socket to the port and enable SO_BROADCAST to receive broadcasts/replies.

Example Overview

The SDK has no UDP broadcast example; this self-written example is built on the wifi_tcp skeleton:

  • after getting an IP, creates udp_broadcast_task;
  • enables SO_BROADCAST and binds local port 6000;
  • broadcasts hello broadcast to 255.255.255.255:6000 every 2 seconds;
  • also receives LAN broadcasts/replies and prints them, demonstrating one-to-many.
  • Related reference: to send to a fixed group use UDP Multicast; point-to-point use UDP Client.

Operation Steps

1
Enter the Example Directory

The SDK has no UDP broadcast example; this page is written on the wifi_tcp skeleton (marked self-written). First enter the directory:

cd examples/wifi/sta/wifi_tcp
2
Replace main.c

Overwrite main.c in the example directory with the self-written one below:

3
Build the Project

Both Ai-M61 and Ai-M62 use bl616:

make CHIP=bl616 BOARD=bl616dk
4
Flash the Firmware

Hold BOOT, briefly press EN/RST to enter download mode, then flash:

make flash CHIP=bl616 COMX=/dev/ttyUSB0
5
Connect Wi-Fi and Verify

Serial tool at 2000000 baud. After connecting, the program broadcasts to 255.255.255.255:6000 every 2 seconds and prints received broadcasts/replies. Run nc -u -l 6000 on another machine on the same Wi-Fi to observe.

wifi_sta_connect Your_SSID 12345678

Code Execution Flow

The complete UDP broadcast flow from boot to send/receive:

APIs Used by the Example

setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt))

Enables broadcast sending, opt = 1. Without this, sendto to a broadcast address fails.

Parameters:

  • sock: socket handle
  • SO_BROADCAST: option name
  • &opt: int, 1 to allow

Return: 0 on success; -1 on failure

bind(sock, addr, len)

Binds the socket to a local port (0.0.0.0:6000 in the example) so broadcasts and replies to that port are received.

Parameters:

  • sock: socket handle
  • addr: sockaddr_in with htons(6000) and INADDR_ANY

Return: 0 on success; -1 on failure

sendto / recvfrom(sock, buf, len, 0, addr, len)

Sending uses the broadcast address 255.255.255.255:6000; receiving returns the sender's address so you can tell which device sent it.

Parameters:

  • sock: socket handle
  • addr / len: destination (send) / source (receive)

Return: bytes transferred; < 0 on error

Complete Code

The self-written main.c below (built on the SDK wifi_tcp skeleton; not an SDK file). Collapsed by default; click to expand:

📜 Click to expand self-written udp_broadcast main.c full code
c
/*
 * Self-written example: UDP broadcast (based on lwIP sockets)
 * Usage:
 *   1. Overwrite examples/wifi/sta/wifi_tcp/main.c with this file;
 *   2. make CHIP=bl616 BOARD=bl616dk && make flash CHIP=bl616 COMX=/dev/ttyUSB0;
 *   3. Run wifi_sta_connect <SSID> <password> on the serial shell; the program broadcasts/receives automatically.
 */

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"

#include <string.h>

#include <lwip/tcpip.h>
#include <lwip/sockets.h>
#include <lwip/netdb.h>

#include "wifi_mgmr_ext.h"
#include "fhost_api.h"
#include "wifi_mgmr.h"

#include "bflb_irq.h"
#include "bflb_uart.h"

#include "rfparam_adapter.h"
#include "async_event.h"
#include "mm.h"
#include "board.h"
#include "shell.h"

#define DBG_TAG "MAIN"
#include "log.h"

#define UDP_BROADCAST_PORT 6000

static volatile uint32_t wifi_state = 0;
static struct bflb_device_s *uart0;

extern void shell_init_with_task(struct bflb_device_s *shell);

void wifi_event_handler(async_input_event_t ev, void *priv)
{
    switch (ev->code) {
        case CODE_WIFI_ON_GOT_IP:
            wifi_state = 1;
            LOG_I("Got IP\r\n");
            break;
        case CODE_WIFI_ON_DISCONNECT:
            wifi_state = 0;
            LOG_I("WiFi disconnected\r\n");
            break;
        default:
            break;
    }
}

static void udp_broadcast_task(void *param)
{
    int sock;
    int opt = 1;
    struct sockaddr_in local, bcast, remote;
    socklen_t addr_len = sizeof(remote);
    char send_buf[] = "hello broadcast";
    char recv_buf[128];

    /* Wait for Wi-Fi to get an IP */
    while (!wifi_state) {
        vTaskDelay(pdMS_TO_TICKS(200));
    }

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        LOG_E("create socket failed\r\n");
        vTaskDelete(NULL);
        return;
    }

    /* Allow broadcast sending */
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) < 0) {
        LOG_E("set SO_BROADCAST failed\r\n");
    }

    /* Bind local port to receive broadcasts and replies */
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(UDP_BROADCAST_PORT);
    local.sin_addr.s_addr = INADDR_ANY;
    if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0) {
        LOG_E("bind failed\r\n");
    }

    /* Broadcast address: 255.255.255.255 means all devices on the current subnet */
    memset(&bcast, 0, sizeof(bcast));
    bcast.sin_family = AF_INET;
    bcast.sin_port = htons(UDP_BROADCAST_PORT);
    bcast.sin_addr.s_addr = inet_addr("255.255.255.255");

    LOG_I("UDP broadcast start, port %d\r\n", UDP_BROADCAST_PORT);

    while (1) {
        int ret = sendto(sock, send_buf, strlen(send_buf), 0,
                         (struct sockaddr *)&bcast, sizeof(bcast));
        if (ret < 0) {
            LOG_E("sendto broadcast failed\r\n");
        } else {
            LOG_I("broadcast send %d bytes\r\n", ret);
        }

        ret = recvfrom(sock, recv_buf, sizeof(recv_buf) - 1, 0,
                       (struct sockaddr *)&remote, &addr_len);
        if (ret >= 0) {
            recv_buf[ret] = '\0';
            LOG_I("recv %d bytes from %s: %s\r\n",
                  ret, inet_ntoa(remote.sin_addr), recv_buf);
        }

        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

static void wifi_start_firmware_task(void *param)
{
    LOG_I("Starting wifi ...\r\n");
    async_register_event_filter(EV_WIFI, wifi_event_handler, NULL);
    wifi_task_create();
    LOG_I("Starting fhost ...\r\n");
    fhost_init();
    vTaskDelete(NULL);
}

int main(void)
{
    board_init();

    uart0 = bflb_device_get_by_name("uart0");
    shell_init_with_task(uart0);

    if (0 != rfparam_init(0, NULL, 0)) {
        LOG_I("PHY RF init failed!\r\n");
        return 0;
    }

    tcpip_init(NULL, NULL);

    xTaskCreate(wifi_start_firmware_task, "wifi init", 1024, NULL, 10, NULL);
    xTaskCreate(udp_broadcast_task, "udp bcast", 1024, NULL, 11, NULL);

    vTaskStartScheduler();

    while (1) {
    }
}

FAQ

sendto to the broadcast address fails

Make sure setsockopt(SOL_SOCKET, SO_BROADCAST) succeeded; lwIP denies broadcast by default, so without this option the send returns an error.

Other devices cannot receive the broadcast

Broadcasts only travel within the same LAN (same router/switch); different subnets cannot receive them. If the router has "AP isolation" enabled, clients are isolated from each other — disable it.

Have questions?

For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23