13 对于仅支持wifiscan的模块, 仅 init/scan/scanResult 函数是可用的
15 例如: Air780E/Air600E/Air780EG等仅支持wifiscan
20 #include "luat_base.h"
21 #include "luat_wlan.h"
23 #define LUAT_LOG_TAG "wlan"
26 uint32_t ipaddr_addr(const char *cp
);
28 static inline void to_ipv4(const char* data
, uint8_t* dst
) {
29 uint32_t tmpip
= ipaddr_addr(data
);
30 dst
[3] = (tmpip
>> 24) & 0xFF;
31 dst
[2] = (tmpip
>> 16) & 0xFF;
32 dst
[1] = (tmpip
>> 8) & 0xFF;
33 dst
[0] = (tmpip
>> 0) & 0xFF;
39 @return bool 成功返回true,否则返回false
41 static int l_wlan_init(lua_State
* L
){
42 int ret
= luat_wlan_init(NULL
);
43 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
49 @api wlan.setMode(mode)
51 @return bool 成功返回true,否则返回false
53 -- 设置为AP模式, 广播ssid, 接收wifi客户端的链接
56 -- 设置为STATION模式, 也是初始化后的默认模式
57 wlan.setMode(wlan.STATION)
60 wlan.setMode(wlan.APSTA)
62 static int l_wlan_mode(lua_State
* L
){
63 int mode
= LUAT_WLAN_MODE_STA
;
64 if (lua_isinteger(L
, 1)) {
65 mode
= lua_tointeger(L
, 1);
67 else if (lua_isinteger(L
, 2)) {
68 mode
= lua_tointeger(L
, 2);
71 if (mode
<= LUAT_WLAN_MODE_NULL
|| mode
>= LUAT_WLAN_MODE_MAX
) {
72 mode
= LUAT_WLAN_MODE_STA
;
77 // case LUAT_WLAN_MODE_NULL:
78 // LLOGD("wlan mode NULL");
80 // case LUAT_WLAN_MODE_STA:
81 // LLOGD("wlan mode STATION");
83 // case LUAT_WLAN_MODE_AP:
84 // LLOGD("wlan mode AP");
86 // case LUAT_WLAN_MODE_APSTA:
87 // LLOGD("wlan mode AP-STATION");
93 luat_wlan_config_t conf
= {
96 int ret
= luat_wlan_mode(&conf
);
97 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
102 作为STATION时,是否已经连接上AP,且获取IP成功
104 @return bool 已经连接成功返回true,否则返回false
106 static int l_wlan_ready(lua_State
* L
){
107 lua_pushboolean(L
, luat_wlan_ready());
113 @api wlan.connect(ssid, password, auto_reconnect, bssid)
115 @string AP的password,可选
116 @int 0关闭自动重连,1开启自动重连.当前强制开启自动重连
117 @string AP的bssid,可选,必须是6字节
118 @return bool 发起连接成功返回true,否则返回false.注意,不代表连接AP成功!!
122 wlan.connect("myap", "12345678")
125 -- 特殊模式, 重用之前的ssid和密码,本次直接连接
126 -- 注意, 前提是本次上电后已经传过ssid和或password,否则必失败
129 -- 特殊模式, 使用ssid和密码,本次连接指定bssid, 2024.5.7新增
130 local bssid = string.fromHex("00182946365f")
131 wlan.connect("myap", "12345678", 1, bssid)
133 static int l_wlan_connect(lua_State
* L
){
134 const char* ssid
= luaL_optstring(L
, 1, "");
135 const char* password
= luaL_optstring(L
, 2, "");
137 luat_wlan_conninfo_t info
= {0};
138 info
.auto_reconnection
= 1;
139 memcpy(info
.ssid
, ssid
, strlen(ssid
));
140 memcpy(info
.password
, password
, strlen(password
));
141 const char* bssid
= luaL_optlstring(L
, 4, "", &len
);
143 memcpy(info
.bssid
, bssid
, 6);
146 int ret
= luat_wlan_connect(&info
);
147 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
153 @api wlan.disconnect()
155 static int l_wlan_disconnect(lua_State
* L
){
157 luat_wlan_disconnect();
165 -- 注意, wlan.scan()是异步API,启动扫描后会马上返回
167 -- wifi扫描成功后, 会有WLAN_SCAN_DONE消息, 读取即可
168 sys.subscribe("WLAN_SCAN_DONE", function ()
169 local results = wlan.scanResult()
170 log.info("scan", "results", #results)
171 for k,v in pairs(results) do
172 log.info("scan", v["ssid"], v["rssi"], (v["bssid"]:toHex()))
176 -- 下面演示的是初始化wifi后定时扫描,请按实际业务需求修改
177 sys.taskInit(function()
186 static int l_wlan_scan(lua_State
* L
){
194 @api wlan.scanResult()
197 -- 用法请查阅 wlan.scan() 函数
199 static int l_wlan_scan_result(lua_State
* L
) {
200 int ap_limit
= luaL_optinteger(L
, 1, 20);
203 else if (ap_limit
< 8)
206 luat_wlan_scan_result_t
*results
= luat_heap_malloc(sizeof(luat_wlan_scan_result_t
) * ap_limit
);
207 if (results
== NULL
) {
208 LLOGE("out of memory when malloc scan result");
211 memset(results
, 0, sizeof(luat_wlan_scan_result_t
) * ap_limit
);
212 int len
= luat_wlan_scan_get_result(results
, ap_limit
);
213 for (int i
= 0; i
< len
; i
++)
217 lua_pushstring(L
, (const char *)results
[i
].ssid
);
218 lua_setfield(L
, -2, "ssid");
220 // lua_pushfstring(L, "%02X%02X%02X%02X%02X%02X", results[i].bssid[0],
221 // results[i].bssid[1],
222 // results[i].bssid[2],
223 // results[i].bssid[3],
224 // results[i].bssid[4],
225 // results[i].bssid[5]);
226 lua_pushlstring(L
, (const char *)results
[i
].bssid
, 6);
227 lua_setfield(L
, -2, "bssid");
229 lua_pushinteger(L
, results
[i
].ch
);
230 lua_setfield(L
, -2, "channel");
232 lua_pushinteger(L
, results
[i
].rssi
);
233 lua_setfield(L
, -2, "rssi");
235 lua_seti(L
, -2, i
+ 1);
237 luat_heap_free(results
);
243 @api wlan.smartconfig(mode)
244 @int 配网模式, 默认为esptouch, 若传0则主动停止配网
245 @return bool 启动成功或停止成功, 返回true, 否则返回false
248 local ret, ssid, passwd = sys.waitUntil("SC_RESULT", 180*1000) -- 最多等3分钟
249 log.info("sc", ret, ssid, passwd)
252 static int l_wlan_smartconfig(lua_State
*L
) {
253 int tp
= luaL_optinteger(L
, 1, LUAT_SC_TYPE_ESPTOUCH
);
254 if (tp
== LUAT_SC_TYPE_STOP
) {
255 luat_wlan_smartconfig_stop();
256 lua_pushboolean(L
, 1);
259 int ret
= luat_wlan_smartconfig_start(tp
);
260 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
267 @api wlan.getMac(tp, hexstr)
268 @int 设置何种mac地址,对ESP32系列来说,只能设置STA的地址,即0,默认值也是0
269 @bool 是否转HEX字符, 默认是true,即输出hex字符串
270 @return string MAC地址,十六进制字符串形式 "AABBCCDDEEFF" 或原始数据
272 log.info("wlan mac", wlan.getMac())
274 static int l_wlan_get_mac(lua_State
* L
){
276 char tmpbuff
[16] = {0};
277 luat_wlan_get_mac(luaL_optinteger(L
, 1, 0), tmp
);
278 if (lua_isboolean(L
, 2) && !lua_toboolean(L
, 2)) {
279 lua_pushlstring(L
, tmp
, 6);
282 sprintf_(tmpbuff
, "%02X%02X%02X%02X%02X%02X", tmp
[0], tmp
[1], tmp
[2], tmp
[3], tmp
[4], tmp
[5]);
283 lua_pushstring(L
, tmpbuff
);
291 @api wlan.setMac(tp, mac)
292 @int 设置何种mac地址,对ESP32系列来说,只能设置STA的地址,即0
293 @string 待设置的MAC地址,长度6字节
294 @return bool 成功返回true,否则返回false
296 -- 设置MAC地址, 2023-03-01之后编译的固件可用
297 local mac = string.fromHex("F01122334455")
300 -- 部分模块支持恢复默认MAC, 例如esp32系列
301 -- 在2023-11-01 之后编译的固件可用
302 local mac = string.fromHex("000000000000")
305 static int l_wlan_set_mac(lua_State
* L
){
306 // int id = luaL_optinteger(L, 1, 0);
307 const char* mac
= luaL_checkstring(L
, 2);
308 int ret
= luat_wlan_set_mac(luaL_optinteger(L
, 1, 0), mac
);
309 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
315 获取ip,仅STATION或APSTA模式下有意义
317 @return string ip地址,当前仅返回ipv4地址,例如 "192.168.1.25"
319 static int l_wlan_get_ip(lua_State
* L
){
320 char tmpbuff
[16] = {0};
321 luat_wlan_get_ip(luaL_optinteger(L
, 1, 0), tmpbuff
);
322 lua_pushstring(L
, tmpbuff
);
328 @api wlan.createAP(ssid, passwd, gateway, netmask, channel, opts)
331 @string AP的网关地址, 默认192.168.4.1
332 @string AP的网关掩码, 默认255.255.255.0
335 @return bool 成功创建返回true,否则返回false
337 -- 注意, 调用本AP时,若wifi模式为STATION,会自动切换成 APSTA
338 wlan.createAP("luatos1234", "12341234")
339 -- 设置网关IP,掩码, 通道, 2023.7.13 新增, BSP未必支持
340 -- wlan.createAP("luatos1234", "12341234", "192.168.4.1", "255.255.255.0", 6)
342 -- opts更多配置项, 2024.3.5新增
345 hidden = false, -- 是否隐藏SSID, 默认false,不隐藏
346 max_conn = 4 -- 最大客户端数量, 默认4
350 #include "lwip/opt.h"
351 #include "lwip/ip_addr.h"
352 #include "lwip/netif.h"
353 static int l_wlan_ap_start(lua_State
*L
) {
355 size_t password_len
= 0;
356 luat_wlan_apinfo_t apinfo
= {0};
357 const char* ssid
= luaL_checklstring(L
, 1, &ssid_len
);
358 const char* password
= luaL_optlstring(L
, 2, "", &password_len
);
359 const char* gateway
= luaL_optstring(L
, 3, "192.168.4.1");
360 const char* netmask
= luaL_optstring(L
, 4, "255.255.255.0");
361 if (strlen(gateway
) > 7) {
362 to_ipv4(gateway
, apinfo
.gateway
);
364 if (strlen(netmask
) > 7) {
365 to_ipv4(netmask
, apinfo
.netmask
);
368 apinfo
.channel
= (uint8_t)luaL_optinteger(L
, 5, 6);
370 LLOGE("ssid MUST NOT EMTRY");
374 LLOGE("ssid too long [%s]", ssid
);
377 if (password_len
> 63) {
378 LLOGE("password too long [%s]", password
);
382 if (lua_istable(L
, 6)) {
383 lua_getfield(L
, 6, "hidden");
384 apinfo
.hidden
= lua_toboolean(L
, -1);
386 lua_getfield(L
, 6, "max_conn");
387 apinfo
.max_conn
= lua_tonumber(L
, -1);
391 memcpy(apinfo
.ssid
, ssid
, ssid_len
);
392 memcpy(apinfo
.password
, password
, password_len
);
394 int ret
= luat_wlan_ap_start(&apinfo
);
396 LLOGD("apstart ret %d", ret
);
397 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
404 @return bool 成功创建返回true,否则返回false
408 static int l_wlan_ap_stop(lua_State
*L
) {
409 int ret
= luat_wlan_ap_stop();
411 LLOGD("apstop ret %d", ret
);
412 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
417 获取信息,如AP的bssid,信号强度, STA联网后可获取
419 @return table 详情,键值对形式
422 log.info("wlan", "info", json.encode(wlan.getInfo()))
432 static int l_wlan_get_info(lua_State
*L
) {
434 char buff2
[32] = {0};
437 luat_wlan_get_ap_bssid(buff
);
438 sprintf_(buff2
, "%02X%02X%02X%02X%02X%02X", buff
[0], buff
[1], buff
[2], buff
[3], buff
[4], buff
[5]);
439 lua_pushstring(L
, buff2
);
440 lua_setfield(L
, -2, "bssid");
443 luat_wlan_get_ap_gateway(buff
);
444 lua_pushstring(L
, buff
);
445 lua_setfield(L
, -2, "gw");
447 lua_pushinteger(L
, luat_wlan_get_ap_rssi());
448 lua_setfield(L
, -2, "rssi");
455 @api wlan.powerSave(mode)
456 @int 省电模式,可选, 传入就是设置, 例如wlan.PS_NONE
457 @return int 当前省电模式/设置后的省电模式
459 -- 请查阅常量表 PS_NONE/PS_MIN_MODEM/PS_MAX_MODEM
460 log.info("wlan", "PS", wlan.powerSave(wlan.PS_NONE))
461 -- 本API于 2023.03.31 新增
463 static int l_wlan_powerSave(lua_State
*L
) {
465 if (lua_isinteger(L
, 1)) {
466 mode
= luaL_checkinteger(L
, 1);
467 luat_wlan_set_ps(mode
);
469 mode
= luat_wlan_get_ps();
470 lua_pushinteger(L
, mode
);
476 @api wlan.hostname(new_name)
477 @string 新的hostname,可选, 传入就是设置
478 @return string 当前的hostname或者设置后的hostname
480 -- 本API于 2023.07.23 新增
481 -- 本函数应该在wlan.init之前设置好, 最晚应早于wlan.connect
482 -- hostname的默认值是 "LUATOS_" + 设备的MAC值
483 -- 例如: LUATOS_0022EECC2399
485 wlan.hostname("我的wifi物联网设备")
487 static int l_wlan_get_set_hostname(lua_State
*L
) {
488 if (lua_isstring(L
, 1)) {
490 const char* hostname
= luaL_checklstring(L
, 1, &len
);
493 LLOGE("hostname is too long");
496 luat_wlan_set_hostname(0, hostname
);
499 const char* tmp
= luat_wlan_get_hostname(0);
500 lua_pushstring(L
, tmp
);
506 @api wlan.staIp(dhcp_enable, ip, netmask, gateway)
507 @bool 是否启用DHCP,默认是true
508 @string 本机IP地址,例如192.168.2.200, 禁用DHCP时必填
509 @string 本机IP掩码,例如255.255.255.0, 禁用DHCP时必填
510 @string 本机IP网关,例如192.168.2.1, 禁用DHCP时必填
511 @return bool 成功返回true,否则返回false
513 -- 本API于 2023.10.06 新增
514 -- 本函数需要在wlan.init之后才允许调用
516 -- 启用DHCP, 默认也是启用DHCP,这里是演示API使用
518 -- 禁用DHCP,自行设置IP/掩码/网关
519 wlan.staIp(false, "192.168.2.200", "255.255.255.0", "192.168.2.1")
521 static int l_wlan_set_sta_ip(lua_State
*L
) {
522 luat_wlan_station_info_t info
= {
525 const char *data
= NULL
;
528 if (lua_isinteger(L
, 1))
529 info
.dhcp_enable
= luaL_optinteger(L
, 1, 1);
530 else if (lua_isboolean(L
, 1))
531 info
.dhcp_enable
= lua_toboolean(L
, 1);
534 data
= luaL_optlstring(L
, 2, "192.168.1.201", &len
);
535 to_ipv4(data
, info
.ipv4_addr
);
538 data
= luaL_optlstring(L
, 3, "255.255.255.0", &len
);
539 to_ipv4(data
, info
.ipv4_netmask
);
542 data
= luaL_optlstring(L
, 4, "192.168.1.1", &len
);
543 to_ipv4(data
, info
.ipv4_gateway
);
545 int ret
= luat_wlan_set_station_ip(&info
);
546 lua_pushboolean(L
, ret
== 0 ? 1 : 0);
550 #include "rotable2.h"
551 static const rotable_Reg_t reg_wlan
[] =
553 { "init", ROREG_FUNC(l_wlan_init
)},
554 { "scan", ROREG_FUNC(l_wlan_scan
)},
555 { "scanResult", ROREG_FUNC(l_wlan_scan_result
)},
556 #ifndef LUAT_USE_WLAN_SCANONLY
557 { "mode", ROREG_FUNC(l_wlan_mode
)},
558 { "setMode", ROREG_FUNC(l_wlan_mode
)},
559 { "ready", ROREG_FUNC(l_wlan_ready
)},
560 { "connect", ROREG_FUNC(l_wlan_connect
)},
561 { "disconnect", ROREG_FUNC(l_wlan_disconnect
)},
564 { "smartconfig", ROREG_FUNC(l_wlan_smartconfig
)},
566 { "getIP", ROREG_FUNC(l_wlan_get_ip
)},
567 { "getInfo", ROREG_FUNC(l_wlan_get_info
)},
568 { "getMac", ROREG_FUNC(l_wlan_get_mac
)},
569 { "setMac", ROREG_FUNC(l_wlan_set_mac
)},
570 { "hostname", ROREG_FUNC(l_wlan_get_set_hostname
)},
572 { "powerSave", ROREG_FUNC(l_wlan_powerSave
)},
574 { "staIp", ROREG_FUNC(l_wlan_set_sta_ip
)},
577 { "createAP", ROREG_FUNC(l_wlan_ap_start
)},
578 { "stopAP", ROREG_FUNC(l_wlan_ap_stop
)},
580 //@const NONE WLAN模式,停用
581 {"NONE", ROREG_INT(LUAT_WLAN_MODE_NULL
)},
582 //@const STATION WLAN模式,STATION模式,主动连AP
583 {"STATION", ROREG_INT(LUAT_WLAN_MODE_STA
)},
584 //@const AP WLAN模式,AP模式,接受STATION连接
585 {"AP", ROREG_INT(LUAT_WLAN_MODE_AP
)},
586 //@const AP WLAN模式,混合模式
587 {"STATIONAP", ROREG_INT(LUAT_WLAN_MODE_APSTA
)},
591 {"STOP", ROREG_INT(LUAT_SC_TYPE_STOP
)},
592 //@const ESPTOUCH esptouch配网, V1
593 {"ESPTOUCH", ROREG_INT(LUAT_SC_TYPE_ESPTOUCH
)},
594 //@const AIRKISS Airkiss配网, 微信常用
595 {"AIRKISS", ROREG_INT(LUAT_SC_TYPE_AIRKISS
)},
596 //@const ESPTOUCH_AIRKISS esptouch和Airkiss混合配网
597 {"ESPTOUCH_AIRKISS", ROREG_INT(LUAT_SC_TYPE_ESPTOUCH_AIRKISS
)},
598 //@const ESPTOUCH_V2 esptouch配网, V2, 未测试
599 {"ESPTOUCH_V2", ROREG_INT(LUAT_SC_TYPE_ESPTOUCH_V2
)},
601 //@const PS_NONE 关闭省电模式
602 {"PS_NONE", ROREG_INT(0)},
603 //@const PS_MIN_MODEM 最小Modem省电模式
604 {"PS_MIN_MODEM", ROREG_INT(1)},
605 //@const PS_MAX_MODEM 最大Modem省电模式
606 {"PS_MAX_MODEM", ROREG_INT(2)},
609 { NULL
, ROREG_INT(0)}
612 LUAMOD_API
int luaopen_wlan( lua_State
*L
) {
613 luat_newlib2(L
, reg_wlan
);