Overview
Soft-AP mode turns the Ai-WB2 into a Wi-Fi hotspot (sending out a Wi-Fi signal like a phone's personal hotspot); phones/computers can connect directly to the board, commonly used for device provisioning and LAN direct control. The board's default IP (the "house number" on the network) is 192.168.169.1, and joined devices get their IP from the onboard DHCP server (the little steward that assigns IPs automatically). This tutorial demonstrates starting the hotspot and observing device join events.
In plain words: Soft-AP is the board "opening its own hotspot" — it sends out a Wi-Fi signal (named SSID), and the phone connects to it like connecting to home Wi-Fi, communicating with the board directly without any router. The board gives the hotspot a fixed "house number" 192.168.169.1; whoever joins, the DHCP little steward inside the board automatically hands them an IP. Commonly used for provisioning devices and directly controlling devices on the LAN.
This tutorial is based on the official Ai-Thinker SDK (Ai-Thinker-Open/Ai-Thinker-WB2, version
release_bl_iot_sdk_1.6.40) exampleapplications/wifi/softAP; the code can be found directly in your local SDK.
Open a terminal and enter the official softAP example project directory:
cd ~/Ai-Thinker-WB2/applications/wifi/softAP
Note:
cdis the “change directory” command, entering the official example project; all subsequentmakecommands must run in this directory.
Open softAP/main.c and change the hotspot name (SSID, the Wi-Fi’s name) and password at the top:
#define AP_SSID "ai-thinker"
#define AP_PWD "12345678"
For example:
#define AP_SSID "WB2-Hotspot"
#define AP_PWD "88888888"
💡 The hotspot password must be at least 8 characters (a WPA2 encryption requirement; shorter than 8 and the hotspot won’t start); search for the hotspot with your phone to join and test.
Open softAP/main.c. The full code for this step has been moved to the end of this page:
📜 Full Code — in the “Full Code” section below, collapsed by default — click to expand, identical to the official example (
applications/wifi/softAP/softAP/main.c).
Code highlights:
| Code | Purpose |
|---|---|
wifi_mgmr_ap_enable() |
Enable AP mode first; without it the hotspot-start functions that follow are all unusable |
wifi_mgmr_conf_max_sta(4) |
Limit to at most 4 joined devices, preventing the hotspot from being overwhelmed |
wifi_mgmr_ap_start(if, ssid, 0, pwd, 6) |
Actually starts the hotspot: name, channel 0 (auto), password, encryption 6 (WPA2) |
wifi_ap_ip_set(...) |
Gives the hotspot its “house number” IP 192.168.169.1, netmask, gateway |
netif_find("ap1") |
Finds the hotspot network interface (ap1); must find it before changing the IP |
CODE_WIFI_ON_AP_STA_ADD |
Notification that a device joined the hotspot; do business here |
CODE_WIFI_ON_AP_STA_DEL |
Notification that a device left the hotspot; do business here |
💡 The default gateway IP
192.168.169.1is defined by theDHCPD_SERVER_IPmacro at line 42 ofcomponents/network/lwip_dhcpd/dhcp_server_raw.c; to switch subnets (e.g.192.168.4.1) you must change both that macro and thewifi_ap_ip_setarguments.
Build in the project directory:
make -j8
Note:
makeis the “build” command, turning code into firmware (the program flashed into the board) the board can run;-j8builds with 8 parallel cores, faster.
On success a firmware build_out/softAP.bin is generated.
Keep the board connected via USB, confirm the serial device, and flash:
make flash p=/dev/ttyUSB0 b=921600
Note:
make flashis the “flash” command, writing the compiled firmware into the board. Afterp=comes the serial device (often/dev/ttyUSB0on Linux,COM3-like on Windows — use your computer’s actual one),b=921600is the flash baud rate (serial transfer speed), keep the default.
⏳ During flashing, press and hold the EN button on the board when prompted to enter download mode; wait for the progress bar to complete — that means the flash succeeded.
After flashing, the board automatically restarts and runs. Open a serial assistant (baud rate 921600, the “speech speed” of serial data — both ends must match) and observe the logs:
[OS] Starting TCP/IP Stack...
<<<<<<<<< init wifi done <<<<<<<<<<
<<<<<<<<< startting soft ap <<<<<<<<<<<
<<<<<<<<< startt soft ap OK<<<<<<<<<<<
[softAP]:SSID:ai-thinker,PASSWORD:12345678,IP addr:192.168.169.1
Search Wi-Fi with your phone, find the hotspot ai-thinker, enter the password and connect; the serial prints:
<<<<<<<<< station connent ap <<<<<<<<<<<
When the phone disconnects it prints station disconnet ap. Visit http://192.168.169.1 in the phone browser to access the board’s Web service (needs a TCP Server application).
The phone joining the hotspot and the serial printing station connent ap means success; if the phone can’t find the hotspot, first check whether the serial printed startt soft ap OK (if not, the hotspot didn’t start); if it can be found but not joined, check that the password is 8+ characters and that you rebuilt and re-flashed after the change — see the FAQ at the end.
API Summary for This Tutorial
wifi_mgmr_ap_enable
Enables AP mode and returns the hotspot interface handle.
Return: interface handle (wifi_interface_t) on success; NULL on failure
wifi_mgmr_conf_max_sta(num)
Limits the maximum number of devices that can join the hotspot.
Parameters:
num: maximum joined devices, the official example passes4
Return: 0 on success; negative error code on failure
wifi_mgmr_ap_start(if, ssid, channel, pwd, enc)
Starts the hotspot (encryption 6 = WPA2, 0 = open).
Parameters:
if: AP interface handle (return ofwifi_mgmr_ap_enable())ssid: hotspot name (official default"ai-thinker")channel: channel (1~13)pwd: hotspot password (official default"12345678"), passNULLfor an open networkenc: encryption (6= WPA2,0= open)
Return: 0 on success; negative error code on failure
wifi_mgmr_start_background(conf)
Starts the Wi-Fi manager (the scheduling core of connecting/hotspot/scanning).
Parameters:
conf:wifi_conf_tstruct pointer, optional fields:country_code(country code,"CN"for China)
Return: 0 on success; negative error code on failure
netif_find(name)
Finds a network interface by name (the hotspot interface is "ap1").
Parameters:
name: network interface name string, values:"st1"(station interface) /"ap1"(hotspot interface)
Return: struct netif* on success; NULL on failure
netif_set_ipaddr / netif_set_netmask / netif_set_gw(netif, addr)
Sets the network interface IP / subnet mask / gateway.
Parameters:
netif: target interface (return ofnetif_find)addr:ip4_addr_tpointer, constructed with theIP4_ADDRmacro
Return: none
netif_set_down / netif_set_up(netif)
Brings the network interface down / up.
Parameters:
netif: target interface (return ofnetif_find)
Return: none
IP4_ADDR(addr, a, b, c, d)
Constructs an IP address from 4 integer segments (network byte order).
Parameters:
addr: outputip4_addr_tpointera, b, c, d: the four IP segment values, e.g.192, 168, 169, 1
Return: none
ip4addr_ntoa(addr)
Converts an IP address to a dotted-decimal string.
Parameters:
addr:ip4_addr_tpointer
Return: dotted-decimal string (e.g. "192.168.169.1")
📌 Hotspot event codes:
CODE_WIFI_ON_AP_STARTED(hotspot started) /CODE_WIFI_ON_AP_STOPPED(stopped) /CODE_WIFI_ON_AP_STA_ADD(device joined) /CODE_WIFI_ON_AP_STA_DEL(device left), defined inhal_wifi.h.
Full Code
Below is the complete softAP/main.c source, identical to the official example (applications/wifi/softAP/softAP/main.c):
📜 Click to expand the full softAP/main.c code
/**
* @file main.c
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2022-10-09
*
* @copyright Copyright (c) 2022
*
*/
#include <FreeRTOS.h>
#include <task.h>
#include <stdio.h>
#include <string.h>
#include <aos/yloop.h>
#include <aos/kernel.h>
#include <lwip/tcpip.h>
#include <wifi_mgmr_ext.h>
#include <hal_wifi.h>
#include <lwip/netif.h>
#include <lwip/inet.h>
#include <blog.h>
#define AP_SSID "ai-thinker"
#define AP_PWD "12345678"
#define TAG "softAP"
static wifi_conf_t ap_conf = {
.country_code = "CN",
};
static wifi_interface_t ap_interface;
/**
* @brief wifi_ap_ip_set
* Set the IP address of soft AP
* @param ip_addr IPV4 addr
* @param netmask netmask
* @param gw DNS
*/
static void wifi_ap_ip_set(char* ip_addr, char* netmask, char* gw)
{
struct netif* ap_netif = netif_find("ap1");
int i = 0;
int ap_ipaddr[4] = { 0 };
int ap_netmask[4] = { 255,255,255,0 };
int ap_gw_arry[4] = { 0,0,0,0 };
ap_ipaddr[0] = atoi(strtok(ip_addr, "."));
for (i = 1;i<4;i++) {
ap_ipaddr[i] = atoi(strtok(NULL, "."));
}
if (netmask) {
ap_netmask[0] = atoi(strtok(netmask, "."));
for (i = 1;i<4;i++)
ap_netmask[i] = atoi(strtok(NULL, "."));
}
if (gw) {
ap_gw_arry[0] = atoi(strtok(gw, "."));
for (i = 1;i<4;i++)
ap_gw_arry[i] = atoi(strtok(NULL, "."));
}
if (ap_netif) {
ip_addr_t ap_ip;
ip_addr_t ap_mask;
ip_addr_t ap_gw;
IP4_ADDR(&ap_ip, ap_ipaddr[0], ap_ipaddr[1], ap_ipaddr[2], ap_ipaddr[3]);
IP4_ADDR(&ap_mask, ap_netmask[0], ap_netmask[1], ap_netmask[2], ap_netmask[3]);
IP4_ADDR(&ap_gw, ap_gw_arry[0], ap_gw_arry[1], ap_gw_arry[2], ap_gw_arry[3]);
netif_set_down(ap_netif);
netif_set_ipaddr(ap_netif, &ap_ip);
netif_set_netmask(ap_netif, &ap_mask);
netif_set_gw(ap_netif, &ap_gw);
netif_set_up(ap_netif);
blog_info("[softAP]:SSID:%s,PASSWORD:%s,IP addr:%s", AP_SSID, AP_PWD, ip4addr_ntoa(netif_ip4_addr(ap_netif)));
}
else
blog_info("no find netif ap1 ");
}
/**
* @brief wifi_ap_start
*
*/
static void wifi_ap_start()
{
ap_interface = wifi_mgmr_ap_enable();
wifi_mgmr_conf_max_sta(4);
wifi_mgmr_ap_start(ap_interface, AP_SSID, 0, AP_PWD, 6);
wifi_ap_ip_set("192.168.169.1", "255.255.255.0", "192.168.169.1"); //defaut gateway ip is "192.168.169.1",if you want usb other gateway ip ,please change components/network/lwip_dhcpd/dhcp_server_raw.c:42 DHCPD_SERVER_IP
//for example, gateway ip:"192.168.4.1" , change DHCPD_SERVER_IP to "192.168.4.1" :
//wifi_ap_ip_set("192.168.4.1", "255.255.255.0", "192.168.4.1");
//components/network/lwip_dhcpd/dhcp_server_raw.c:42 #define DHCPD_SERVER_IP "192.168.4.1"
}
static void event_cb_wifi_event(input_event_t* event, void* private_data)
{
switch (event->code) {
case CODE_WIFI_ON_INIT_DONE:
blog_info("<<<<<<<<< init wifi done <<<<<<<<<<");
wifi_mgmr_start_background(&ap_conf);
break;
case CODE_WIFI_ON_MGMR_DONE:
blog_info("<<<<<<<<< startting soft ap <<<<<<<<<<<");
wifi_ap_start();
break;
case CODE_WIFI_ON_AP_STARTED:
blog_info("<<<<<<<<< startt soft ap OK<<<<<<<<<<<");
break;
case CODE_WIFI_ON_AP_STOPPED:
break;
case CODE_WIFI_ON_AP_STA_ADD:
blog_info("<<<<<<<<< station connent ap <<<<<<<<<<<");
break;
case CODE_WIFI_ON_AP_STA_DEL:
blog_info("<<<<<<<<< station disconnet ap <<<<<<<<<<<");
break;
default:
break;
}
}
static void proc_main_entry(void* pvParameters)
{
aos_register_event_filter(EV_WIFI, event_cb_wifi_event, NULL);
hal_wifi_start_firmware_task();
aos_post_event(EV_WIFI, CODE_WIFI_ON_INIT_DONE, 0);
vTaskDelete(NULL);
}
static void system_thread_init()
{
/*nothing here*/
}
void main()
{
system_thread_init();
puts("[OS] Starting TCP/IP Stack...");
tcpip_init(NULL, NULL);
puts("[OS] proc_main_entry task...");
xTaskCreate(proc_main_entry, (char*)"main_entry", 1024, NULL, 15, NULL);
}FAQ & Troubleshooting
⚠️ Phone can't find the hotspot
Cause: the hotspot didn't start successfully, or the phone's Wi-Fi is off / prefers 5GHz
Fix: confirm the serial printed startt soft ap OK; turn on the phone's Wi-Fi and wait a few seconds then search again (the hotspot is 2.4GHz)
⚠️ Wrong password prompt when joining the hotspot
Cause: the hotspot password is under 8 characters (WPA2 requirement), or the code was changed but not re-flashed
Fix: make AP_PWD at least 8 characters; rebuild and re-flash after changes
⚠️ Device joins but can't get an IP
Cause: the DHCP server isn't running, or the subnet doesn't match DHCPD_SERVER_IP
Fix: confirm dhcp_server_raw.c wasn't modified; when switching subnets change both the macro and wifi_ap_ip_set
⚠️ Want to connect to a router and open a hotspot at the same time
Cause: the official example only enables AP mode
Fix: first wifi_mgmr_sta_enable() + connect to the router, then wifi_mgmr_ap_enable() + wifi_mgmr_ap_start(); the SDK supports STA+AP coexistence
⚠️ Serial device not found / can't open
Cause: USB-to-serial driver not installed, insufficient permission, or the cable only charges and can't transfer data
Fix: on Linux check the device with lsusb/dmesg; if permission denied run sudo chmod 666 /dev/ttyUSB0; on Windows install the driver and check the COM port in Device Manager; try a data-capable cable
⚠️ Flashing keeps waiting / fails
Cause: download mode wasn't entered, wrong baud rate, or a wrong serial number
Fix: press and hold EN during flashing to enter download mode as prompted; change p=/dev/ttyUSB0 to your actual serial port; try another USB port or cable
Self-Check
The phone finds and joins the hotspot (serial prints station connent ap) — Soft-AP is verified.

