diff --git a/app/include/rom.h b/app/include/rom.h index 409d2bbe..80168fff 100644 --- a/app/include/rom.h +++ b/app/include/rom.h @@ -129,8 +129,6 @@ void ets_delay_us (uint32_t us); int ets_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); -int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3))); - void ets_str2macaddr (uint8_t *dst, const char *str); void ets_timer_disarm (ETSTimer *a); diff --git a/app/include/user_config.h b/app/include/user_config.h index f0ba8a3a..5a865fd3 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -107,6 +107,10 @@ extern void luaL_assertfail(const char *file, int line, const char *message); //#define WIFI_SMART_ENABLE +#define WIFI_STATION_STATUS_MONITOR_ENABLE +#define WIFI_SDK_EVENT_MONITOR_ENABLE +#define WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE + #define STRBUF_DEFAULT_INCREMENT 32 #endif /* __USER_CONFIG_H__ */ diff --git a/app/libc/c_stdio.h b/app/libc/c_stdio.h index 631f5c3a..41391bd7 100644 --- a/app/libc/c_stdio.h +++ b/app/libc/c_stdio.h @@ -63,7 +63,7 @@ extern void output_redirect(const char *str); int c_sprintf(char* s,const char *fmt, ...); #endif -// #define c_vsprintf ets_vsprintf +#define c_vsprintf ets_vsprintf #define c_printf(...) do { \ unsigned char __print_buf[BUFSIZ]; \ c_sprintf(__print_buf, __VA_ARGS__); \ diff --git a/app/modules/wifi.c b/app/modules/wifi.c index 2c3961fa..ddf573dd 100644 --- a/app/modules/wifi.c +++ b/app/modules/wifi.c @@ -10,6 +10,8 @@ #include "c_types.h" #include "user_interface.h" +#include "wifi_common.h" + #ifdef WIFI_SMART_ENABLE #include "smart.h" @@ -20,25 +22,17 @@ static int wifi_smart_succeed = LUA_NOREF; static uint8 getap_output_format=0; +#define INVALID_MAC_STR "MAC:FF:FF:FF:FF:FF:FF" + //wifi.sleep variables #define FPM_SLEEP_MAX_TIME 0xFFFFFFF static bool FLAG_wifi_force_sleep_enabled=0; - -//variables for wifi event monitor -static sint32_t wifi_status_cb_ref[6] = {LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF}; -static os_timer_t wifi_sta_status_timer; -static uint8 prev_wifi_status=0; - - #ifdef WIFI_SMART_ENABLE -#if defined( NODE_SMART_OLDSTYLE ) -#else -static lua_State* smart_L = NULL; -#endif static void wifi_smart_succeed_cb(sc_status status, void *pdata){ NODE_DBG("wifi_smart_succeed_cb is called.\n"); + lua_State* L = lua_getstate(); if (status == SC_STATUS_LINK_OVER) { smartconfig_stop(); @@ -68,14 +62,13 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){ if(wifi_smart_succeed != LUA_NOREF) { - lua_rawgeti(smart_L, LUA_REGISTRYINDEX, wifi_smart_succeed); + lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_smart_succeed); - lua_pushstring(smart_L, sta_conf->ssid); - lua_pushstring(smart_L, sta_conf->password); - lua_call(smart_L, 2, 0); + lua_pushstring(L, sta_conf->ssid); + lua_pushstring(L, sta_conf->password); + lua_call(L, 2, 0); - luaL_unref(smart_L, LUA_REGISTRYINDEX, wifi_smart_succeed); - wifi_smart_succeed = LUA_NOREF; + unregister_lua_cb(L, &wifi_smart_succeed); } #endif // defined( NODE_SMART_OLDSTYLE ) @@ -83,7 +76,6 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){ #endif // WIFI_SMART_ENABLE static int wifi_scan_succeed = LUA_NOREF; -static lua_State* gL = NULL; /** * @brief Wifi ap scan over callback to display. * @param arg: contain the aps information @@ -92,19 +84,20 @@ static lua_State* gL = NULL; */ static void wifi_scan_done(void *arg, STATUS status) { + lua_State* L = lua_getstate(); uint8 ssid[33]; - char temp[128]; + char temp[sizeof("11:22:33:44:55:66")]; if(wifi_scan_succeed == LUA_NOREF) return; if(arg == NULL) return; - lua_rawgeti(gL, LUA_REGISTRYINDEX, wifi_scan_succeed); + lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_scan_succeed); if (status == OK) { struct bss_info *bss_link = (struct bss_info *)arg; - lua_newtable( gL ); + lua_newtable( L ); while (bss_link != NULL) { @@ -119,18 +112,16 @@ static void wifi_scan_done(void *arg, STATUS status) } if(getap_output_format==1) //use new format(BSSID : SSID, RSSI, Authmode, Channel) { - c_sprintf(temp,"%s,%d,%d,%d", ssid, bss_link->rssi, bss_link->authmode, bss_link->channel); - lua_pushstring(gL, temp); - NODE_DBG(MACSTR" : %s\n",MAC2STR(bss_link->bssid) , temp); c_sprintf(temp,MACSTR, MAC2STR(bss_link->bssid)); - lua_setfield( gL, -2, temp); + wifi_add_sprintf_field(L, temp, "%s,%d,%d,%d", + ssid, bss_link->rssi, bss_link->authmode, bss_link->channel); + NODE_DBG(MACSTR" : %s\n",MAC2STR(bss_link->bssid) , temp);//00 00 00 00 00 00 } else//use old format(SSID : Authmode, RSSI, BSSID, Channel) { - c_sprintf(temp,"%d,%d,"MACSTR",%d", bss_link->authmode, bss_link->rssi, MAC2STR(bss_link->bssid),bss_link->channel); - lua_pushstring(gL, temp); - lua_setfield( gL, -2, ssid ); - NODE_DBG("%s : %s\n", ssid, temp); + wifi_add_sprintf_field(L, ssid, "%d,%d,"MACSTR",%d", + bss_link->authmode, bss_link->rssi, MAC2STR(bss_link->bssid),bss_link->channel); + NODE_DBG("%s : %s\n", ssid, temp); } bss_link = bss_link->next.stqe_next; @@ -138,14 +129,10 @@ static void wifi_scan_done(void *arg, STATUS status) } else { - lua_newtable( gL ); - } - lua_call(gL, 1, 0); - if(wifi_scan_succeed != LUA_NOREF) - { - luaL_unref(gL, LUA_REGISTRYINDEX, wifi_scan_succeed); - wifi_scan_succeed = LUA_NOREF; + lua_newtable( L ); } + lua_call(L, 1, 0); + unregister_lua_cb(L, &wifi_scan_succeed); } #ifdef WIFI_SMART_ENABLE @@ -191,7 +178,6 @@ static int wifi_start_smart( lua_State* L ) } uint8_t smart_type = 0; int stack = 1; - smart_L = L; if ( lua_isnumber(L, stack) ) { smart_type = lua_tointeger(L, stack); @@ -201,9 +187,7 @@ static int wifi_start_smart( lua_State* L ) if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION) { lua_pushvalue(L, stack); // copy argument (func) to the top of stack - if(wifi_smart_succeed != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, wifi_smart_succeed); - wifi_smart_succeed = luaL_ref(L, LUA_REGISTRYINDEX); + register_lua_cb(L, &wifi_smart_succeed); } if ( smart_type > 1 ) @@ -226,9 +210,7 @@ static int wifi_exit_smart( lua_State* L ) smartconfig_stop(); #endif // defined( NODE_SMART_OLDSTYLE ) - if(wifi_smart_succeed != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, wifi_smart_succeed); - wifi_smart_succeed = LUA_NOREF; + unregister_lua_cb(L, &wifi_smart_succeed); return 0; } #endif // WIFI_SMART_ENABLE @@ -240,7 +222,7 @@ static int wifi_setmode( lua_State* L ) mode = luaL_checkinteger( L, 1 ); - if ( mode != STATION_MODE && mode != SOFTAP_MODE && mode != STATIONAP_MODE ) + if ( mode != STATION_MODE && mode != SOFTAP_MODE && mode != STATIONAP_MODE && mode != NULL_MODE ) return luaL_error( L, "wrong arg type" ); wifi_set_opmode( (uint8_t)mode); mode = (unsigned)wifi_get_opmode(); @@ -407,9 +389,7 @@ static int wifi_setmac( lua_State* L, uint8_t mode ) uint8_t mac[6]; unsigned len = 0; const char *macaddr = luaL_checklstring( L, 1, &len ); - if(len!=17) - return luaL_error( L, "wrong arg type" ); - + luaL_argcheck(L, len==17, 1, INVALID_MAC_STR); ets_str2macaddr(mac, macaddr); lua_pushboolean(L,wifi_set_macaddr(mode, (uint8 *)mac)); return 1; @@ -632,7 +612,7 @@ static int wifi_station_config( lua_State* L ) if (sl>32 || ssid == NULL) return luaL_error( L, "ssid:<32" ); const char *password = luaL_checklstring( L, 2, &pl ); - if (pl!=0 && (pl<8 || pl>64) || password == NULL) + if ((pl!=0 && (pl<8 || pl>64)) || password == NULL) return luaL_error( L, "pwd:0,8~64" ); if(lua_isnumber(L, 3)) @@ -665,8 +645,7 @@ static int wifi_station_config( lua_State* L ) if (lua_isstring(L, 4)) { const char *macaddr = luaL_checklstring( L, 4, &ml ); - if (ml!=17) - return luaL_error( L, "MAC:FF:FF:FF:FF:FF:FF" ); + luaL_argcheck(L, ml==17, 1, INVALID_MAC_STR); c_memset(sta_conf.bssid, 0, 6); ets_str2macaddr(sta_conf.bssid, macaddr); sta_conf.bssid_set = 1; @@ -692,8 +671,8 @@ static int wifi_station_config( lua_State* L ) NODE_DBG("\n"); - wifi_station_set_config(&sta_conf); wifi_station_disconnect(); + wifi_station_set_config(&sta_conf); if(auto_connect==0) { @@ -729,13 +708,8 @@ static int wifi_station_setauto( lua_State* L ) unsigned a; a = luaL_checkinteger( L, 1 ); - - if ( a != 0 && a != 1 ) - return luaL_error( L, "wrong arg type" ); + luaL_argcheck(L, ( a == 0 || a == 1 ), 1, "0 or 1"); wifi_station_set_auto_connect(a); - if(a){ - // station_check_connect(0); - } return 0; } @@ -781,7 +755,6 @@ static int wifi_station_listap( lua_State* L ) { return luaL_error( L, "Can't list ap in SOFTAP mode" ); } - gL = L; struct scan_config scan_cfg; getap_output_format=0; @@ -817,8 +790,7 @@ static int wifi_station_listap( lua_State* L ) if( lua_isstring(L, -1) ) // deal with the ssid string { const char *macaddr = luaL_checklstring( L, -1, &len ); - if(len!=17) - return luaL_error( L, "bssid: FF:FF:FF:FF:FF:FF" ); + luaL_argcheck(L, len==17, 1, INVALID_MAC_STR); c_memset(bssid, 0, 6); ets_str2macaddr(bssid, macaddr); scan_cfg.bssid=bssid; @@ -908,9 +880,8 @@ static int wifi_station_listap( lua_State* L ) if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION) { lua_pushvalue(L, 3); // copy argument (func) to the top of stack - if(wifi_scan_succeed != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed); - wifi_scan_succeed = luaL_ref(L, LUA_REGISTRYINDEX); + register_lua_cb(L, &wifi_scan_succeed); + if (lua_type(L, 1)==LUA_TTABLE) { wifi_station_scan(&scan_cfg,wifi_scan_done); @@ -922,67 +893,46 @@ static int wifi_station_listap( lua_State* L ) } else { - if(wifi_scan_succeed != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed); - wifi_scan_succeed = LUA_NOREF; + unregister_lua_cb(L, &wifi_scan_succeed); } } // Lua: wifi.sta.gethostname() static int wifi_sta_gethostname( lua_State* L ) { - char* hostname = wifi_station_get_hostname(); - lua_pushstring(L, hostname); + char* hostname = wifi_station_get_hostname(); + lua_pushstring(L, hostname); return 1; } -static uint8 wifi_sta_sethostname(const char *hostname, size_t len) +static bool wifi_sta_sethostname(const char *hostname, size_t len) { - uint8 status; - if(hostname[0]!='-' && hostname[len-1]!='-' && (len >= 1 && len <= 32)) + //this function follows RFC 952 & RFC 1123 host name standards. + //the hostname must be 32 chars or less and first and last char must be alphanumeric + if (!isalnum(hostname[0]) || !isalnum(hostname[len-1]) || len > 32) { - uint8 i=0; - while(hostname[i]) - { - if(!(isalnum(hostname[i])||hostname[i]=='-')) - { - return 2; - } - i++; + return false; + } + + for (int i=1; i 5)) // verify user specified a valid wifi status - { - return luaL_error( L, "valid wifi status:0-5" ); - } - - if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) //check if 2nd item on stack is a function - { - lua_pushvalue(L, 2); //push function to top of stack - if(wifi_status_cb_ref[id] != LUA_NOREF) - { - luaL_unref(L, LUA_REGISTRYINDEX, wifi_status_cb_ref[id]); - } - wifi_status_cb_ref[id] = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushinteger(L, rssival); } else { - if(wifi_status_cb_ref[id] != LUA_NOREF) - { - luaL_unref(L, LUA_REGISTRYINDEX, wifi_status_cb_ref[id]); - wifi_status_cb_ref[id] = LUA_NOREF; - } + lua_pushnil(L); } - return 0; + return 1; } - -//wifi.sta.eventMonStart() -static int wifi_station_event_mon_start(lua_State* L) +//Lua: wifi.ap.deauth() +static int wifi_ap_deauth( lua_State* L ) { - if(wifi_get_opmode() == SOFTAP_MODE) + uint8_t mac[6]; + unsigned len = 0; + if(lua_isstring(L, 1)) { - return luaL_error( L, "Can't monitor station in SOFTAP mode" ); + const char *macaddr = luaL_checklstring( L, 1, &len ); + luaL_argcheck(L, len==17, 1, INVALID_MAC_STR); + ets_str2macaddr(mac, macaddr); } - if (wifi_status_cb_ref[0]==LUA_NOREF && wifi_status_cb_ref[1]==LUA_NOREF && - wifi_status_cb_ref[2]==LUA_NOREF && wifi_status_cb_ref[3]==LUA_NOREF && - wifi_status_cb_ref[4]==LUA_NOREF && wifi_status_cb_ref[5]==LUA_NOREF ) + else { - return luaL_error( L, "No callbacks defined" ); + c_memset(&mac, 0xFF, sizeof(mac)); } - uint32 ms=150; - if(lua_isnumber(L, 1)) - { - ms=luaL_checknumber(L, 1); - } - - os_timer_disarm(&wifi_sta_status_timer); - os_timer_setfn(&wifi_sta_status_timer, (os_timer_func_t *)wifi_status_cb, NULL); - os_timer_arm(&wifi_sta_status_timer, ms, 1); - return 0; + lua_pushboolean(L,wifi_softap_deauth(mac)); + return 1; } // Lua: wifi.ap.getmac() @@ -1264,12 +1153,8 @@ static int wifi_ap_listclient( lua_State* L ) struct station_info * next_station; while (station != NULL) { - c_sprintf(temp, IPSTR, IP2STR(&station->ip)); - lua_pushstring(L, temp); - c_sprintf(temp, MACSTR, MAC2STR(station->bssid)); - lua_setfield(L, -2, temp); - + wifi_add_sprintf_field(L, temp, IPSTR, IP2STR(&station->ip)); next_station = STAILQ_NEXT(station, next); c_free(station); station = next_station; @@ -1344,10 +1229,13 @@ static const LUA_REG_TYPE wifi_station_map[] = { { LSTRKEY( "getap" ), LFUNCVAL( wifi_station_listap ) }, { LSTRKEY( "sethostname" ), LFUNCVAL( wifi_sta_sethostname_lua ) }, { LSTRKEY( "gethostname" ), LFUNCVAL( wifi_sta_gethostname ) }, + { LSTRKEY( "getrssi" ), LFUNCVAL( wifi_station_getrssi ) }, { LSTRKEY( "status" ), LFUNCVAL( wifi_station_status ) }, - { LSTRKEY( "eventMonReg" ), LFUNCVAL( wifi_station_event_mon_reg ) }, - { LSTRKEY( "eventMonStart" ), LFUNCVAL( wifi_station_event_mon_start ) }, - { LSTRKEY( "eventMonStop" ), LFUNCVAL( wifi_station_event_mon_stop ) }, +#if defined(WIFI_STATION_STATUS_MONITOR_ENABLE) + { LSTRKEY( "eventMonReg" ), LFUNCVAL( wifi_station_event_mon_reg ) }, //declared in wifi_eventmon.c + { LSTRKEY( "eventMonStart" ), LFUNCVAL( wifi_station_event_mon_start ) }, //declared in wifi_eventmon.c + { LSTRKEY( "eventMonStop" ), LFUNCVAL( wifi_station_event_mon_stop ) }, //declared in wifi_eventmon.c +#endif { LNILKEY, LNILVAL } }; @@ -1360,6 +1248,7 @@ static const LUA_REG_TYPE wifi_ap_dhcp_map[] = { static const LUA_REG_TYPE wifi_ap_map[] = { { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_config ) }, + { LSTRKEY( "deauth" ), LFUNCVAL( wifi_ap_deauth ) }, { LSTRKEY( "getip" ), LFUNCVAL( wifi_ap_getip ) }, { LSTRKEY( "setip" ), LFUNCVAL( wifi_ap_setip ) }, { LSTRKEY( "getbroadcast" ), LFUNCVAL( wifi_ap_getbroadcast) }, @@ -1387,7 +1276,9 @@ static const LUA_REG_TYPE wifi_map[] = { { LSTRKEY( "sta" ), LROVAL( wifi_station_map ) }, { LSTRKEY( "ap" ), LROVAL( wifi_ap_map ) }, - +#if defined(WIFI_SDK_EVENT_MONITOR_ENABLE) + { LSTRKEY( "eventmon" ), LROVAL( wifi_event_monitor_map ) }, //declared in wifi_eventmon.c +#endif { LSTRKEY( "NULLMODE" ), LNUMVAL( NULL_MODE ) }, { LSTRKEY( "STATION" ), LNUMVAL( STATION_MODE ) }, { LSTRKEY( "SOFTAP" ), LNUMVAL( SOFTAP_MODE ) }, @@ -1418,7 +1309,7 @@ static const LUA_REG_TYPE wifi_map[] = { { LNILKEY, LNILVAL } }; -int luaopen_wifi( lua_State *L ) +static void wifi_change_default_host_name(task_param_t param, uint8 priority) { #ifndef WIFI_STA_HOSTNAME char temp[32]; @@ -1428,9 +1319,7 @@ int luaopen_wifi( lua_State *L ) wifi_sta_sethostname((const char*)temp, strlen(temp)); #elif defined(WIFI_STA_HOSTNAME) && !defined(WIFI_STA_HOSTNAME_APPEND_MAC) - const char* hostname=WIFI_STA_HOSTNAME; - uint8 retval=wifi_sta_sethostname(hostname, strlen(hostname)); - if(retval!=1) + if(!wifi_sta_sethostname(WIFI_STA_HOSTNAME, strlen(WIFI_STA_HOSTNAME))) { char temp[32]; uint8_t mac[6]; @@ -1444,14 +1333,22 @@ int luaopen_wifi( lua_State *L ) uint8_t mac[6]; wifi_get_macaddr(STATION_IF, mac); c_sprintf(temp, "%s%X%X%X", WIFI_STA_HOSTNAME, (mac)[3], (mac)[4], (mac)[5]); - uint8 retval=wifi_sta_sethostname(temp, strlen(temp)); - if(retval!=1) + if(!wifi_sta_sethostname(temp, strlen(temp))) { c_sprintf(temp, "NODE-%X%X%X", (mac)[3], (mac)[4], (mac)[5]); wifi_sta_sethostname((const char*)temp, strlen(temp)); } #endif -return 0; + +} + +int luaopen_wifi( lua_State *L ) +{ + task_post_low(task_get_id(wifi_change_default_host_name), FALSE); +#if defined(WIFI_SDK_EVENT_MONITOR_ENABLE) + wifi_eventmon_init(); +#endif + return 0; } NODEMCU_MODULE(WIFI, "wifi", wifi_map, luaopen_wifi); diff --git a/app/modules/wifi_common.c b/app/modules/wifi_common.c new file mode 100644 index 00000000..cba000eb --- /dev/null +++ b/app/modules/wifi_common.c @@ -0,0 +1,17 @@ +#include "wifi_common.h" + +void wifi_add_int_field(lua_State* L, char* name, lua_Integer integer) +{ + lua_pushinteger(L, integer); + lua_setfield(L, -2, name); +} +void wifi_add_sprintf_field(lua_State* L, char* name, char* string, ...) +{ + char buffer[256]; + va_list arglist; + va_start( arglist, string ); + c_vsprintf( buffer, string, arglist ); + va_end( arglist ); + lua_pushstring(L, buffer); + lua_setfield(L, -2, name); +} diff --git a/app/modules/wifi_common.h b/app/modules/wifi_common.h new file mode 100644 index 00000000..758115fe --- /dev/null +++ b/app/modules/wifi_common.h @@ -0,0 +1,54 @@ +#ifndef APP_MODULES_WIFI_COMMON_H_ +#define APP_MODULES_WIFI_COMMON_H_ + +#include "module.h" +#include "lauxlib.h" +#include "platform.h" + +#include "c_string.h" +#include "c_stdlib.h" +#include "c_types.h" +#include "user_interface.h" +#include "user_config.h" +#include "c_stdio.h" +#include "task/task.h" + +void wifi_add_sprintf_field(lua_State* L, char* name, char* string, ...); +void wifi_add_int_field(lua_State* L, char* name, lua_Integer integer); + +static inline void register_lua_cb(lua_State* L,int* cb_ref) +{ + int ref=luaL_ref(L, LUA_REGISTRYINDEX); + if( *cb_ref != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); + } + *cb_ref = ref; +} + +static inline void unregister_lua_cb(lua_State* L, int* cb_ref) +{ + if(*cb_ref != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); + *cb_ref = LUA_NOREF; + } +} + +#ifdef NODE_DEBUG +#define EVENT_DBG(...) c_printf(__VA_ARGS__) +#else +#define EVENT_DBG(...) //c_printf(__VA_ARGS__) +#endif + +#ifdef WIFI_SDK_EVENT_MONITOR_ENABLE + extern const LUA_REG_TYPE wifi_event_monitor_map[]; + void wifi_eventmon_init(); +#endif +#ifdef WIFI_STATION_STATUS_MONITOR_ENABLE + int wifi_station_event_mon_start(lua_State* L); + int wifi_station_event_mon_reg(lua_State* L); + void wifi_station_event_mon_stop(lua_State* L); +#endif + +#endif /* APP_MODULES_WIFI_COMMON_H_ */ diff --git a/app/modules/wifi_eventmon.c b/app/modules/wifi_eventmon.c new file mode 100644 index 00000000..4b562212 --- /dev/null +++ b/app/modules/wifi_eventmon.c @@ -0,0 +1,367 @@ +// WiFi Event Monitor + +#include "module.h" +#include "lauxlib.h" +#include "platform.h" + +#include "c_string.h" +#include "c_stdlib.h" + +#include "c_types.h" +#include "user_interface.h" +#include "smart.h" +#include "smartconfig.h" +#include "user_config.h" + +#include "wifi_common.h" + +#if defined(LUA_USE_MODULES_WIFI) + +#ifdef WIFI_STATION_STATUS_MONITOR_ENABLE + +//variables for wifi event monitor +static int wifi_station_status_cb_ref[6] = {[0 ... 6-1] = LUA_NOREF}; +static os_timer_t wifi_sta_status_timer; +static uint8 prev_wifi_status=0; + +// wifi.sta.eventMonStop() +void wifi_station_event_mon_stop(lua_State* L) +{ + os_timer_disarm(&wifi_sta_status_timer); + if(lua_isstring(L,1)) + { + int i; + for (i=0; i<6; i++) + { + unregister_lua_cb(L, &wifi_station_status_cb_ref[i]); + } + } + return; +} + +static void wifi_status_cb(int arg) +{ + lua_State* L = lua_getstate(); + if (wifi_get_opmode() == SOFTAP_MODE) + { + os_timer_disarm(&wifi_sta_status_timer); + return; + } + int wifi_status = wifi_station_get_connect_status(); + if (wifi_status != prev_wifi_status) + { + if(wifi_station_status_cb_ref[wifi_status] != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_station_status_cb_ref[wifi_status]); + lua_pushnumber(L, prev_wifi_status); + lua_call(L, 1, 0); + } + } + prev_wifi_status = wifi_status; +} + +// wifi.sta.eventMonReg() +int wifi_station_event_mon_reg(lua_State* L) +{ + uint8 id=(uint8)luaL_checknumber(L, 1); + if ((id > 5)) // verify user specified a valid wifi status + { + return luaL_error( L, "valid wifi status:0-5" ); + } + + if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) //check if 2nd item on stack is a function + { + lua_pushvalue(L, 2); //push function to top of stack + register_lua_cb(L, &wifi_station_status_cb_ref[id]);//pop function from top of the stack, register it in the LUA_REGISTRY, then assign returned lua_ref to wifi_station_status_cb_ref[id] + } + else + { + unregister_lua_cb(L, &wifi_station_status_cb_ref[id]); // unregister user's callback + } + return 0; +} + + +// wifi.sta.eventMonStart() +int wifi_station_event_mon_start(lua_State* L) +{ + if(wifi_get_opmode() == SOFTAP_MODE) //Verify ESP is in either Station mode or StationAP mode + { + return luaL_error( L, "Can't monitor in SOFTAP mode" ); + } + if (wifi_station_status_cb_ref[0] == LUA_NOREF && wifi_station_status_cb_ref[1] == LUA_NOREF && + wifi_station_status_cb_ref[2] == LUA_NOREF && wifi_station_status_cb_ref[3] == LUA_NOREF && + wifi_station_status_cb_ref[4] == LUA_NOREF && wifi_station_status_cb_ref[5] == LUA_NOREF ) + { //verify user has registered callbacks + return luaL_error( L, "No callbacks defined" ); + } + uint32 ms = 150; //set default timer interval + if(lua_isnumber(L, 1)) // check if user has specified a different timer interval + { + ms=luaL_checknumber(L, 1); // retrieve user-defined interval + } + + os_timer_disarm(&wifi_sta_status_timer); + os_timer_setfn(&wifi_sta_status_timer, (os_timer_func_t *)wifi_status_cb, NULL); + os_timer_arm(&wifi_sta_status_timer, ms, 1); + return 0; +} + +#endif + +#ifdef WIFI_SDK_EVENT_MONITOR_ENABLE + +//variables for wifi event monitor +static task_handle_t wifi_event_monitor_task_id; //variable to hold task id for task handler(process_event_queue) + +typedef struct evt_queue{ + System_Event_t *evt; + struct evt_queue * next; +}evt_queue_t; //structure to hold pointers to event info and next item in queue + +static evt_queue_t *wifi_event_queue_head; //pointer to beginning of queue +static evt_queue_t *wifi_event_queue_tail; //pointer to end of queue +static int wifi_event_cb_ref[EVENT_MAX+1] = { [0 ... EVENT_MAX] = LUA_NOREF}; //holds references to registered Lua callbacks + +// wifi.eventmon.register() +static int wifi_event_monitor_register(lua_State* L) +{ + uint8 id = (uint8)luaL_checknumber(L, 1); + if ( id > EVENT_MAX ) //Check if user is trying to register a callback for a valid event. + { + return luaL_error( L, "valid wifi events:0-%d", EVENT_MAX ); + } + else + { + if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) //check if 2nd item on stack is a function + { + lua_pushvalue(L, 2); // copy argument (func) to the top of stack + register_lua_cb(L, &wifi_event_cb_ref[id]); //pop function from top of the stack, register it in the LUA_REGISTRY, then assign lua_ref to wifi_event_cb_ref[id] + } + else // unregister user's callback + { + unregister_lua_cb(L, &wifi_event_cb_ref[id]); + } + return 0; + } +} + +static void wifi_event_monitor_handle_event_cb(System_Event_t *evt) +{ + EVENT_DBG("\n\twifi_event_monitor_handle_event_cb is called\n"); + + if((wifi_event_cb_ref[evt->event] != LUA_NOREF) || ((wifi_event_cb_ref[EVENT_MAX] != LUA_NOREF) && + !(evt->event == EVENT_STAMODE_CONNECTED || evt->event == EVENT_STAMODE_DISCONNECTED || + evt->event == EVENT_STAMODE_AUTHMODE_CHANGE||evt->event==EVENT_STAMODE_GOT_IP || + evt->event == EVENT_STAMODE_DHCP_TIMEOUT||evt->event==EVENT_SOFTAPMODE_STACONNECTED || + evt->event == EVENT_SOFTAPMODE_STADISCONNECTED||evt->event==EVENT_SOFTAPMODE_PROBEREQRECVED))) + { + evt_queue_t *temp = (evt_queue_t*)c_malloc(sizeof(evt_queue_t)); //allocate memory for new queue item + temp->evt = (System_Event_t*)c_malloc(sizeof(System_Event_t)); //allocate memory to hold event structure + if(!temp || !temp->evt) + { + luaL_error(lua_getstate(), "wifi.eventmon malloc: out of memory"); + return; + } + c_memcpy(temp->evt, evt, sizeof(System_Event_t)); //copy event data to new struct + + if(wifi_event_queue_head == NULL && wifi_event_queue_tail == NULL)// if queue is empty add item to queue + { + wifi_event_queue_head = wifi_event_queue_tail = temp; + EVENT_DBG("\n\tqueue empty, adding event and posting task\n"); + task_post_low(wifi_event_monitor_task_id, false); + } + else //if queue is not empty append item to end of queue + { + wifi_event_queue_tail->next=temp; + wifi_event_queue_tail=temp; + EVENT_DBG("\n\tqueue not empty, appending queue\n"); + } + } +} + + +static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 priority) +{ + lua_State* L = lua_getstate(); + evt_queue_t *temp = wifi_event_queue_head; //copy event_queue_head pointer to temporary pointer + System_Event_t *evt = temp->evt; //copy event data pointer to temporary pointer + + EVENT_DBG("\t\tevent %u\n", evt->event); + + if(wifi_event_cb_ref[evt->event] != LUA_NOREF) // check if user has registered a callback + { + lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_event_cb_ref[evt->event]); //get user's callback + } + else if((wifi_event_cb_ref[EVENT_MAX]!=LUA_NOREF) && + !(evt->event==EVENT_STAMODE_CONNECTED||evt->event==EVENT_STAMODE_DISCONNECTED|| + evt->event==EVENT_STAMODE_AUTHMODE_CHANGE||evt->event==EVENT_STAMODE_GOT_IP|| + evt->event==EVENT_STAMODE_DHCP_TIMEOUT||evt->event==EVENT_SOFTAPMODE_STACONNECTED|| + evt->event==EVENT_SOFTAPMODE_STADISCONNECTED||evt->event==EVENT_SOFTAPMODE_PROBEREQRECVED)) + { //if user has registered an EVENT_MAX(default) callback and event is not implemented... + lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_event_cb_ref[EVENT_MAX]); //get user's callback + } + + lua_newtable( L ); + + switch (evt->event) + { + case EVENT_STAMODE_CONNECTED: + EVENT_DBG("\n\tSTAMODE_CONNECTED\n"); + wifi_add_sprintf_field(L, "SSID", (char*)evt->event_info.connected.ssid); + wifi_add_sprintf_field(L, "BSSID", MACSTR, MAC2STR(evt->event_info.connected.bssid)); + wifi_add_int_field(L, "channel", evt->event_info.connected.channel); + EVENT_DBG("\tConnected to SSID %s, Channel %d\n", + evt->event_info.connected.ssid, + evt->event_info.connected.channel); + break; + + case EVENT_STAMODE_DISCONNECTED: + EVENT_DBG("\n\tSTAMODE_DISCONNECTED\n"); + wifi_add_sprintf_field(L, "SSID", (char*)evt->event_info.disconnected.ssid); + wifi_add_int_field(L, "reason", evt->event_info.disconnected.reason); + wifi_add_sprintf_field(L, "BSSID", MACSTR, MAC2STR(evt->event_info.disconnected.bssid)); + EVENT_DBG("\tDisconnect from SSID %s, reason %d\n", + evt->event_info.disconnected.ssid, + evt->event_info.disconnected.reason); + break; + + case EVENT_STAMODE_AUTHMODE_CHANGE: + EVENT_DBG("\n\tSTAMODE_AUTHMODE_CHANGE\n"); + wifi_add_int_field(L, "old_auth_mode", evt->event_info.auth_change.old_mode); + wifi_add_int_field(L, "new_auth_mode", evt->event_info.auth_change.new_mode); + EVENT_DBG("\tAuthmode: %u -> %u\n", + evt->event_info.auth_change.old_mode, + evt->event_info.auth_change.new_mode); + break; + + case EVENT_STAMODE_GOT_IP: + EVENT_DBG("\n\tGOT_IP\n"); + wifi_add_sprintf_field(L, "IP", IPSTR, IP2STR(&evt->event_info.got_ip.ip)); + wifi_add_sprintf_field(L, "netmask", IPSTR, IP2STR(&evt->event_info.got_ip.mask)); + wifi_add_sprintf_field(L, "gateway", IPSTR, IP2STR(&evt->event_info.got_ip.gw)); + EVENT_DBG("\tIP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "\n", + IP2STR(&evt->event_info.got_ip.ip), + IP2STR(&evt->event_info.got_ip.mask), + IP2STR(&evt->event_info.got_ip.gw)); + break; + + case EVENT_STAMODE_DHCP_TIMEOUT: + EVENT_DBG("\n\tSTAMODE_DHCP_TIMEOUT\n"); + break; + + case EVENT_SOFTAPMODE_STACONNECTED: + EVENT_DBG("\n\tSOFTAPMODE_STACONNECTED\n"); + wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.sta_connected.mac)); + wifi_add_int_field(L, "AID", evt->event_info.sta_connected.aid); + EVENT_DBG("\tStation: " MACSTR "join, AID = %d\n", + MAC2STR(evt->event_info.sta_connected.mac), + evt->event_info.sta_connected.aid); + break; + + case EVENT_SOFTAPMODE_STADISCONNECTED: + EVENT_DBG("\n\tSOFTAPMODE_STADISCONNECTED\n"); + wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.sta_disconnected.mac)); + wifi_add_int_field(L, "AID", evt->event_info.sta_disconnected.aid); + EVENT_DBG("\tstation: " MACSTR "leave, AID = %d\n", + MAC2STR(evt->event_info.sta_disconnected.mac), + evt->event_info.sta_disconnected.aid); + break; + + case EVENT_SOFTAPMODE_PROBEREQRECVED: + EVENT_DBG("\n\tSOFTAPMODE_PROBEREQRECVED\n"); + wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.ap_probereqrecved.mac)); + wifi_add_int_field(L, "RSSI", evt->event_info.ap_probereqrecved.rssi); + EVENT_DBG("Station PROBEREQ: " MACSTR " RSSI = %d\n", + MAC2STR(evt->event_info.ap_probereqrecved.mac), + evt->event_info.ap_probereqrecved.rssi); + break; + + default://if event is not implemented, push table with userdata containing event data + EVENT_DBG("\n\tswitch/case default\n"); + wifi_add_sprintf_field(L, "info", "event %u not implemented", evt->event); + break; + } + + lua_call(L, 1, 0); //execute user's callback and pass Lua table + + if (wifi_event_queue_head == wifi_event_queue_tail) //if queue is empty.. + { + wifi_event_queue_head = wifi_event_queue_tail = NULL; //set queue pointers to NULL + EVENT_DBG("\n\tQueue empty\n"); + } + else //if queue is not empty... + { + wifi_event_queue_head = wifi_event_queue_head->next; //append item to end of queue + EVENT_DBG("\n\tmore in queue, posting task...\n"); + task_post_low(wifi_event_monitor_task_id, false); //post task to process next item in queue + } + + c_free(evt); //free memory used by event structure + c_free(temp); //free memory used by queue structure +} + +#ifdef WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE +static const LUA_REG_TYPE wifi_event_monitor_reason_map[] = +{ + { LSTRKEY( "UNSPECIFIED" ), LNUMVAL( REASON_UNSPECIFIED ) }, + { LSTRKEY( "AUTH_EXPIRE" ), LNUMVAL( REASON_AUTH_EXPIRE ) }, + { LSTRKEY( "AUTH_LEAVE" ), LNUMVAL( REASON_AUTH_LEAVE ) }, + { LSTRKEY( "ASSOC_EXPIRE" ), LNUMVAL( REASON_ASSOC_EXPIRE ) }, + { LSTRKEY( "ASSOC_TOOMANY" ), LNUMVAL( REASON_ASSOC_TOOMANY ) }, + { LSTRKEY( "NOT_AUTHED" ), LNUMVAL( REASON_NOT_AUTHED ) }, + { LSTRKEY( "NOT_ASSOCED" ), LNUMVAL( REASON_NOT_ASSOCED ) }, + { LSTRKEY( "ASSOC_LEAVE" ), LNUMVAL( REASON_ASSOC_LEAVE ) }, + { LSTRKEY( "ASSOC_NOT_AUTHED" ), LNUMVAL( REASON_ASSOC_NOT_AUTHED ) }, + { LSTRKEY( "DISASSOC_PWRCAP_BAD" ), LNUMVAL( REASON_DISASSOC_PWRCAP_BAD ) }, + { LSTRKEY( "DISASSOC_SUPCHAN_BAD" ), LNUMVAL( REASON_DISASSOC_SUPCHAN_BAD ) }, + { LSTRKEY( "IE_INVALID" ), LNUMVAL( REASON_IE_INVALID ) }, + { LSTRKEY( "MIC_FAILURE" ), LNUMVAL( REASON_MIC_FAILURE ) }, + { LSTRKEY( "4WAY_HANDSHAKE_TIMEOUT" ), LNUMVAL( REASON_4WAY_HANDSHAKE_TIMEOUT ) }, + { LSTRKEY( "GROUP_KEY_UPDATE_TIMEOUT" ), LNUMVAL( REASON_GROUP_KEY_UPDATE_TIMEOUT ) }, + { LSTRKEY( "IE_IN_4WAY_DIFFERS" ), LNUMVAL( REASON_IE_IN_4WAY_DIFFERS ) }, + { LSTRKEY( "GROUP_CIPHER_INVALID" ), LNUMVAL( REASON_GROUP_CIPHER_INVALID ) }, + { LSTRKEY( "PAIRWISE_CIPHER_INVALID" ), LNUMVAL( REASON_PAIRWISE_CIPHER_INVALID ) }, + { LSTRKEY( "AKMP_INVALID" ), LNUMVAL( REASON_AKMP_INVALID ) }, + { LSTRKEY( "UNSUPP_RSN_IE_VERSION" ), LNUMVAL( REASON_UNSUPP_RSN_IE_VERSION ) }, + { LSTRKEY( "INVALID_RSN_IE_CAP" ), LNUMVAL( REASON_INVALID_RSN_IE_CAP ) }, + { LSTRKEY( "802_1X_AUTH_FAILED" ), LNUMVAL( REASON_802_1X_AUTH_FAILED ) }, + { LSTRKEY( "CIPHER_SUITE_REJECTED" ), LNUMVAL( REASON_CIPHER_SUITE_REJECTED ) }, + { LSTRKEY( "BEACON_TIMEOUT" ), LNUMVAL( REASON_BEACON_TIMEOUT ) }, + { LSTRKEY( "NO_AP_FOUND" ), LNUMVAL( REASON_NO_AP_FOUND ) }, + { LSTRKEY( "AUTH_FAIL" ), LNUMVAL( REASON_AUTH_FAIL ) }, + { LSTRKEY( "ASSOC_FAIL" ), LNUMVAL( REASON_ASSOC_FAIL ) }, + { LSTRKEY( "HANDSHAKE_TIMEOUT" ), LNUMVAL( REASON_HANDSHAKE_TIMEOUT ) }, + { LNILKEY, LNILVAL } +}; +#endif + +const LUA_REG_TYPE wifi_event_monitor_map[] = +{ + { LSTRKEY( "register" ), LFUNCVAL( wifi_event_monitor_register ) }, + { LSTRKEY( "unregister" ), LFUNCVAL( wifi_event_monitor_register ) }, + { LSTRKEY( "STA_CONNECTED" ), LNUMVAL( EVENT_STAMODE_CONNECTED ) }, + { LSTRKEY( "STA_DISCONNECTED" ), LNUMVAL( EVENT_STAMODE_DISCONNECTED ) }, + { LSTRKEY( "STA_AUTHMODE_CHANGE" ), LNUMVAL( EVENT_STAMODE_AUTHMODE_CHANGE ) }, + { LSTRKEY( "STA_GOT_IP" ), LNUMVAL( EVENT_STAMODE_GOT_IP ) }, + { LSTRKEY( "STA_DHCP_TIMEOUT" ), LNUMVAL( EVENT_STAMODE_DHCP_TIMEOUT ) }, + { LSTRKEY( "AP_STACONNECTED" ), LNUMVAL( EVENT_SOFTAPMODE_STACONNECTED ) }, + { LSTRKEY( "AP_STADISCONNECTED" ), LNUMVAL( EVENT_SOFTAPMODE_STADISCONNECTED ) }, + { LSTRKEY( "AP_PROBEREQRECVED" ), LNUMVAL( EVENT_SOFTAPMODE_PROBEREQRECVED ) }, + { LSTRKEY( "EVENT_MAX" ), LNUMVAL( EVENT_MAX ) }, +#ifdef WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE + { LSTRKEY( "reason" ), LROVAL( wifi_event_monitor_reason_map ) }, +#endif + { LNILKEY, LNILVAL } +}; + +void wifi_eventmon_init() +{ + wifi_event_monitor_task_id = task_get_id(wifi_event_monitor_process_event_queue);//get task id from task interface + wifi_set_event_handler_cb(wifi_event_monitor_handle_event_cb); + return; +} + +#endif +#endif + diff --git a/docs/en/modules/wifi.md b/docs/en/modules/wifi.md index 92322916..ec3aeed2 100644 --- a/docs/en/modules/wifi.md +++ b/docs/en/modules/wifi.md @@ -9,6 +9,7 @@ The NodeMCU WiFi control is spread across several tables: - [`wifi.sta`](#wifista-module) for station mode functions - [`wifi.ap`](#wifiap-module) for wireless access point (WAP or simply AP) functions - [`wifi.ap.dhcp`](#wifiapdhcp-module) for DHCP server control +- [`wifi.eventmon`](#wifieventmon-module) for wifi event monitor ## wifi.getchannel() @@ -368,6 +369,9 @@ wifi.sta.eventMonReg(wifi.STA_IDLE) #### See also - [`wifi.sta.eventMonStart()`](#wifistaeventmonstart) - [`wifi.sta.eventMonStop()`](#wifistaeventmonstop) +- [`wifi.eventmon.register()`](#wifieventmonregister) +- [`wifi.eventmon.unregister()`](#wifieventmonunregister) + ## wifi.sta.eventMonStart() @@ -377,7 +381,7 @@ Starts WiFi station event monitor. `wifi.sta.eventMonStart([ms])` ### Parameters -`ms` interval between checks in milliseconds, defaults to 150ms if not provided +- `ms` interval between checks in milliseconds, defaults to 150ms if not provided. #### Returns `nil` @@ -394,6 +398,8 @@ wifi.sta.eventMonStart(100) #### See also - [`wifi.sta.eventMonReg()`](#wifistaeventmonreg) - [`wifi.sta.eventMonStop()`](#wifistaeventmonstop) +- [`wifi.eventmon.register()`](#wifieventmonregister) +- [`wifi.eventmon.unregister()`](#wifieventmonunregister) ## wifi.sta.eventMonStop() @@ -420,6 +426,8 @@ wifi.sta.eventMonStop(1) #### See also - [`wifi.sta.eventMonReg()`](#wifistaeventmonreg) - [`wifi.sta.eventMonStart()`](#wifistaeventmonstart) +- [`wifi.eventmon.register()`](#wifieventmonregister) +- [`wifi.eventmon.unregister()`](#wifieventmonunregister) ## wifi.sta.getap() @@ -629,6 +637,27 @@ MAC address as string e.g. "18-33-44-FE-55-BB" #### See also [`wifi.sta.getip()`](#wifistagetip) + +## wifi.sta.getrssi() + +Get RSSI(Received Signal Strength Indicator) of the Access Point which ESP8266 station connected to. + +#### Syntax +`wifi.sta.getrssi()` + +#### Parameters +none + +#### Returns +- If station is connected to an access point, `rssi` is returned. +- If station is not connected to an access point, `nil` is returned. + +#### Example +```lua +RSSI=wifi.sta.getrssi() +print("RSSI is", RSSI) +``` + ## wifi.sta.sethostname() Sets station hostname. @@ -640,7 +669,7 @@ Sets station hostname. `hostname` must only contain letters, numbers and hyphens('-') and be 32 characters or less with first and last character being alphanumeric #### Returns -true if hostname was successfully set, false otherwise +`nil` #### Example ```lua @@ -724,7 +753,7 @@ Sets SSID and password in AP mode. Be sure to make the password at least 8 chara `wifi.ap.config(cfg)` #### Parameters -- `ssdi` SSID chars 1-32 +- `ssid` SSID chars 1-32 - `pwd` password chars 8-64 - `auth` authentication one of AUTH\_OPEN, AUTH\_WPA\_PSK, AUTH\_WPA2\_PSK, AUTH\_WPA\_WPA2\_PSK, default = AUTH\_OPEN - `channel` channel number 1-14 default = 6 @@ -743,6 +772,43 @@ Sets SSID and password in AP mode. Be sure to make the password at least 8 chara wifi.ap.config(cfg) ``` +## wifi.ap.deauth() + +Deauths (forcibly removes) a client from the ESP access point by sending a corresponding IEEE802.11 management packet (first) and removing the client from it's data structures (afterwards). + +The IEEE802.11 reason code used is 2 for "Previous authentication no longer valid"(AUTH_EXPIRE). + +#### Syntax +`wifi.ap.deauth([MAC])` + +#### Parameters +- `MAC` address of station to be deauthed. + - Note: if this field is left blank, all currently connected stations will get deauthed. + +#### Returns +Returns true unless called while the ESP is in the STATION opmode + +#### Example +```lua +allowed_mac_list={"18:fe:34:00:00:00", "18:fe:34:00:00:01"} + +wifi.eventmon.register(wifi.eventmon.AP_STACONNECTED, function(T) + print("\n\tAP - STATION CONNECTED".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID) + if(allowed_mac_list~=nil) then + for _, v in pairs(allowed_mac_list) do + if(v == T.MAC) then return end + end + end + wifi.ap.deauth(T.MAC) + print("\tStation DeAuthed!") +end) + +``` + +#### See also +[`wifi.eventmon.register()`](#wifieventmonregister) +[`wifi.eventmon.reason()`](#wifieventmonreason) + ## wifi.ap.getbroadcast() Gets broadcast address in AP mode. @@ -939,3 +1005,173 @@ none #### Returns boolean indicating success + +# wifi.eventmon Module +Note: The functions `wifi.sta.eventMon___()` and `wifi.eventmon.___()` are completely seperate and can be used independently of one another. + +## wifi.eventmon.register() + +Register/unregister callbacks for WiFi event monitor. + +#### Syntax +wifi.eventmon.register(Event[, function(T)]) + +#### Parameters +Event: WiFi event you would like to set a callback for. + +- Valid WiFi events: + - wifi.eventmon.STA_CONNECTED + - wifi.eventmon.STA_DISCONNECTED + - wifi.eventmon.STA_AUTHMODE_CHANGE + - wifi.eventmon.STA_GOT_IP + - wifi.eventmon.STA_DHCP_TIMEOUT + - wifi.eventmon.AP_STACONNECTED + - wifi.eventmon.AP_STADISCONNECTED + - wifi.eventmon.AP_PROBEREQRECVED + +#### Returns +Function: +`nil` + +Callback: +T: Table returned by event. + +- `wifi.eventmon.STA_CONNECTED` Station is connected to access point. + - `SSID`: SSID of access point. + - `BSSID`: BSSID of access point. + - `channel`: The channel the access point is on. +- `wifi.eventmon.STA_DISCONNECT`: Station was disconnected from access point. + - `SSID`: SSID of access point. + - `BSSID`: BSSID of access point. + - `REASON`: See [wifi.eventmon.reason](#wifieventmonreason) below. +- `wifi.eventmon.STA_AUTHMODE_CHANGE`: Access point has changed authorization mode. + - `old_auth_mode`: Old wifi authorization mode. + - `new_auth_mode`: New wifi authorization mode. +- `wifi.eventmon.STA_GOT_IP`: Station got an IP address. + - `IP`: The IP address assigned to the station. + - `netmask`: Subnet mask. + - `gateway`: The IP address of the access point the station is connected to. +- `wifi.eventmon.STA_DHCP_TIMEOUT`: Station DHCP request has timed out. + - Blank table is returned. +- `wifi.eventmon.AP_STACONNECTED`: A new client has connected to the access point. + - `MAC`: MAC address of client that has connected. + - `AID`: SDK provides no details concerning this return value. +- `wifi.eventmon.AP_STADISCONNECTED`: A client has disconnected from the access point. + - `MAC`: MAC address of client that has disconnected. + - `AID`: SDK provides no details concerning this return value. +- `wifi.eventmon.AP_PROBEREQRECVED`: A probe request was received. + - `MAC`: MAC address of the client that is probing the access point. + - `RSSI`: Received Signal Strength Indicator of client. + +#### Example + +```lua + wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, function(T) + print("\n\tSTA - CONNECTED".."\n\tSSID: "..T.SSID.."\n\tBSSID: ".. + T.BSSID.."\n\tChannel: "..T.channel) + end) + + wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, function(T) + print("\n\tSTA - DISCONNECTED".."\n\tSSID: "..T.SSID.."\n\tBSSID: ".. + T.BSSID.."\n\treason: "..T.reason) + end) + + wifi.eventmon.register(wifi.eventmon.STA_AUTHMODE_CHANGE, Function(T) + print("\n\tSTA - AUTHMODE CHANGE".."\n\told_auth_mode: ".. + T.old_auth_mode.."\n\tnew_auth_mode: "..T.new_auth_mode) + end) + + wifi.eventmon.register(wifi.eventmon.stasgottipa_got_ip, function(T) + print("\n\tSTA - GOT IP".."\n\tStation IP: "..T.IP.."\n\tSubnet mask: ".. + T.netmask.."\n\tGateway IP: "..T.gateway) + end) + + wifi.eventmon.register(wifi.eventmon.STA_DHCP_TIMEOUT, function() + print("\n\tSTA - DHCP TIMEOUT") + end) + + wifi.eventmon.register(wifi.eventmon.AP_STACONNECTED, function(T) + print("\n\tAP - STATION CONNECTED".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID) + end) + + wifi.eventmon.register(wifi.eventmon.AP_STADISCONNECTED, function(T) + print("\n\tAP - STATION DISCONNECTED".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID) + end) + + wifi.eventmon.register(wifi.eventmon.AP_PROBEREQRECVED, function(T) + print("\n\tAP - STATION DISCONNECTED".."\n\tMAC: ".. T.MAC.."\n\tRSSI: "..T.RSSI) + end) +``` +#### See also +- [`wifi.eventmon.unregister()`](#wifieventmonunregister) +- [`wifi.sta.eventMonStart()`](#wifistaeventmonstart) +- [`wifi.sta.eventMonStop()`](#wifistaeventmonstop) +- [`wifi.sta.eventMonReg()`](#wifistaeventmonreg) + +## wifi.eventmon.unregister() + +Unregister callbacks for WiFi event monitor. + +#### Syntax +wifi.eventmon.unregister(Event) + +#### Parameters +Event: WiFi event you would like to set a callback for. + +- Valid WiFi events: + - wifi.eventmon.STA_CONNECTED + - wifi.eventmon.STA_DISCONNECTED + - wifi.eventmon.STA_AUTHMODE_CHANGE + - wifi.eventmon.STA_GOT_IP + - wifi.eventmon.STA_DHCP_TIMEOUT + - wifi.eventmon.AP_STACONNECTED + - wifi.eventmon.AP_STADISCONNECTED + - wifi.eventmon.AP_PROBEREQRECVED + +#### Returns +`nil` + +#### Example + +```lua + wifi.eventmon.unregister(wifi.eventmon.STA_CONNECTED) +``` +#### See also +- [`wifi.eventmon.register()`](#wifieventmonregister) +- [`wifi.sta.eventMonStart()`](#wifistaeventmonstart) +- [`wifi.sta.eventMonStop()`](#wifistaeventmonstop) + +## wifi.eventmon.reason + +Table containing disconnect reasons. + +| Disconnect reason | value | +|:--------------------|:-------:| +|wifi.eventmon.reason.UNSPECIFIED | 1 | +|wifi.eventmon.reason.AUTH_EXPIRE | 2 | +|wifi.eventmon.reason.AUTH_LEAVE | 3 | +|wifi.eventmon.reason.ASSOC_EXPIRE | 4 | +|wifi.eventmon.reason.ASSOC_TOOMANY | 5 | +|wifi.eventmon.reason.NOT_AUTHED | 6 | +|wifi.eventmon.reason.NOT_ASSOCED | 7 | +|wifi.eventmon.reason.ASSOC_LEAVE | 8 | +|wifi.eventmon.reason.ASSOC_NOT_AUTHED | 9 | +|wifi.eventmon.reason.DISASSOC_PWRCAP_BAD | 10 | +|wifi.eventmon.reason.DISASSOC_SUPCHAN_BAD | 11 | +|wifi.eventmon.reason.IE_INVALID | 13 | +|wifi.eventmon.reason.MIC_FAILURE | 14 | +|wifi.eventmon.reason.4WAY_HANDSHAKE_TIMEOUT | 15 | +|wifi.eventmon.reason.GROUP_KEY_UPDATE_TIMEOUT | 16 | +|wifi.eventmon.reason.IE_IN_4WAY_DIFFERS | 17 | +|wifi.eventmon.reason.GROUP_CIPHER_INVALID | 18 | +|wifi.eventmon.reason.PAIRWISE_CIPHER_INVALID | 19 | +|wifi.eventmon.reason.AKMP_INVALID | 20 | +|wifi.eventmon.reason.UNSUPP_RSN_IE_VERSION | 21 | +|wifi.eventmon.reason.INVALID_RSN_IE_CAP | 22 | +|wifi.eventmon.reason.802_1X_AUTH_FAILED | 23 | +|wifi.eventmon.reason.CIPHER_SUITE_REJECTED | 24 | +|wifi.eventmon.reason.BEACON_TIMEOUT | 200 | +|wifi.eventmon.reason.NO_AP_FOUND | 201 | +|wifi.eventmon.reason.AUTH_FAIL | 202 | +|wifi.eventmon.reason.ASSOC_FAIL | 203 | +|wifi.eventmon.reason.HANDSHAKE_TIMEOUT | 204 | diff --git a/sdk-overrides/include/ets_sys.h b/sdk-overrides/include/ets_sys.h new file mode 100644 index 00000000..b92b036b --- /dev/null +++ b/sdk-overrides/include/ets_sys.h @@ -0,0 +1,12 @@ +#ifndef SDK_OVERRIDES_INCLUDE_ETS_SYS_H_ +#define SDK_OVERRIDES_INCLUDE_ETS_SYS_H_ + +#include_next "ets_sys.h" + +#include "../libc/c_stdarg.h" + +int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3))); + +int ets_vsprintf (char *d, const char *s, va_list ap); + +#endif /* SDK_OVERRIDES_INCLUDE_ETS_SYS_H_ */ diff --git a/sdk-overrides/include/user_interface.h b/sdk-overrides/include/user_interface.h new file mode 100644 index 00000000..2fe4da29 --- /dev/null +++ b/sdk-overrides/include/user_interface.h @@ -0,0 +1,8 @@ +#ifndef SDK_OVERRIDES_INCLUDE_USER_INTERFACE_H_ +#define SDK_OVERRIDES_INCLUDE_USER_INTERFACE_H_ + +#include_next "user_interface.h" + +bool wifi_softap_deauth(uint8 mac[6]); + +#endif /* SDK_OVERRIDES_INCLUDE_USER_INTERFACE_H_ */