luat_lib_wlan.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. @module wlan
  3. @summary wifi操作
  4. @catalog 外设API
  5. @version 1.0
  6. @date 2022.09.30
  7. @demo wlan
  8. @tag LUAT_USE_WLAN
  9. */
  10. #include "luat_base.h"
  11. #include "luat_wlan.h"
  12. #define LUAT_LOG_TAG "wlan"
  13. #include "luat_log.h"
  14. /*
  15. 初始化
  16. @api wlan.init()
  17. @return bool 成功返回true,否则返回false
  18. */
  19. static int l_wlan_init(lua_State* L){
  20. int ret = luat_wlan_init(NULL);
  21. lua_pushboolean(L, ret == 0 ? 1 : 0);
  22. return 1;
  23. }
  24. /*
  25. 设置wifi模式
  26. @api wlan.setMode(mode)
  27. @int wifi模式
  28. @return bool 成功返回true,否则返回false
  29. @usage
  30. -- 设置为AP模式, 广播ssid, 接收wifi客户端的链接
  31. wlan.setMode(wlan.AP)
  32. -- 设置为STATION模式, 也是初始化后的默认模式
  33. wlan.setMode(wlan.STATION)
  34. -- 混合模式, 做AP又做STATION
  35. wlan.setMode(wlan.APSTA)
  36. */
  37. static int l_wlan_mode(lua_State* L){
  38. int mode = LUAT_WLAN_MODE_STA;
  39. if (lua_isinteger(L, 1)) {
  40. mode = lua_tointeger(L, 1);
  41. }
  42. else if (lua_isinteger(L, 2)) {
  43. mode = lua_tointeger(L, 2);
  44. }
  45. if (mode <= LUAT_WLAN_MODE_NULL || mode >= LUAT_WLAN_MODE_MAX) {
  46. mode = LUAT_WLAN_MODE_STA;
  47. }
  48. // switch (mode)
  49. // {
  50. // case LUAT_WLAN_MODE_NULL:
  51. // LLOGD("wlan mode NULL");
  52. // break;
  53. // case LUAT_WLAN_MODE_STA:
  54. // LLOGD("wlan mode STATION");
  55. // break;
  56. // case LUAT_WLAN_MODE_AP:
  57. // LLOGD("wlan mode AP");
  58. // break;
  59. // case LUAT_WLAN_MODE_APSTA:
  60. // LLOGD("wlan mode AP-STATION");
  61. // break;
  62. // default:
  63. // break;
  64. // }
  65. luat_wlan_config_t conf = {
  66. .mode = mode
  67. };
  68. int ret = luat_wlan_mode(&conf);
  69. lua_pushboolean(L, ret == 0 ? 1 : 0);
  70. return 1;
  71. }
  72. /*
  73. 作为STATION时,是否已经连接上AP,且获取IP成功
  74. @api wlan.ready()
  75. @return bool 已经连接成功返回true,否则返回false
  76. */
  77. static int l_wlan_ready(lua_State* L){
  78. lua_pushboolean(L, luat_wlan_ready());
  79. return 1;
  80. }
  81. /*
  82. 作为STATION时,连接到指定AP
  83. @api wlan.connect(ssid, password)
  84. @string AP的ssid
  85. @string AP的password,可选
  86. @return bool 发起连接成功返回true,否则返回false.注意,不代表连接AP成功!!
  87. @usage
  88. -- 普通模式,带密码
  89. wlan.connect("myap", "12345678")
  90. -- 普通模式,不带密码
  91. wlan.connect("myap")
  92. -- 特殊模式, 重用之前的ssid和密码,本次直接连接
  93. -- 注意, 前提是本次上电后已经传过ssid和或password,否则必失败
  94. wlan.connect()
  95. */
  96. static int l_wlan_connect(lua_State* L){
  97. const char* ssid = luaL_optstring(L, 1, "");
  98. const char* password = luaL_optstring(L, 2, "");
  99. luat_wlan_conninfo_t info = {0};
  100. info.auto_reconnection = 1;
  101. memcpy(info.ssid, ssid, strlen(ssid));
  102. memcpy(info.password, password, strlen(password));
  103. int ret = luat_wlan_connect(&info);
  104. lua_pushboolean(L, ret == 0 ? 1 : 0);
  105. return 1;
  106. }
  107. /*
  108. 作为STATION时,断开AP
  109. @api wlan.disconnect()
  110. */
  111. static int l_wlan_disconnect(lua_State* L){
  112. luat_wlan_disconnect();
  113. return 0;
  114. }
  115. /*
  116. 扫描wifi频段
  117. @api wlan.scan()
  118. @usage
  119. -- 注意, wlan.scan()是异步API,启动扫描后会马上返回
  120. -- wifi扫描成功后, 会有WLAN_SCAN_DONE消息, 读取即可
  121. sys.subscribe("WLAN_SCAN_DONE", function ()
  122. local results = wlan.scanResult()
  123. log.info("scan", "results", #results)
  124. for k,v in pairs(results) do
  125. log.info("scan", v["ssid"], v["rssi"], (v["bssid"]:toHex()))
  126. end
  127. end)
  128. -- 下面演示的是初始化wifi后定时扫描,请按实际业务需求修改
  129. sys.taskInit(function()
  130. sys.wait(1000)
  131. wlan.init()
  132. while 1 do
  133. wlan.scan()
  134. sys.wait(15000)
  135. end
  136. end)
  137. */
  138. static int l_wlan_scan(lua_State* L){
  139. luat_wlan_scan();
  140. return 0;
  141. }
  142. /*
  143. 获取wifi扫描结果
  144. @api wlan.scanResult()
  145. @return table 扫描结果
  146. @usage
  147. -- 用法请查阅 wlan.scan() 函数
  148. */
  149. static int l_wlan_scan_result(lua_State* L) {
  150. int ap_limit = luaL_optinteger(L, 1, 20);
  151. if (ap_limit > 32)
  152. ap_limit = 32;
  153. else if (ap_limit < 8)
  154. ap_limit = 8;
  155. lua_newtable(L);
  156. luat_wlan_scan_result_t *results = luat_heap_malloc(sizeof(luat_wlan_scan_result_t) * ap_limit);
  157. if (results == NULL) {
  158. LLOGE("out of memory when malloc scan result");
  159. return 1;
  160. }
  161. memset(results, 0, sizeof(luat_wlan_scan_result_t) * ap_limit);
  162. int len = luat_wlan_scan_get_result(results, ap_limit);
  163. for (size_t i = 0; i < len; i++)
  164. {
  165. lua_newtable(L);
  166. lua_pushstring(L, (const char *)results[i].ssid);
  167. lua_setfield(L, -2, "ssid");
  168. // lua_pushfstring(L, "%02X%02X%02X%02X%02X%02X", results[i].bssid[0],
  169. // results[i].bssid[1],
  170. // results[i].bssid[2],
  171. // results[i].bssid[3],
  172. // results[i].bssid[4],
  173. // results[i].bssid[5]);
  174. lua_pushlstring(L, (const char *)results[i].bssid, 6);
  175. lua_setfield(L, -2, "bssid");
  176. lua_pushinteger(L, results[i].ch);
  177. lua_setfield(L, -2, "channel");
  178. lua_pushinteger(L, results[i].rssi);
  179. lua_setfield(L, -2, "rssi");
  180. lua_seti(L, -2, i + 1);
  181. }
  182. luat_heap_free(results);
  183. return 1;
  184. }
  185. /*
  186. 配网
  187. @api wlan.smartconfig(mode)
  188. @int 配网模式, 默认为esptouch, 若传0则主动停止配网
  189. @return bool 启动成功或停止成功, 返回true, 否则返回false
  190. @usage
  191. wlan.smartconfig()
  192. local ret, ssid, passwd = sys.waitUntil("SC_RESULT", 180*1000) -- 最多等3分钟
  193. log.info("sc", ret, ssid, passwd)
  194. -- 详细用法请查看demo
  195. */
  196. static int l_wlan_smartconfig(lua_State *L) {
  197. int tp = luaL_optinteger(L, 1, LUAT_SC_TYPE_ESPTOUCH);
  198. if (tp == LUAT_SC_TYPE_STOP) {
  199. luat_wlan_smartconfig_stop();
  200. lua_pushboolean(L, 1);
  201. }
  202. else {
  203. int ret = luat_wlan_smartconfig_start(tp);
  204. lua_pushboolean(L, ret == 0 ? 1 : 0);
  205. }
  206. return 1;
  207. }
  208. /*
  209. 获取mac
  210. @api wlan.getMode()
  211. @return string MAC地址,十六进制字符串形式 "AABBCCDDEEFF"
  212. */
  213. static int l_wlan_get_mac(lua_State* L){
  214. char tmp[6] = {0};
  215. char tmpbuff[16] = {0};
  216. luat_wlan_get_mac(luaL_optinteger(L, 1, 0), tmp);
  217. sprintf_(tmpbuff, "%02X%02X%02X%02X%02X%02X", tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]);
  218. lua_pushstring(L, tmpbuff);
  219. return 1;
  220. }
  221. /*
  222. 获取ip,仅STATION或APSTA模式下有意义
  223. @api wlan.getIP()
  224. @return string ip地址,当前仅返回ipv4地址,例如 "192.168.1.25"
  225. */
  226. static int l_wlan_get_ip(lua_State* L){
  227. char tmpbuff[16] = {0};
  228. luat_wlan_get_ip(luaL_optinteger(L, 1, 0), tmpbuff);
  229. lua_pushstring(L, tmpbuff);
  230. return 1;
  231. }
  232. /*
  233. 启动AP
  234. @api wlan.createAP(ssid, passwd)
  235. @string AP的SSID,必填
  236. @string AP的密码,可选
  237. @return bool 成功创建返回true,否则返回false
  238. @usage
  239. -- 注意, 调用本AP时,若wifi模式为STATION,会自动切换成 APSTA
  240. wlan.createAP("uiot", "12345678")
  241. */
  242. static int l_wlan_ap_start(lua_State *L) {
  243. size_t ssid_len = 0;
  244. size_t password_len = 0;
  245. luat_wlan_apinfo_t apinfo = {0};
  246. const char* ssid = luaL_checklstring(L, 1, &ssid_len);
  247. const char* password = luaL_optlstring(L, 2, "", &password_len);
  248. if (ssid_len < 1) {
  249. LLOGE("ssid MUST NOT EMTRY");
  250. return 0;
  251. }
  252. if (ssid_len > 32) {
  253. LLOGE("ssid too long [%s]", ssid);
  254. return 0;
  255. }
  256. if (password_len > 63) {
  257. LLOGE("password too long [%s]", password);
  258. return 0;
  259. }
  260. memcpy(apinfo.ssid, ssid, ssid_len);
  261. memcpy(apinfo.password, password, password_len);
  262. int ret = luat_wlan_ap_start(&apinfo);
  263. LLOGD("apstart ret %d", ret);
  264. lua_pushboolean(L, ret == 0 ? 1 : 0);
  265. return 1;
  266. }
  267. /*
  268. 获取信息,如AP的bssid,信号强度
  269. @api wlan.getInfo()
  270. @return table 详情,键值对形式
  271. @usage
  272. log.info("wlan", "info", json.encode(wlan.getInfo()))
  273. --[[
  274. 典型输出
  275. {
  276. "bssid" : "xxxxxx",
  277. "rssi" : -89,
  278. "gw" : "192.168.1.1"
  279. }
  280. ]]
  281. */
  282. static int l_wlan_get_info(lua_State *L) {
  283. char buff[48] = {0};
  284. char buff2[32] = {0};
  285. lua_newtable(L);
  286. luat_wlan_get_ap_bssid(buff);
  287. sprintf_(buff2, "%02X%02X%02X%02X%02X%02X", buff[0], buff[1], buff[2], buff[3], buff[4], buff[5]);
  288. lua_pushstring(L, buff2);
  289. lua_setfield(L, -2, "bssid");
  290. memset(buff, 0, 48);
  291. luat_wlan_get_ap_gateway(buff);
  292. lua_pushstring(L, buff);
  293. lua_setfield(L, -2, "gw");
  294. lua_pushinteger(L, luat_wlan_get_ap_rssi());
  295. lua_setfield(L, -2, "rssi");
  296. return 1;
  297. }
  298. #include "rotable2.h"
  299. static const rotable_Reg_t reg_wlan[] =
  300. {
  301. { "init", ROREG_FUNC(l_wlan_init)},
  302. { "scan", ROREG_FUNC(l_wlan_scan)},
  303. { "scanResult", ROREG_FUNC(l_wlan_scan_result)},
  304. #ifndef LUAT_USE_WLAN_SCANONLY
  305. { "mode", ROREG_FUNC(l_wlan_mode)},
  306. { "setMode", ROREG_FUNC(l_wlan_mode)},
  307. { "ready", ROREG_FUNC(l_wlan_ready)},
  308. { "connect", ROREG_FUNC(l_wlan_connect)},
  309. { "disconnect", ROREG_FUNC(l_wlan_disconnect)},
  310. // 配网相关
  311. { "smartconfig", ROREG_FUNC(l_wlan_smartconfig)},
  312. { "getMac", ROREG_FUNC(l_wlan_get_mac)},
  313. { "getIP", ROREG_FUNC(l_wlan_get_ip)},
  314. { "getInfo", ROREG_FUNC(l_wlan_get_info)},
  315. // AP相关
  316. { "createAP", ROREG_FUNC(l_wlan_ap_start)},
  317. #endif
  318. // wifi模式
  319. //@const NONE WLAN模式,停用
  320. {"NONE", ROREG_INT(LUAT_WLAN_MODE_NULL)},
  321. //@const STATION WLAN模式,STATION模式,主动连AP
  322. {"STATION", ROREG_INT(LUAT_WLAN_MODE_STA)},
  323. //@const AP WLAN模式,AP模式,接受STATION连接
  324. {"AP", ROREG_INT(LUAT_WLAN_MODE_AP)},
  325. //@const AP WLAN模式,混合模式
  326. {"STATIONAP", ROREG_INT(LUAT_WLAN_MODE_APSTA)},
  327. // 配网模式
  328. //@const STOP 停止配网
  329. {"STOP", ROREG_INT(LUAT_SC_TYPE_STOP)},
  330. //@const ESPTOUCH esptouch配网, V1
  331. {"ESPTOUCH", ROREG_INT(LUAT_SC_TYPE_ESPTOUCH)},
  332. //@const AIRKISS Airkiss配网, 微信常用
  333. {"AIRKISS", ROREG_INT(LUAT_SC_TYPE_AIRKISS)},
  334. //@const ESPTOUCH_AIRKISS esptouch和Airkiss混合配网
  335. {"ESPTOUCH_AIRKISS", ROREG_INT(LUAT_SC_TYPE_ESPTOUCH_AIRKISS)},
  336. //@const ESPTOUCH_V2 esptouch配网, V2, 未测试
  337. {"ESPTOUCH_V2", ROREG_INT(LUAT_SC_TYPE_ESPTOUCH_V2)},
  338. { NULL, ROREG_INT(0)}
  339. };
  340. LUAMOD_API int luaopen_wlan( lua_State *L ) {
  341. luat_newlib2(L, reg_wlan);
  342. return 1;
  343. }