wifi.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785
  1. // Module for interfacing with WIFI
  2. // FIXME: sprintf->snprintf everywhere.
  3. #include "module.h"
  4. #include "lauxlib.h"
  5. #include "platform.h"
  6. #include "c_string.h"
  7. #include "c_stdlib.h"
  8. #include "ctype.h"
  9. #include "c_types.h"
  10. #include "user_interface.h"
  11. #include "wifi_common.h"
  12. #ifdef WIFI_SMART_ENABLE
  13. #include "smart.h"
  14. #include "smartconfig.h"
  15. static int wifi_smart_succeed = LUA_NOREF;
  16. #endif
  17. static uint8 getap_output_format=0;
  18. #define INVALID_MAC_STR "MAC:FF:FF:FF:FF:FF:FF"
  19. #ifdef WIFI_SMART_ENABLE
  20. static void wifi_smart_succeed_cb(sc_status status, void *pdata){
  21. NODE_DBG("wifi_smart_succeed_cb is called.\n");
  22. lua_State* L = lua_getstate();
  23. if (status == SC_STATUS_LINK_OVER)
  24. {
  25. smartconfig_stop();
  26. return;
  27. }
  28. #if defined( NODE_SMART_OLDSTYLE )
  29. if (status != SC_STATUS_LINK || !pdata)
  30. return;
  31. if(wifi_smart_succeed == LUA_NOREF)
  32. return;
  33. lua_State* L = (lua_State *)arg;
  34. lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_smart_succeed);
  35. lua_call(L, 0, 0);
  36. #else
  37. if (status != SC_STATUS_LINK || !pdata)
  38. return;
  39. struct station_config *sta_conf = pdata;
  40. wifi_station_set_config(sta_conf);
  41. wifi_station_disconnect();
  42. wifi_station_connect();
  43. if(wifi_smart_succeed != LUA_NOREF)
  44. {
  45. lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_smart_succeed);
  46. lua_pushstring(L, sta_conf->ssid);
  47. lua_pushstring(L, sta_conf->password);
  48. lua_call(L, 2, 0);
  49. unregister_lua_cb(L, &wifi_smart_succeed);
  50. }
  51. #endif // defined( NODE_SMART_OLDSTYLE )
  52. }
  53. #endif // WIFI_SMART_ENABLE
  54. static int wifi_scan_succeed = LUA_NOREF;
  55. // callback for wifi_station_listap
  56. static void wifi_scan_done(void *arg, STATUS status)
  57. {
  58. lua_State* L = lua_getstate();
  59. uint8 ssid[33];
  60. char temp[sizeof("11:22:33:44:55:66")];
  61. if(wifi_scan_succeed == LUA_NOREF)
  62. return;
  63. if(arg == NULL)
  64. return;
  65. lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_scan_succeed);
  66. if (status == OK)
  67. {
  68. struct bss_info *bss_link = (struct bss_info *)arg;
  69. lua_newtable( L );
  70. while (bss_link != NULL)
  71. {
  72. c_memset(ssid, 0, 33);
  73. if (c_strlen(bss_link->ssid) <= 32)
  74. {
  75. c_memcpy(ssid, bss_link->ssid, c_strlen(bss_link->ssid));
  76. }
  77. else
  78. {
  79. c_memcpy(ssid, bss_link->ssid, 32);
  80. }
  81. if(getap_output_format==1) //use new format(BSSID : SSID, RSSI, Authmode, Channel)
  82. {
  83. c_sprintf(temp,MACSTR, MAC2STR(bss_link->bssid));
  84. wifi_add_sprintf_field(L, temp, "%s,%d,%d,%d",
  85. ssid, bss_link->rssi, bss_link->authmode, bss_link->channel);
  86. NODE_DBG(MACSTR" : %s\n",MAC2STR(bss_link->bssid) , temp);//00 00 00 00 00 00
  87. }
  88. else //use old format(SSID : Authmode, RSSI, BSSID, Channel)
  89. {
  90. wifi_add_sprintf_field(L, ssid, "%d,%d,"MACSTR",%d",
  91. bss_link->authmode, bss_link->rssi, MAC2STR(bss_link->bssid),bss_link->channel);
  92. NODE_DBG("%s : %s\n", ssid, temp);
  93. }
  94. bss_link = bss_link->next.stqe_next;
  95. }
  96. }
  97. else
  98. {
  99. lua_newtable( L );
  100. }
  101. lua_call(L, 1, 0);
  102. unregister_lua_cb(L, &wifi_scan_succeed);
  103. }
  104. #ifdef WIFI_SMART_ENABLE
  105. // Lua: smart(channel, function succeed_cb)
  106. // Lua: smart(type, function succeed_cb)
  107. static int wifi_start_smart( lua_State* L )
  108. {
  109. #if defined( NODE_SMART_OLDSTYLE )
  110. unsigned channel;
  111. int stack = 1;
  112. if ( lua_isnumber(L, stack) )
  113. {
  114. channel = lua_tointeger(L, stack);
  115. stack++;
  116. }
  117. else
  118. {
  119. channel = 6;
  120. }
  121. // luaL_checkanyfunction(L, stack);
  122. if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION)
  123. {
  124. lua_pushvalue(L, stack); // copy argument (func) to the top of stack
  125. if(wifi_smart_succeed != LUA_NOREF)
  126. luaL_unref(L, LUA_REGISTRYINDEX, wifi_smart_succeed);
  127. wifi_smart_succeed = luaL_ref(L, LUA_REGISTRYINDEX);
  128. }
  129. if ( channel > 14 || channel < 1 )
  130. return luaL_error( L, "wrong arg range" );
  131. if(wifi_smart_succeed == LUA_NOREF){
  132. smart_begin(channel, NULL, NULL);
  133. }
  134. else
  135. {
  136. smart_begin(channel, (smart_succeed )wifi_smart_succeed_cb, L);
  137. }
  138. #else
  139. if(wifi_get_opmode() != STATION_MODE)
  140. {
  141. return luaL_error( L, "Smart link only in STATION mode" );
  142. }
  143. uint8_t smart_type = 0;
  144. int stack = 1;
  145. if ( lua_isnumber(L, stack) )
  146. {
  147. smart_type = lua_tointeger(L, stack);
  148. stack++;
  149. }
  150. if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION)
  151. {
  152. lua_pushvalue(L, stack); // copy argument (func) to the top of stack
  153. register_lua_cb(L, &wifi_smart_succeed);
  154. }
  155. if ( smart_type > 1 )
  156. return luaL_error( L, "wrong arg range" );
  157. smartconfig_set_type(smart_type);
  158. smartconfig_start(wifi_smart_succeed_cb);
  159. #endif // defined( NODE_SMART_OLDSTYLE )
  160. return 0;
  161. }
  162. // Lua: exit_smart()
  163. static int wifi_exit_smart( lua_State* L )
  164. {
  165. #if defined( NODE_SMART_OLDSTYLE )
  166. smart_end();
  167. #else
  168. smartconfig_stop();
  169. #endif // defined( NODE_SMART_OLDSTYLE )
  170. unregister_lua_cb(L, &wifi_smart_succeed);
  171. return 0;
  172. }
  173. #endif // WIFI_SMART_ENABLE
  174. // Lua: wifi.setmode(mode, save_to_flash)
  175. static int wifi_setmode( lua_State* L )
  176. {
  177. unsigned mode;
  178. bool save_to_flash=true;
  179. mode = luaL_checkinteger( L, 1 );
  180. luaL_argcheck(L, mode == STATION_MODE || mode == SOFTAP_MODE || mode == STATIONAP_MODE || mode == NULL_MODE, 1, "Invalid mode");
  181. if(!lua_isnoneornil(L, 2))
  182. {
  183. if(!lua_isboolean(L, 2))
  184. {
  185. luaL_typerror(L, 2, lua_typename(L, LUA_TBOOLEAN));
  186. }
  187. save_to_flash=lua_toboolean(L, 2);
  188. }
  189. if(save_to_flash)
  190. {
  191. wifi_set_opmode( (uint8_t)mode);
  192. }
  193. else
  194. {
  195. wifi_set_opmode_current( (uint8_t)mode);
  196. }
  197. mode = (unsigned)wifi_get_opmode();
  198. lua_pushinteger( L, mode );
  199. return 1;
  200. }
  201. // Lua: wifi.getmode()
  202. static int wifi_getmode( lua_State* L )
  203. {
  204. unsigned mode;
  205. mode = (unsigned)wifi_get_opmode();
  206. lua_pushinteger( L, mode );
  207. return 1;
  208. }
  209. // Lua: wifi.getdefaultmode()
  210. static int wifi_getdefaultmode( lua_State* L )
  211. {
  212. unsigned mode;
  213. mode = (unsigned)wifi_get_opmode_default();
  214. lua_pushinteger( L, mode );
  215. return 1;
  216. }
  217. // Lua: wifi.getchannel()
  218. static int wifi_getchannel( lua_State* L )
  219. {
  220. unsigned channel;
  221. channel = (unsigned)wifi_get_channel();
  222. lua_pushinteger( L, channel );
  223. return 1;
  224. }
  225. // Lua: wifi.setphymode()
  226. static int wifi_setphymode( lua_State* L )
  227. {
  228. unsigned mode;
  229. mode = luaL_checkinteger( L, 1 );
  230. if ( mode != PHY_MODE_11B && mode != PHY_MODE_11G && mode != PHY_MODE_11N )
  231. return luaL_error( L, "wrong arg type" );
  232. wifi_set_phy_mode( (uint8_t)mode);
  233. mode = (unsigned)wifi_get_phy_mode();
  234. lua_pushinteger( L, mode );
  235. return 1;
  236. }
  237. // Lua: wifi.getphymode()
  238. static int wifi_getphymode( lua_State* L )
  239. {
  240. unsigned mode;
  241. mode = (unsigned)wifi_get_phy_mode();
  242. lua_pushinteger( L, mode );
  243. return 1;
  244. }
  245. #ifdef PMSLEEP_ENABLE
  246. /* Begin WiFi suspend functions*/
  247. #include "pmSleep.h"
  248. static int wifi_resume_cb_ref = LUA_NOREF; // Holds resume callback reference
  249. static int wifi_suspend_cb_ref = LUA_NOREF; // Holds suspend callback reference
  250. void wifi_pmSleep_suspend_CB(void)
  251. {
  252. PMSLEEP_DBG("\n\tDBG: %s start\n", __func__);
  253. if (wifi_suspend_cb_ref != LUA_NOREF)
  254. {
  255. lua_State* L = lua_getstate(); // Get main Lua thread pointer
  256. lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_suspend_cb_ref); // Push suspend callback onto stack
  257. lua_unref(L, wifi_suspend_cb_ref); // remove suspend callback from LUA_REGISTRY
  258. wifi_suspend_cb_ref = LUA_NOREF; // Update variable since reference is no longer valid
  259. lua_call(L, 0, 0); // Execute suspend callback
  260. }
  261. else
  262. {
  263. PMSLEEP_DBG("\n\tDBG: lua cb unavailable\n");
  264. }
  265. PMSLEEP_DBG("\n\tDBG: %s end\n", __func__);
  266. return;
  267. }
  268. void wifi_pmSleep_resume_CB(void)
  269. {
  270. PMSLEEP_DBG("\n\tDBG: %s start\n", __func__);
  271. // If resume callback was defined
  272. pmSleep_execute_lua_cb(&wifi_resume_cb_ref);
  273. PMSLEEP_DBG("\n\tDBG: %s end\n", __func__);
  274. return;
  275. }
  276. // Lua: wifi.suspend({duration, suspend_cb, resume_cb, preserve_mode})
  277. static int wifi_suspend(lua_State* L)
  278. {
  279. // If no parameters were provided
  280. if (lua_isnone(L, 1))
  281. {
  282. // Return current WiFi suspension state
  283. lua_pushnumber(L, pmSleep_get_state());
  284. return 1; // Return WiFi suspension state
  285. }
  286. pmSleep_INIT_CFG(cfg);
  287. cfg.sleep_mode = MODEM_SLEEP_T;
  288. if(lua_istable(L, 1))
  289. {
  290. pmSleep_parse_table_lua(L, 1, &cfg, &wifi_suspend_cb_ref, &wifi_resume_cb_ref);
  291. }
  292. else
  293. return luaL_argerror(L, 1, "must be table");
  294. cfg.resume_cb_ptr = &wifi_pmSleep_resume_CB;
  295. cfg.suspend_cb_ptr = &wifi_pmSleep_suspend_CB;
  296. pmSleep_suspend(&cfg);
  297. return 0;
  298. }
  299. // Lua: wifi.resume([Resume_CB])
  300. static int wifi_resume(lua_State* L)
  301. {
  302. PMSLEEP_DBG("\n\tDBG: %s start\n", __func__);
  303. uint8 fpm_state = pmSleep_get_state();
  304. // If forced sleep api is not enabled, return error
  305. if (fpm_state == 0)
  306. {
  307. return luaL_error(L, "WIFi not suspended");
  308. }
  309. // If a resume callback was provided
  310. if (lua_isfunction(L, 1))
  311. {
  312. // If there is already a resume callback reference
  313. lua_pushvalue(L, 1); //Push resume callback to the top of the stack
  314. register_lua_cb(L, &wifi_resume_cb_ref);
  315. PMSLEEP_DBG("\n\tDBG: Resume CB registered\n");
  316. }
  317. pmSleep_resume(NULL);
  318. PMSLEEP_DBG("\n\tDBG: %s end\n", __func__);
  319. return 0;
  320. }
  321. /* End WiFi suspend functions*/
  322. #endif
  323. // Lua: wifi.nullmodesleep()
  324. static int wifi_null_mode_auto_sleep(lua_State* L)
  325. {
  326. if (!lua_isnone(L, 1))
  327. {
  328. bool auto_sleep_setting=lua_toboolean(L, 1);
  329. if (auto_sleep_setting!=(bool) get_fpm_auto_sleep_flag())
  330. {
  331. wifi_fpm_auto_sleep_set_in_null_mode((uint8)auto_sleep_setting);
  332. //if esp is already in NULL_MODE, auto sleep setting won't take effect until next wifi_set_opmode(NULL_MODE) call.
  333. if(wifi_get_opmode()==NULL_MODE)
  334. {
  335. wifi_set_opmode_current(NULL_MODE);
  336. }
  337. }
  338. }
  339. lua_pushboolean(L, (bool) get_fpm_auto_sleep_flag());
  340. return 1;
  341. }
  342. // Lua: mac = wifi.xx.getmac()
  343. static int wifi_getmac( lua_State* L, uint8_t mode )
  344. {
  345. char temp[64];
  346. uint8_t mac[6];
  347. wifi_get_macaddr(mode, mac);
  348. c_sprintf(temp, MACSTR, MAC2STR(mac));
  349. lua_pushstring( L, temp );
  350. return 1;
  351. }
  352. // Lua: mac = wifi.xx.setmac()
  353. static int wifi_setmac( lua_State* L, uint8_t mode )
  354. {
  355. uint8_t mac[6];
  356. unsigned len = 0;
  357. const char *macaddr = luaL_checklstring( L, 1, &len );
  358. luaL_argcheck(L, len==17, 1, INVALID_MAC_STR);
  359. ets_str2macaddr(mac, macaddr);
  360. lua_pushboolean(L,wifi_set_macaddr(mode, (uint8 *)mac));
  361. return 1;
  362. }
  363. // Lua: ip = wifi.xx.getip()
  364. static int wifi_getip( lua_State* L, uint8_t mode )
  365. {
  366. struct ip_info pTempIp;
  367. char temp[64];
  368. wifi_get_ip_info(mode, &pTempIp);
  369. if(pTempIp.ip.addr==0){
  370. lua_pushnil(L);
  371. return 1;
  372. }
  373. else
  374. {
  375. c_sprintf(temp, "%d.%d.%d.%d", IP2STR(&pTempIp.ip) );
  376. lua_pushstring( L, temp );
  377. c_sprintf(temp, "%d.%d.%d.%d", IP2STR(&pTempIp.netmask) );
  378. lua_pushstring( L, temp );
  379. c_sprintf(temp, "%d.%d.%d.%d", IP2STR(&pTempIp.gw) );
  380. lua_pushstring( L, temp );
  381. return 3;
  382. }
  383. }
  384. // Lua: broadcast = wifi.xx.getbroadcast()
  385. static int wifi_getbroadcast( lua_State* L, uint8_t mode )
  386. {
  387. struct ip_info pTempIp;
  388. char temp[64];
  389. wifi_get_ip_info(mode, &pTempIp);
  390. if(pTempIp.ip.addr==0){
  391. lua_pushnil(L);
  392. return 1;
  393. }
  394. else
  395. {
  396. struct ip_addr broadcast_address;
  397. uint32 subnet_mask32 = pTempIp.netmask.addr & pTempIp.ip.addr;
  398. uint32 broadcast_address32 = ~pTempIp.netmask.addr | subnet_mask32;
  399. broadcast_address.addr = broadcast_address32;
  400. c_sprintf(temp, "%d.%d.%d.%d", IP2STR(&broadcast_address) );
  401. lua_pushstring( L, temp );
  402. return 1;
  403. }
  404. }
  405. // Used by wifi_setip
  406. static uint32_t parse_key(lua_State* L, const char * key){
  407. lua_getfield(L, 1, key);
  408. if( lua_isstring(L, -1) ) // deal with the ip/netmask/gw string
  409. {
  410. const char *ip = luaL_checkstring( L, -1 );
  411. return ipaddr_addr(ip);
  412. }
  413. lua_pop(L, 1);
  414. return 0;
  415. }
  416. // Lua: ip = wifi.xx.setip()
  417. static int wifi_setip( lua_State* L, uint8_t mode )
  418. {
  419. struct ip_info pTempIp;
  420. wifi_get_ip_info(mode, &pTempIp);
  421. if (!lua_istable(L, 1))
  422. return luaL_error( L, "wrong arg type" );
  423. uint32_t ip = parse_key(L, "ip");
  424. if(ip!=0)
  425. pTempIp.ip.addr = ip;
  426. ip = parse_key(L, "netmask");
  427. if(ip!=0)
  428. pTempIp.netmask.addr = ip;
  429. ip = parse_key(L, "gateway");
  430. if(mode==SOFTAP_IF || ip!=0)
  431. pTempIp.gw.addr = ip;
  432. if(STATION_IF == mode)
  433. {
  434. wifi_station_dhcpc_stop();
  435. lua_pushboolean(L,wifi_set_ip_info(mode, &pTempIp));
  436. }
  437. else
  438. {
  439. wifi_softap_dhcps_stop();
  440. lua_pushboolean(L,wifi_set_ip_info(mode, &pTempIp));
  441. wifi_softap_dhcps_start();
  442. }
  443. return 1;
  444. }
  445. // Lua: wifi.sta.getapinfo
  446. static int wifi_station_get_ap_info4lua( lua_State* L )
  447. {
  448. struct station_config config[5];
  449. char temp[sizeof(config[0].password)+1]; //max password length + '\0'
  450. uint8 number_of_aps = wifi_station_get_ap_info(config);
  451. #if defined(WIFI_DEBUG)
  452. char debug_temp[128];
  453. #endif
  454. lua_newtable(L);
  455. lua_pushnumber(L, number_of_aps);
  456. lua_setfield(L, -2, "qty");
  457. WIFI_DBG("\n\t# of APs stored in flash:%d\n", number_of_aps);
  458. WIFI_DBG(" %-6s %-32s %-64s %-17s\n", "index:", "ssid:", "password:", "bssid:");
  459. for(int i=0;i<number_of_aps;i++)
  460. {
  461. lua_newtable(L);
  462. memset(temp, 0, sizeof(temp));
  463. memcpy(temp, config[i].ssid, sizeof(config[i].ssid));
  464. lua_pushstring(L, temp);
  465. lua_setfield(L, -2, "ssid");
  466. #if defined(WIFI_DEBUG)
  467. c_sprintf(debug_temp, " %-6d %-32s ", i, temp);
  468. #endif
  469. memset(temp, 0, sizeof(temp));
  470. if(strlen(config[i].password) > 0) /* WPA = min 8, WEP = min 5 ASCII characters for a 40-bit key */
  471. {
  472. memcpy(temp, config[i].password, sizeof(config[i].password));
  473. lua_pushstring(L, temp);
  474. lua_setfield(L, -2, "pwd");
  475. }
  476. #if defined(WIFI_DEBUG)
  477. c_sprintf(debug_temp + strlen(debug_temp), "%-64s ", temp);
  478. #endif
  479. memset(temp, 0, sizeof(temp));
  480. if (config[i].bssid_set)
  481. {
  482. c_sprintf(temp, MACSTR, MAC2STR(config[i].bssid));
  483. lua_pushstring(L, temp);
  484. lua_setfield(L, -2, "bssid");
  485. }
  486. #if defined(WIFI_DEBUG)
  487. WIFI_DBG("%s%-17s \n", debug_temp, temp);
  488. #endif
  489. lua_pushnumber(L, i+1); //Add one, so that AP index follows Lua Conventions
  490. lua_insert(L, -2);
  491. lua_settable(L, -3);
  492. }
  493. return 1;
  494. }
  495. // Lua: wifi.setapnumber(number_of_aps_to_save)
  496. static int wifi_station_ap_number_set4lua( lua_State* L )
  497. {
  498. unsigned limit=luaL_checkinteger(L, 1);
  499. luaL_argcheck(L, (limit >= 1 && limit <= 5), 1, "Valid range: 1-5");
  500. lua_pushboolean(L, wifi_station_ap_number_set((uint8)limit));
  501. return 1;
  502. }
  503. // Lua: wifi.setapnumber(number_of_aps_to_save)
  504. static int wifi_station_change_ap( lua_State* L )
  505. {
  506. uint8 ap_index=luaL_checkinteger(L, 1);
  507. luaL_argcheck(L, (ap_index >= 1 && ap_index <= 5), 1, "Valid range: 1-5");
  508. lua_pushboolean(L, wifi_station_ap_change(ap_index-1));
  509. return 1;
  510. }
  511. // Lua: wifi.setapnumber(number_of_aps_to_save)
  512. static int wifi_station_get_ap_index( lua_State* L )
  513. {
  514. lua_pushnumber(L, wifi_station_get_current_ap_id()+1);
  515. return 1;
  516. }
  517. // Lua: wifi.sta.getmac()
  518. static int wifi_station_getmac( lua_State* L ){
  519. return wifi_getmac(L, STATION_IF);
  520. }
  521. // Lua: wifi.sta.setmac()
  522. static int wifi_station_setmac( lua_State* L ){
  523. return wifi_setmac(L, STATION_IF);
  524. }
  525. // Lua: wifi.sta.getip()
  526. static int wifi_station_getip( lua_State* L ){
  527. return wifi_getip(L, STATION_IF);
  528. }
  529. // Lua: wifi.sta.setip()
  530. static int wifi_station_setip( lua_State* L ){
  531. return wifi_setip(L, STATION_IF);
  532. }
  533. // Lua: wifi.sta.getbroadcast()
  534. static int wifi_station_getbroadcast( lua_State* L ){
  535. return wifi_getbroadcast(L, STATION_IF);
  536. }
  537. // Used by wifi_station_getconfig_xxx
  538. static int wifi_station_getconfig( lua_State* L, bool get_flash_cfg)
  539. {
  540. struct station_config sta_conf;
  541. char temp[sizeof(sta_conf.password)+1]; //max password length + '\0'
  542. if(get_flash_cfg)
  543. {
  544. wifi_station_get_config_default(&sta_conf);
  545. }
  546. else
  547. {
  548. wifi_station_get_config(&sta_conf);
  549. }
  550. if(sta_conf.ssid==0)
  551. {
  552. lua_pushnil(L);
  553. return 1;
  554. }
  555. else
  556. {
  557. if(lua_isboolean(L, 1) && lua_toboolean(L, 1)==true)
  558. {
  559. lua_newtable(L);
  560. memset(temp, 0, sizeof(temp));
  561. memcpy(temp, sta_conf.ssid, sizeof(sta_conf.ssid));
  562. lua_pushstring(L, temp);
  563. lua_setfield(L, -2, "ssid");
  564. if(strlen(sta_conf.password) > 0) /* WPA = min 8, WEP = min 5 ASCII characters for a 40-bit key */
  565. {
  566. memset(temp, 0, sizeof(temp));
  567. memcpy(temp, sta_conf.password, sizeof(sta_conf.password));
  568. lua_pushstring(L, temp);
  569. lua_setfield(L, -2, "pwd");
  570. }
  571. if(sta_conf.bssid_set==1)
  572. {
  573. memset(temp, 0, sizeof(temp));
  574. c_sprintf(temp, MACSTR, MAC2STR(sta_conf.bssid));
  575. lua_pushstring( L, temp);
  576. lua_setfield(L, -2, "bssid");
  577. }
  578. return 1;
  579. }
  580. else
  581. {
  582. memset(temp, 0, sizeof(temp));
  583. memcpy(temp, sta_conf.ssid, sizeof(sta_conf.ssid));
  584. lua_pushstring(L, temp);
  585. memset(temp, 0, sizeof(temp));
  586. memcpy(temp, sta_conf.password, sizeof(sta_conf.password));
  587. lua_pushstring(L, temp);
  588. lua_pushinteger( L, sta_conf.bssid_set);
  589. c_sprintf(temp, MACSTR, MAC2STR(sta_conf.bssid));
  590. lua_pushstring( L, temp);
  591. return 4;
  592. }
  593. }
  594. }
  595. // Lua: wifi.sta.getconfig()
  596. static int wifi_station_getconfig_current(lua_State *L)
  597. {
  598. return wifi_station_getconfig(L, false);
  599. }
  600. // Lua: wifi.sta.getdefaultconfig()
  601. static int wifi_station_getconfig_default(lua_State *L)
  602. {
  603. return wifi_station_getconfig(L, true);
  604. }
  605. // Lua: wifi.sta.clearconfig()
  606. static int wifi_station_clear_config ( lua_State* L )
  607. {
  608. struct station_config sta_conf;
  609. bool auto_connect=true;
  610. bool save_to_flash=true;
  611. memset(sta_conf.ssid, 0, sizeof(sta_conf.ssid));
  612. memset(sta_conf.password, 0, sizeof(sta_conf.password));
  613. memset(sta_conf.bssid, 0, sizeof(sta_conf.bssid));
  614. sta_conf.bssid_set=0;
  615. wifi_station_disconnect();
  616. bool config_success;
  617. if(save_to_flash)
  618. {
  619. config_success = wifi_station_set_config(&sta_conf);
  620. }
  621. else
  622. {
  623. config_success = wifi_station_set_config_current(&sta_conf);
  624. }
  625. wifi_station_set_auto_connect((uint8)0);
  626. lua_pushboolean(L, config_success);
  627. return 1;
  628. }
  629. // Lua: wifi.sta.config()
  630. static int wifi_station_config( lua_State* L )
  631. {
  632. struct station_config sta_conf;
  633. bool auto_connect=true;
  634. bool save_to_flash=true;
  635. size_t sl, pl, ml;
  636. memset(sta_conf.ssid, 0, sizeof(sta_conf.ssid));
  637. memset(sta_conf.password, 0, sizeof(sta_conf.password));
  638. memset(sta_conf.bssid, 0, sizeof(sta_conf.bssid));
  639. sta_conf.bssid_set=0;
  640. if(lua_istable(L, 1))
  641. {
  642. lua_getfield(L, 1, "ssid");
  643. if (!lua_isnil(L, -1))
  644. {
  645. if( lua_isstring(L, -1) )
  646. {
  647. const char *ssid = luaL_checklstring( L, -1, &sl );
  648. luaL_argcheck(L, ((sl>=0 && sl<=sizeof(sta_conf.ssid)) ), 1, "ssid: length:0-32"); /* Zero-length SSID is valid as a way to clear config */
  649. memcpy(sta_conf.ssid, ssid, sl);
  650. }
  651. else
  652. {
  653. return luaL_argerror( L, 1, "ssid:not string" );
  654. }
  655. }
  656. else
  657. {
  658. return luaL_argerror( L, 1, "ssid required" );
  659. }
  660. lua_pop(L, 1);
  661. lua_getfield(L, 1, "pwd");
  662. if (!lua_isnil(L, -1))
  663. {
  664. if( lua_isstring(L, -1) )
  665. {
  666. const char *pwd = luaL_checklstring( L, -1, &pl );
  667. luaL_argcheck(L, ((pl>=0 && pl<=sizeof(sta_conf.password)) ), 1, "pwd: length:0-64"); /* WPA = min 8, WEP = min 5 ASCII characters for a 40-bit key */
  668. memcpy(sta_conf.password, pwd, pl);
  669. }
  670. else
  671. {
  672. return luaL_argerror( L, 1, "pwd:not string" );
  673. }
  674. }
  675. lua_pop(L, 1);
  676. lua_getfield(L, 1, "bssid");
  677. if (!lua_isnil(L, -1))
  678. {
  679. if (lua_isstring(L, -1))
  680. {
  681. const char *macaddr = luaL_checklstring( L, -1, &ml );
  682. luaL_argcheck(L, ((ml==sizeof("AA:BB:CC:DD:EE:FF")-1) ), 1, "bssid: FF:FF:FF:FF:FF:FF");
  683. ets_str2macaddr(sta_conf.bssid, macaddr);
  684. sta_conf.bssid_set = 1;
  685. }
  686. else
  687. {
  688. return luaL_argerror(L, 1, "bssid:not string");
  689. }
  690. }
  691. lua_pop(L, 1);
  692. lua_getfield(L, 1, "auto");
  693. if (!lua_isnil(L, -1))
  694. {
  695. if (lua_isboolean(L, -1))
  696. {
  697. auto_connect=lua_toboolean(L, -1);
  698. }
  699. else
  700. {
  701. return luaL_argerror(L, 1, "auto:not boolean");
  702. }
  703. }
  704. lua_pop(L, 1);
  705. lua_getfield(L, 1, "save");
  706. if (!lua_isnil(L, -1))
  707. {
  708. if (lua_isboolean(L, -1))
  709. {
  710. save_to_flash=lua_toboolean(L, -1);
  711. }
  712. else
  713. {
  714. return luaL_argerror(L, 1, "save:not boolean");
  715. }
  716. }
  717. else
  718. {
  719. save_to_flash=false;
  720. }
  721. lua_pop(L, 1);
  722. }
  723. else //to be deprecated
  724. {
  725. platform_print_deprecation_note("Argument style station configuration is replaced by table style station configuration", "in the next version");
  726. const char *ssid = luaL_checklstring( L, 1, &sl );
  727. luaL_argcheck(L, (sl>=0 && sl<sizeof(sta_conf.ssid)), 1, "length:0-32"); /* Zero-length SSID is valid as a way to clear config */
  728. memcpy(sta_conf.ssid, ssid, sl);
  729. const char *password = luaL_checklstring( L, 2, &pl );
  730. luaL_argcheck(L, (pl>=0 && pl<=sizeof(sta_conf.password)), 2, "length:0-64"); /* WPA = min 8, WEP = min 5 ASCII characters for a 40-bit key */
  731. memcpy(sta_conf.password, password, pl);
  732. if(lua_isnumber(L, 3))
  733. {
  734. lua_Integer lint=luaL_checkinteger( L, 3 );
  735. if ( lint != 0 && lint != 1)
  736. return luaL_error( L, "wrong arg type" );
  737. auto_connect=(bool)lint;
  738. }
  739. else if (lua_isstring(L, 3)&& !(lua_isnumber(L, 3)))
  740. {
  741. lua_pushnil(L);
  742. lua_insert(L, 3);
  743. }
  744. else
  745. {
  746. if(lua_isnil(L, 3))
  747. return luaL_error( L, "wrong arg type" );
  748. auto_connect=1;
  749. }
  750. if(lua_isnumber(L, 4))
  751. {
  752. sta_conf.bssid_set = 0;
  753. memset(sta_conf.bssid, 0, sizeof(sta_conf.bssid));
  754. }
  755. else
  756. {
  757. if (lua_isstring(L, 4))
  758. {
  759. const char *macaddr = luaL_checklstring( L, 4, &ml );
  760. luaL_argcheck(L, ml==sizeof("AA:BB:CC:DD:EE:FF")-1, 1, INVALID_MAC_STR);
  761. memset(sta_conf.bssid, 0, sizeof(sta_conf.bssid));
  762. ets_str2macaddr(sta_conf.bssid, macaddr);
  763. sta_conf.bssid_set = 1;
  764. }
  765. else
  766. {
  767. sta_conf.bssid_set = 0;
  768. memset(sta_conf.bssid, 0, sizeof(sta_conf.bssid));
  769. }
  770. }
  771. }
  772. #if defined(WIFI_DEBUG)
  773. char debug_temp[sizeof(sta_conf.password)+1]; //max password length + '\0'
  774. memset(debug_temp, 0, sizeof(debug_temp));
  775. memcpy(debug_temp, sta_conf.ssid, sizeof(sta_conf.ssid));
  776. WIFI_DBG("\n\tsta_conf.ssid=\"%s\" len=%d\n", debug_temp, sl);
  777. memset(debug_temp, 0, sizeof(debug_temp));
  778. memcpy(debug_temp, sta_conf.password, sizeof(sta_conf.password));
  779. WIFI_DBG("\tsta_conf.password=\"%s\" len=%d\n", debug_temp, pl);
  780. WIFI_DBG("\tsta_conf.bssid=\""MACSTR"\"\tbssid_set=%d\n", MAC2STR(sta_conf.bssid), sta_conf.bssid_set);
  781. WIFI_DBG("\tsave_to_flash=%s\n", save_to_flash ? "true":"false");
  782. #endif
  783. wifi_station_disconnect();
  784. bool config_success;
  785. if(save_to_flash)
  786. {
  787. config_success = wifi_station_set_config(&sta_conf);
  788. }
  789. else
  790. {
  791. config_success = wifi_station_set_config_current(&sta_conf);
  792. }
  793. wifi_station_set_auto_connect((uint8)auto_connect);
  794. if(auto_connect)
  795. {
  796. wifi_station_connect();
  797. }
  798. lua_pushboolean(L, config_success);
  799. return 1;
  800. }
  801. // Lua: wifi.sta.connect()
  802. static int wifi_station_connect4lua( lua_State* L )
  803. {
  804. wifi_station_connect();
  805. return 0;
  806. }
  807. // Lua: wifi.sta.disconnect()
  808. static int wifi_station_disconnect4lua( lua_State* L )
  809. {
  810. wifi_station_disconnect();
  811. return 0;
  812. }
  813. // Lua: wifi.sta.auto(true/false)
  814. static int wifi_station_setauto( lua_State* L )
  815. {
  816. unsigned a;
  817. a = luaL_checkinteger( L, 1 );
  818. luaL_argcheck(L, ( a == 0 || a == 1 ), 1, "0 or 1");
  819. wifi_station_set_auto_connect(a);
  820. return 0;
  821. }
  822. // Lua: wifi.sta.listap()
  823. static int wifi_station_listap( lua_State* L )
  824. {
  825. if(wifi_get_opmode() == SOFTAP_MODE)
  826. {
  827. return luaL_error( L, "Can't list ap in SOFTAP mode" );
  828. }
  829. struct scan_config scan_cfg;
  830. getap_output_format=0;
  831. if (lua_type(L, 1)==LUA_TTABLE)
  832. {
  833. char ssid[32];
  834. char bssid[6];
  835. uint8 channel=0;
  836. uint8 show_hidden=0;
  837. size_t len;
  838. lua_getfield(L, 1, "ssid");
  839. if (!lua_isnil(L, -1)) /* found? */
  840. {
  841. if( lua_isstring(L, -1) ) // deal with the ssid string
  842. {
  843. const char *ssidstr = luaL_checklstring( L, -1, &len );
  844. if(len>32)
  845. return luaL_error( L, "ssid:<32" );
  846. c_memset(ssid, 0, 32);
  847. c_memcpy(ssid, ssidstr, len);
  848. scan_cfg.ssid=ssid;
  849. NODE_DBG(scan_cfg.ssid);
  850. NODE_DBG("\n");
  851. }
  852. else
  853. {
  854. return luaL_error( L, "wrong arg type" );
  855. }
  856. }
  857. else
  858. {
  859. scan_cfg.ssid=NULL;
  860. }
  861. lua_getfield(L, 1, "bssid");
  862. if (!lua_isnil(L, -1)) /* found? */
  863. {
  864. if( lua_isstring(L, -1) ) // deal with the ssid string
  865. {
  866. const char *macaddr = luaL_checklstring( L, -1, &len );
  867. luaL_argcheck(L, len==17, 1, INVALID_MAC_STR);
  868. c_memset(bssid, 0, 6);
  869. ets_str2macaddr(bssid, macaddr);
  870. scan_cfg.bssid=bssid;
  871. NODE_DBG(MACSTR, MAC2STR(scan_cfg.bssid));
  872. NODE_DBG("\n");
  873. }
  874. else
  875. {
  876. return luaL_error( L, "wrong arg type" );
  877. }
  878. }
  879. else
  880. {
  881. scan_cfg.bssid=NULL;
  882. }
  883. lua_getfield(L, 1, "channel");
  884. if (!lua_isnil(L, -1)) /* found? */
  885. {
  886. if( lua_isnumber(L, -1) ) // deal with the ssid string
  887. {
  888. channel = luaL_checknumber( L, -1);
  889. if(!(channel>=0 && channel<=13))
  890. return luaL_error( L, "channel: 0 or 1-13" );
  891. scan_cfg.channel=channel;
  892. NODE_DBG("%d\n", scan_cfg.channel);
  893. }
  894. else
  895. {
  896. return luaL_error( L, "wrong arg type" );
  897. }
  898. }
  899. else
  900. {
  901. scan_cfg.channel=0;
  902. }
  903. lua_getfield(L, 1, "show_hidden");
  904. if (!lua_isnil(L, -1)) /* found? */
  905. {
  906. if( lua_isnumber(L, -1) ) // deal with the ssid string
  907. {
  908. show_hidden = luaL_checknumber( L, -1);
  909. if(show_hidden!=0 && show_hidden!=1)
  910. return luaL_error( L, "show_hidden: 0 or 1" );
  911. scan_cfg.show_hidden=show_hidden;
  912. NODE_DBG("%d\n", scan_cfg.show_hidden);
  913. }
  914. else
  915. {
  916. return luaL_error( L, "wrong arg type" );
  917. }
  918. }
  919. else
  920. {
  921. scan_cfg.show_hidden=0;
  922. }
  923. if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION)
  924. {
  925. lua_pushnil(L);
  926. lua_insert(L, 2);
  927. }
  928. lua_pop(L, -4);
  929. }
  930. else if (lua_type(L, 1) == LUA_TNUMBER)
  931. {
  932. lua_pushnil(L);
  933. lua_insert(L, 1);
  934. }
  935. else if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION)
  936. {
  937. lua_pushnil(L);
  938. lua_insert(L, 1);
  939. lua_pushnil(L);
  940. lua_insert(L, 1);
  941. }
  942. else if(lua_isnil(L, 1))
  943. {
  944. if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION)
  945. {
  946. lua_pushnil(L);
  947. lua_insert(L, 2);
  948. }
  949. }
  950. else
  951. {
  952. return luaL_error( L, "wrong arg type" );
  953. }
  954. if (lua_type(L, 2) == LUA_TNUMBER) //this section changes the output format
  955. {
  956. getap_output_format=luaL_checkinteger( L, 2 );
  957. if (getap_output_format != 0 && getap_output_format != 1)
  958. return luaL_error( L, "wrong arg type" );
  959. }
  960. NODE_DBG("Use alternate output format: %d\n", getap_output_format);
  961. if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION)
  962. {
  963. lua_pushvalue(L, 3); // copy argument (func) to the top of stack
  964. register_lua_cb(L, &wifi_scan_succeed);
  965. if (lua_type(L, 1)==LUA_TTABLE)
  966. {
  967. wifi_station_scan(&scan_cfg,wifi_scan_done);
  968. }
  969. else
  970. {
  971. wifi_station_scan(NULL,wifi_scan_done);
  972. }
  973. }
  974. else
  975. {
  976. unregister_lua_cb(L, &wifi_scan_succeed);
  977. }
  978. return 0;
  979. }
  980. // Lua: wifi.sta.gethostname()
  981. static int wifi_sta_gethostname( lua_State* L )
  982. {
  983. char* hostname = wifi_station_get_hostname();
  984. lua_pushstring(L, hostname);
  985. return 1;
  986. }
  987. // Used by wifi_sta_sethostname_lua and wifi_change_default_hostname
  988. static bool wifi_sta_sethostname(const char *hostname, size_t len)
  989. {
  990. //this function follows RFC 952 & RFC 1123 host name standards.
  991. //the hostname must be 32 chars or less and first and last char must be alphanumeric
  992. if (!isalnum(hostname[0]) || !isalnum(hostname[len-1]) || len > 32)
  993. {
  994. return false;
  995. }
  996. for (int i=1; i<len; i++)
  997. {
  998. //characters in the middle of the host name can be alphanumeric or a hyphen(-) only
  999. if (!(isalnum(hostname[i]) || hostname[i]=='-'))
  1000. {
  1001. return false;
  1002. }
  1003. }
  1004. return wifi_station_set_hostname((char*)hostname);
  1005. }
  1006. // Lua: wifi.sta.sethostname()
  1007. static int wifi_sta_sethostname_lua( lua_State* L )
  1008. {
  1009. size_t len;
  1010. const char *hostname = luaL_checklstring(L, 1, &len);
  1011. luaL_argcheck(L, wifi_sta_sethostname(hostname, len), 1, "Invalid hostname");
  1012. return 0;
  1013. }
  1014. // Lua: wifi.sta.sleeptype(type)
  1015. static int wifi_station_sleeptype( lua_State* L )
  1016. {
  1017. unsigned type;
  1018. if ( lua_isnumber(L, 1) )
  1019. {
  1020. type = lua_tointeger(L, 1);
  1021. luaL_argcheck(L, (type == NONE_SLEEP_T || type == LIGHT_SLEEP_T || type == MODEM_SLEEP_T), 1, "range:0-2");
  1022. if(!wifi_set_sleep_type(type)){
  1023. lua_pushnil(L);
  1024. return 1;
  1025. }
  1026. }
  1027. type = wifi_get_sleep_type();
  1028. lua_pushinteger( L, type );
  1029. return 1;
  1030. }
  1031. // Lua: wifi.sta.status()
  1032. static int wifi_station_status( lua_State* L )
  1033. {
  1034. uint8_t status = wifi_station_get_connect_status();
  1035. lua_pushinteger( L, status );
  1036. return 1;
  1037. }
  1038. // Lua: wifi.sta.getrssi()
  1039. static int wifi_station_getrssi( lua_State* L ){
  1040. sint8 rssival=wifi_station_get_rssi();
  1041. NODE_DBG("\n\tRSSI is %d\n", rssival);
  1042. if (rssival<10)
  1043. {
  1044. lua_pushinteger(L, rssival);
  1045. }
  1046. else
  1047. {
  1048. lua_pushnil(L);
  1049. }
  1050. return 1;
  1051. }
  1052. //Lua: wifi.ap.deauth()
  1053. static int wifi_ap_deauth( lua_State* L )
  1054. {
  1055. uint8_t mac[6];
  1056. unsigned len = 0;
  1057. if(lua_isstring(L, 1))
  1058. {
  1059. const char *macaddr = luaL_checklstring( L, 1, &len );
  1060. luaL_argcheck(L, len==17, 1, INVALID_MAC_STR);
  1061. ets_str2macaddr(mac, macaddr);
  1062. }
  1063. else
  1064. {
  1065. c_memset(&mac, 0xFF, sizeof(mac));
  1066. }
  1067. lua_pushboolean(L,wifi_softap_deauth(mac));
  1068. return 1;
  1069. }
  1070. // Lua: wifi.ap.getmac()
  1071. static int wifi_ap_getmac( lua_State* L ){
  1072. return wifi_getmac(L, SOFTAP_IF);
  1073. }
  1074. // Lua: wifi.ap.setmac()
  1075. static int wifi_ap_setmac( lua_State* L ){
  1076. return wifi_setmac(L, SOFTAP_IF);
  1077. }
  1078. // Lua: wifi.ap.getip()
  1079. static int wifi_ap_getip( lua_State* L ){
  1080. return wifi_getip(L, SOFTAP_IF);
  1081. }
  1082. // Lua: wifi.ap.setip()
  1083. static int wifi_ap_setip( lua_State* L ){
  1084. return wifi_setip(L, SOFTAP_IF);
  1085. }
  1086. // Lua: wifi.ap.getbroadcast()
  1087. static int wifi_ap_getbroadcast( lua_State* L ){
  1088. return wifi_getbroadcast(L, SOFTAP_IF);
  1089. }
  1090. // Lua: wifi.ap.getconfig()
  1091. static int wifi_ap_getconfig( lua_State* L, bool get_flash_cfg)
  1092. {
  1093. struct softap_config config;
  1094. char temp[sizeof(config.password)+1]; //max password length + '\0'
  1095. if (get_flash_cfg)
  1096. {
  1097. wifi_softap_get_config_default(&config);
  1098. }
  1099. else
  1100. {
  1101. wifi_softap_get_config(&config);
  1102. }
  1103. if(lua_isboolean(L, 1) && lua_toboolean(L, 1)==true)
  1104. {
  1105. lua_newtable(L);
  1106. memset(temp, 0, sizeof(temp));
  1107. memcpy(temp, config.ssid, sizeof(config.ssid));
  1108. lua_pushstring(L, temp);
  1109. lua_setfield(L, -2, "ssid");
  1110. if(config.authmode!=AUTH_OPEN)
  1111. {
  1112. memset(temp, 0, sizeof(temp));
  1113. memcpy(temp, config.password, sizeof(config.password));
  1114. lua_pushstring(L, temp);
  1115. lua_setfield(L, -2, "pwd");
  1116. }
  1117. lua_pushnumber(L, config.authmode);
  1118. lua_setfield(L, -2, "auth");
  1119. lua_pushnumber(L, config.channel);
  1120. lua_setfield(L, -2, "channel");
  1121. lua_pushboolean(L, (bool)config.ssid_hidden);
  1122. lua_setfield(L, -2, "hidden");
  1123. lua_pushnumber(L, config.max_connection);
  1124. lua_setfield(L, -2, "max");
  1125. lua_pushnumber(L, config.beacon_interval);
  1126. lua_setfield(L, -2, "beacon");
  1127. return 1;
  1128. }
  1129. else
  1130. {
  1131. memset(temp, 0, sizeof(temp));
  1132. memcpy(temp, config.ssid, sizeof(config.ssid));
  1133. lua_pushstring(L, temp);
  1134. if(config.authmode == AUTH_OPEN)
  1135. {
  1136. lua_pushnil(L);
  1137. }
  1138. else
  1139. {
  1140. memset(temp, 0, sizeof(temp));
  1141. memcpy(temp, config.password, sizeof(config.password));
  1142. lua_pushstring(L, temp);
  1143. }
  1144. return 2;
  1145. }
  1146. }
  1147. // Lua: wifi.sta.getconfig()
  1148. static int wifi_ap_getconfig_current(lua_State *L)
  1149. {
  1150. return wifi_ap_getconfig(L, false);
  1151. }
  1152. // Lua: wifi.sta.getdefaultconfig()
  1153. static int wifi_ap_getconfig_default(lua_State *L)
  1154. {
  1155. return wifi_ap_getconfig(L, true);
  1156. }
  1157. // Lua: wifi.ap.config(table)
  1158. static int wifi_ap_config( lua_State* L )
  1159. {
  1160. if (!lua_istable(L, 1))
  1161. {
  1162. return luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE));
  1163. }
  1164. struct softap_config config;
  1165. bool save_to_flash=true;
  1166. size_t sl = 0 , pl = 0;
  1167. lua_Integer lint=0;
  1168. int Ltype_tmp=LUA_TNONE;
  1169. memset(config.ssid, 0, sizeof(config.ssid));
  1170. memset(config.password, 0, sizeof(config.password));
  1171. lua_getfield(L, 1, "ssid");
  1172. if (!lua_isnil(L, -1)) /* found? */
  1173. {
  1174. if( lua_isstring(L, -1) ) // deal with the ssid string
  1175. {
  1176. const char *ssid = luaL_checklstring( L, -1, &sl );
  1177. luaL_argcheck(L, ((sl>=1 && sl<=sizeof(config.ssid)) ), 1, "ssid: length:1-32");
  1178. memcpy(config.ssid, ssid, sl);
  1179. config.ssid_len = sl;
  1180. config.ssid_hidden = 0;
  1181. }
  1182. else
  1183. {
  1184. return luaL_argerror( L, 1, "ssid: not string" );
  1185. }
  1186. }
  1187. else
  1188. {
  1189. return luaL_argerror( L, 1, "ssid: required" );
  1190. }
  1191. lua_pop(L, 1);
  1192. lua_getfield(L, 1, "pwd");
  1193. if (!lua_isnil(L, -1)) /* found? */
  1194. {
  1195. if( lua_isstring(L, -1) ) // deal with the password string
  1196. {
  1197. const char *pwd = luaL_checklstring( L, -1, &pl );
  1198. luaL_argcheck(L, (pl>=8 && pl<=sizeof(config.password)), 1, "pwd: length:0 or 8-64");
  1199. memcpy(config.password, pwd, pl);
  1200. config.authmode = AUTH_WPA_WPA2_PSK;
  1201. }
  1202. else
  1203. {
  1204. return luaL_argerror( L, 1, "pwd: not string" );
  1205. }
  1206. }
  1207. else
  1208. {
  1209. config.authmode = AUTH_OPEN;
  1210. }
  1211. lua_pop(L, 1);
  1212. lua_getfield(L, 1, "auth");
  1213. if (!lua_isnil(L, -1))
  1214. {
  1215. if(lua_isnumber(L, -1))
  1216. {
  1217. lint=luaL_checkinteger(L, -1);
  1218. luaL_argcheck(L, (lint >= 0 && lint < AUTH_MAX), 1, "auth: Range:0-4");
  1219. config.authmode = (uint8_t)luaL_checkinteger(L, -1);
  1220. }
  1221. else
  1222. {
  1223. return luaL_argerror(L, 1, "auth: not number");
  1224. }
  1225. }
  1226. lua_pop(L, 1);
  1227. lua_getfield(L, 1, "channel");
  1228. if (!lua_isnil(L, -1))
  1229. {
  1230. if(lua_isnumber(L, -1))
  1231. {
  1232. lint=luaL_checkinteger(L, -1);
  1233. luaL_argcheck(L, (lint >= 1 && lint <= 13), 1, "channel: Range:1-13");
  1234. config.channel = (uint8_t)lint;
  1235. }
  1236. else
  1237. {
  1238. luaL_argerror(L, 1, "channel: not number");
  1239. }
  1240. }
  1241. else
  1242. {
  1243. config.channel = 6;
  1244. }
  1245. lua_pop(L, 1);
  1246. lua_getfield(L, 1, "hidden");
  1247. if (!lua_isnil(L, -1))
  1248. {
  1249. Ltype_tmp=lua_type(L, -1);
  1250. if(Ltype_tmp==LUA_TNUMBER||Ltype_tmp==LUA_TBOOLEAN)
  1251. {
  1252. if(Ltype_tmp==LUA_TNUMBER)
  1253. {
  1254. lint=luaL_checkinteger(L, -1);
  1255. }
  1256. if(Ltype_tmp==LUA_TBOOLEAN)
  1257. {
  1258. lint=(lua_Number)lua_toboolean(L, -1);
  1259. }
  1260. luaL_argcheck(L, (lint == 0 || lint==1), 1, "hidden: 0 or 1");
  1261. config.ssid_hidden = (uint8_t)lint;
  1262. }
  1263. else
  1264. {
  1265. return luaL_argerror(L, 1, "hidden: not boolean");
  1266. }
  1267. }
  1268. else
  1269. {
  1270. config.ssid_hidden = 0;
  1271. }
  1272. lua_pop(L, 1);
  1273. lua_getfield(L, 1, "max");
  1274. if (!lua_isnil(L, -1))
  1275. {
  1276. if(lua_isnumber(L, -1))
  1277. {
  1278. lint=luaL_checkinteger(L, -1);
  1279. luaL_argcheck(L, (lint >= 1 && lint <= 4), 1, "max: 1-4");
  1280. config.max_connection = (uint8_t)lint;
  1281. }
  1282. else
  1283. {
  1284. return luaL_argerror(L, 1, "max: not number");
  1285. }
  1286. }
  1287. else
  1288. {
  1289. config.max_connection = 4;
  1290. }
  1291. lua_pop(L, 1);
  1292. lua_getfield(L, 1, "beacon");
  1293. if (!lua_isnil(L, -1))
  1294. {
  1295. if(lua_isnumber(L, -1))
  1296. {
  1297. lint=luaL_checkinteger(L, -1);
  1298. luaL_argcheck(L, (lint >= 100 && lint <= 60000), 1, "beacon: 100-60000");
  1299. config.beacon_interval = (uint16_t)lint;
  1300. }
  1301. else
  1302. {
  1303. return luaL_argerror(L, 1, "beacon: not number");
  1304. }
  1305. }
  1306. else
  1307. {
  1308. config.beacon_interval = 100;
  1309. }
  1310. lua_pop(L, 1);
  1311. lua_getfield(L, 1, "save");
  1312. if (!lua_isnil(L, -1))
  1313. {
  1314. if (lua_isboolean(L, -1))
  1315. {
  1316. save_to_flash=lua_toboolean(L, -1);
  1317. }
  1318. else
  1319. {
  1320. return luaL_argerror(L, 1, "save: not boolean");
  1321. }
  1322. }
  1323. lua_pop(L, 1);
  1324. #if defined(WIFI_DEBUG)
  1325. char debug_temp[sizeof(config.password)+1];
  1326. memset(debug_temp, 0, sizeof(debug_temp));
  1327. memcpy(debug_temp, config.ssid, sizeof(config.ssid));
  1328. WIFI_DBG("\n\tconfig.ssid=\"%s\" len=%d\n", debug_temp, sl);
  1329. memset(debug_temp, 0, sizeof(debug_temp));
  1330. memcpy(debug_temp, config.password, sizeof(config.password));
  1331. WIFI_DBG("\tconfig.password=\"%s\" len=%d\n", debug_temp, pl);
  1332. WIFI_DBG("\tconfig.authmode=%d\n", config.authmode);
  1333. WIFI_DBG("\tconfig.channel=%d\n", config.channel);
  1334. WIFI_DBG("\tconfig.ssid_hidden=%d\n", config.ssid_hidden);
  1335. WIFI_DBG("\tconfig.max_connection=%d\n", config.max_connection);
  1336. WIFI_DBG("\tconfig.beacon_interval=%d\n", config.beacon_interval);
  1337. WIFI_DBG("\tsave_to_flash=%s\n", save_to_flash ? "true":"false");
  1338. #endif
  1339. bool config_success;
  1340. if(save_to_flash)
  1341. {
  1342. config_success = wifi_softap_set_config(&config);
  1343. }
  1344. else
  1345. {
  1346. config_success = wifi_softap_set_config_current(&config);
  1347. }
  1348. lua_pushboolean(L, config_success);
  1349. return 1;
  1350. }
  1351. // Lua: table = wifi.ap.getclient()
  1352. static int wifi_ap_listclient( lua_State* L )
  1353. {
  1354. if (wifi_get_opmode() == STATION_MODE)
  1355. {
  1356. return luaL_error( L, "Can't list client in STATION_MODE mode" );
  1357. }
  1358. char temp[64];
  1359. lua_newtable(L);
  1360. struct station_info * station = wifi_softap_get_station_info();
  1361. struct station_info * next_station;
  1362. while (station != NULL)
  1363. {
  1364. c_sprintf(temp, MACSTR, MAC2STR(station->bssid));
  1365. wifi_add_sprintf_field(L, temp, IPSTR, IP2STR(&station->ip));
  1366. next_station = STAILQ_NEXT(station, next);
  1367. c_free(station);
  1368. station = next_station;
  1369. }
  1370. return 1;
  1371. }
  1372. // Lua: ip = wifi.ap.dhcp.config()
  1373. static int wifi_ap_dhcp_config( lua_State* L )
  1374. {
  1375. if (!lua_istable(L, 1))
  1376. return luaL_error( L, "wrong arg type" );
  1377. struct dhcps_lease lease;
  1378. uint32_t ip;
  1379. ip = parse_key(L, "start");
  1380. if (ip == 0)
  1381. return luaL_error( L, "wrong arg type" );
  1382. lease.start_ip.addr = ip;
  1383. NODE_DBG(IPSTR, IP2STR(&lease.start_ip));
  1384. NODE_DBG("\n");
  1385. // use configured max_connection to determine end
  1386. struct softap_config config;
  1387. wifi_softap_get_config(&config);
  1388. lease.end_ip = lease.start_ip;
  1389. ip4_addr4(&lease.end_ip) += config.max_connection - 1;
  1390. char temp[64];
  1391. c_sprintf(temp, IPSTR, IP2STR(&lease.start_ip));
  1392. lua_pushstring(L, temp);
  1393. c_sprintf(temp, IPSTR, IP2STR(&lease.end_ip));
  1394. lua_pushstring(L, temp);
  1395. // note: DHCP max range = 101 from start_ip to end_ip
  1396. wifi_softap_dhcps_stop();
  1397. wifi_softap_set_dhcps_lease(&lease);
  1398. wifi_softap_dhcps_start();
  1399. return 2;
  1400. }
  1401. // Lua: wifi.ap.dhcp.start()
  1402. static int wifi_ap_dhcp_start( lua_State* L )
  1403. {
  1404. lua_pushboolean(L, wifi_softap_dhcps_start());
  1405. return 1;
  1406. }
  1407. // Lua: wifi.ap.dhcp.stop()
  1408. static int wifi_ap_dhcp_stop( lua_State* L )
  1409. {
  1410. lua_pushboolean(L, wifi_softap_dhcps_stop());
  1411. return 1;
  1412. }
  1413. // Module function map
  1414. static const LUA_REG_TYPE wifi_station_map[] = {
  1415. { LSTRKEY( "autoconnect" ), LFUNCVAL( wifi_station_setauto ) },
  1416. { LSTRKEY( "changeap" ), LFUNCVAL( wifi_station_change_ap ) },
  1417. { LSTRKEY( "clearconfig"), LFUNCVAL( wifi_station_clear_config ) },
  1418. { LSTRKEY( "config" ), LFUNCVAL( wifi_station_config ) },
  1419. { LSTRKEY( "connect" ), LFUNCVAL( wifi_station_connect4lua ) },
  1420. { LSTRKEY( "disconnect" ), LFUNCVAL( wifi_station_disconnect4lua ) },
  1421. #if defined(WIFI_STATION_STATUS_MONITOR_ENABLE)
  1422. { LSTRKEY( "eventMonReg" ), LFUNCVAL( wifi_station_event_mon_reg ) }, //defined in wifi_eventmon.c
  1423. { LSTRKEY( "eventMonStart" ), LFUNCVAL( wifi_station_event_mon_start ) }, //defined in wifi_eventmon.c
  1424. { LSTRKEY( "eventMonStop" ), LFUNCVAL( wifi_station_event_mon_stop ) }, //defined in wifi_eventmon.c
  1425. #endif
  1426. { LSTRKEY( "getap" ), LFUNCVAL( wifi_station_listap ) },
  1427. { LSTRKEY( "getapindex" ), LFUNCVAL( wifi_station_get_ap_index ) },
  1428. { LSTRKEY( "getapinfo" ), LFUNCVAL( wifi_station_get_ap_info4lua ) },
  1429. { LSTRKEY( "getbroadcast" ), LFUNCVAL( wifi_station_getbroadcast) },
  1430. { LSTRKEY( "getconfig" ), LFUNCVAL( wifi_station_getconfig_current ) },
  1431. { LSTRKEY( "getdefaultconfig" ), LFUNCVAL( wifi_station_getconfig_default ) },
  1432. { LSTRKEY( "gethostname" ), LFUNCVAL( wifi_sta_gethostname ) },
  1433. { LSTRKEY( "getip" ), LFUNCVAL( wifi_station_getip ) },
  1434. { LSTRKEY( "getmac" ), LFUNCVAL( wifi_station_getmac ) },
  1435. { LSTRKEY( "getrssi" ), LFUNCVAL( wifi_station_getrssi ) },
  1436. { LSTRKEY( "setaplimit" ), LFUNCVAL( wifi_station_ap_number_set4lua ) },
  1437. { LSTRKEY( "sethostname" ), LFUNCVAL( wifi_sta_sethostname_lua ) },
  1438. { LSTRKEY( "setip" ), LFUNCVAL( wifi_station_setip ) },
  1439. { LSTRKEY( "setmac" ), LFUNCVAL( wifi_station_setmac ) },
  1440. { LSTRKEY( "sleeptype" ), LFUNCVAL( wifi_station_sleeptype ) },
  1441. { LSTRKEY( "status" ), LFUNCVAL( wifi_station_status ) },
  1442. { LNILKEY, LNILVAL }
  1443. };
  1444. static const LUA_REG_TYPE wifi_ap_dhcp_map[] = {
  1445. { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_dhcp_config ) },
  1446. { LSTRKEY( "start" ), LFUNCVAL( wifi_ap_dhcp_start ) },
  1447. { LSTRKEY( "stop" ), LFUNCVAL( wifi_ap_dhcp_stop ) },
  1448. { LNILKEY, LNILVAL }
  1449. };
  1450. static const LUA_REG_TYPE wifi_ap_map[] = {
  1451. { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_config ) },
  1452. { LSTRKEY( "deauth" ), LFUNCVAL( wifi_ap_deauth ) },
  1453. { LSTRKEY( "getip" ), LFUNCVAL( wifi_ap_getip ) },
  1454. { LSTRKEY( "setip" ), LFUNCVAL( wifi_ap_setip ) },
  1455. { LSTRKEY( "getbroadcast" ), LFUNCVAL( wifi_ap_getbroadcast) },
  1456. { LSTRKEY( "getmac" ), LFUNCVAL( wifi_ap_getmac ) },
  1457. { LSTRKEY( "setmac" ), LFUNCVAL( wifi_ap_setmac ) },
  1458. { LSTRKEY( "getclient" ), LFUNCVAL( wifi_ap_listclient ) },
  1459. { LSTRKEY( "getconfig" ), LFUNCVAL( wifi_ap_getconfig_current ) },
  1460. { LSTRKEY( "getdefaultconfig" ), LFUNCVAL( wifi_ap_getconfig_default ) },
  1461. { LSTRKEY( "dhcp" ), LROVAL( wifi_ap_dhcp_map ) },
  1462. //{ LSTRKEY( "__metatable" ), LROVAL( wifi_ap_map ) },
  1463. { LNILKEY, LNILVAL }
  1464. };
  1465. static const LUA_REG_TYPE wifi_map[] = {
  1466. { LSTRKEY( "setmode" ), LFUNCVAL( wifi_setmode ) },
  1467. { LSTRKEY( "getmode" ), LFUNCVAL( wifi_getmode ) },
  1468. { LSTRKEY( "getdefaultmode" ), LFUNCVAL( wifi_getdefaultmode ) },
  1469. { LSTRKEY( "getchannel" ), LFUNCVAL( wifi_getchannel ) },
  1470. { LSTRKEY( "setphymode" ), LFUNCVAL( wifi_setphymode ) },
  1471. { LSTRKEY( "getphymode" ), LFUNCVAL( wifi_getphymode ) },
  1472. #ifdef PMSLEEP_ENABLE
  1473. { LSTRKEY( "suspend" ), LFUNCVAL( wifi_suspend ) },
  1474. { LSTRKEY( "resume" ), LFUNCVAL( wifi_resume ) },
  1475. #endif
  1476. { LSTRKEY( "nullmodesleep" ), LFUNCVAL( wifi_null_mode_auto_sleep ) },
  1477. #ifdef WIFI_SMART_ENABLE
  1478. { LSTRKEY( "startsmart" ), LFUNCVAL( wifi_start_smart ) },
  1479. { LSTRKEY( "stopsmart" ), LFUNCVAL( wifi_exit_smart ) },
  1480. #endif
  1481. { LSTRKEY( "sleeptype" ), LFUNCVAL( wifi_station_sleeptype ) },
  1482. { LSTRKEY( "sta" ), LROVAL( wifi_station_map ) },
  1483. { LSTRKEY( "ap" ), LROVAL( wifi_ap_map ) },
  1484. #if defined(WIFI_SDK_EVENT_MONITOR_ENABLE)
  1485. { LSTRKEY( "eventmon" ), LROVAL( wifi_event_monitor_map ) }, //declared in wifi_eventmon.c
  1486. #endif
  1487. { LSTRKEY( "NULLMODE" ), LNUMVAL( NULL_MODE ) },
  1488. { LSTRKEY( "STATION" ), LNUMVAL( STATION_MODE ) },
  1489. { LSTRKEY( "SOFTAP" ), LNUMVAL( SOFTAP_MODE ) },
  1490. { LSTRKEY( "STATIONAP" ), LNUMVAL( STATIONAP_MODE ) },
  1491. { LSTRKEY( "PHYMODE_B" ), LNUMVAL( PHY_MODE_11B ) },
  1492. { LSTRKEY( "PHYMODE_G" ), LNUMVAL( PHY_MODE_11G ) },
  1493. { LSTRKEY( "PHYMODE_N" ), LNUMVAL( PHY_MODE_11N ) },
  1494. { LSTRKEY( "NONE_SLEEP" ), LNUMVAL( NONE_SLEEP_T ) },
  1495. { LSTRKEY( "LIGHT_SLEEP" ), LNUMVAL( LIGHT_SLEEP_T ) },
  1496. { LSTRKEY( "MODEM_SLEEP" ), LNUMVAL( MODEM_SLEEP_T ) },
  1497. { LSTRKEY( "OPEN" ), LNUMVAL( AUTH_OPEN ) },
  1498. //{ LSTRKEY( "WEP" ), LNUMVAL( AUTH_WEP ) },
  1499. { LSTRKEY( "WPA_PSK" ), LNUMVAL( AUTH_WPA_PSK ) },
  1500. { LSTRKEY( "WPA2_PSK" ), LNUMVAL( AUTH_WPA2_PSK ) },
  1501. { LSTRKEY( "WPA_WPA2_PSK" ), LNUMVAL( AUTH_WPA_WPA2_PSK ) },
  1502. { LSTRKEY( "STA_IDLE" ), LNUMVAL( STATION_IDLE ) },
  1503. { LSTRKEY( "STA_CONNECTING" ), LNUMVAL( STATION_CONNECTING ) },
  1504. { LSTRKEY( "STA_WRONGPWD" ), LNUMVAL( STATION_WRONG_PASSWORD ) },
  1505. { LSTRKEY( "STA_APNOTFOUND" ), LNUMVAL( STATION_NO_AP_FOUND ) },
  1506. { LSTRKEY( "STA_FAIL" ), LNUMVAL( STATION_CONNECT_FAIL ) },
  1507. { LSTRKEY( "STA_GOTIP" ), LNUMVAL( STATION_GOT_IP ) },
  1508. { LSTRKEY( "__metatable" ), LROVAL( wifi_map ) },
  1509. { LNILKEY, LNILVAL }
  1510. };
  1511. // Used by user_rf_pre_init(user_main.c)
  1512. void wifi_change_default_host_name(void)
  1513. {
  1514. uint8 opmode_temp=wifi_get_opmode();
  1515. wifi_set_opmode_current(STATION_MODE);
  1516. #ifndef WIFI_STA_HOSTNAME
  1517. char temp[32];
  1518. uint8_t mac[6];
  1519. wifi_get_macaddr(STATION_IF, mac);
  1520. c_sprintf(temp, "NODE-%X%X%X", (mac)[3], (mac)[4], (mac)[5]);
  1521. wifi_sta_sethostname((const char*)temp, strlen(temp));
  1522. #elif defined(WIFI_STA_HOSTNAME) && !defined(WIFI_STA_HOSTNAME_APPEND_MAC)
  1523. if(!wifi_sta_sethostname(WIFI_STA_HOSTNAME, strlen(WIFI_STA_HOSTNAME)))
  1524. {
  1525. char temp[32];
  1526. uint8_t mac[6];
  1527. wifi_get_macaddr(STATION_IF, mac);
  1528. c_sprintf(temp, "NODE-%X%X%X", (mac)[3], (mac)[4], (mac)[5]);
  1529. wifi_sta_sethostname((const char*)temp, strlen(temp));
  1530. }
  1531. #elif defined(WIFI_STA_HOSTNAME) && defined(WIFI_STA_HOSTNAME_APPEND_MAC)
  1532. char temp[32];
  1533. uint8_t mac[6];
  1534. wifi_get_macaddr(STATION_IF, mac);
  1535. c_sprintf(temp, "%s%X%X%X", WIFI_STA_HOSTNAME, (mac)[3], (mac)[4], (mac)[5]);
  1536. if(!wifi_sta_sethostname(temp, strlen(temp)))
  1537. {
  1538. c_sprintf(temp, "NODE-%X%X%X", (mac)[3], (mac)[4], (mac)[5]);
  1539. wifi_sta_sethostname((const char*)temp, strlen(temp));
  1540. }
  1541. #endif
  1542. if(opmode_temp!=wifi_get_opmode())
  1543. {
  1544. wifi_set_opmode_current(opmode_temp);
  1545. }
  1546. }
  1547. int luaopen_wifi( lua_State *L )
  1548. {
  1549. wifi_fpm_auto_sleep_set_in_null_mode(1);
  1550. //if esp is already in NULL_MODE, auto sleep setting won't take effect until next wifi_set_opmode(NULL_MODE) call.
  1551. if(wifi_get_opmode()==NULL_MODE)
  1552. {
  1553. wifi_set_opmode_current(NULL_MODE);
  1554. }
  1555. #if defined(WIFI_SDK_EVENT_MONITOR_ENABLE)
  1556. wifi_eventmon_init();
  1557. #endif
  1558. return 0;
  1559. }
  1560. NODEMCU_MODULE(WIFI, "wifi", wifi_map, luaopen_wifi);