From 07ced6396969d13e17047e86bf30135ed4c8a3ff Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Sun, 20 May 2018 00:46:04 -0700 Subject: [PATCH] Dev wifi/wifi_eventmon malloc/free update (#2318) * updated wifi_eventmon to store events in LUA_REGISTRYINDEX * updated wifi_eventmon debug comments * Updated wifi.c to remove c_free() In wifi_ap_listclient(app/modules/wifi.c), c_free() was replaced with wifi_softap_free_station_info() * Removed unnecessary line of code from app/modules/wifi_eventmon.c --- app/modules/wifi.c | 7 +- app/modules/wifi_common.h | 22 +++--- app/modules/wifi_eventmon.c | 139 ++++++++++++++++++++---------------- 3 files changed, 88 insertions(+), 80 deletions(-) diff --git a/app/modules/wifi.c b/app/modules/wifi.c index 3eb68194..e0460c13 100644 --- a/app/modules/wifi.c +++ b/app/modules/wifi.c @@ -1787,7 +1787,7 @@ static int wifi_ap_listclient( lua_State* L ) { if (wifi_get_opmode() == STATION_MODE) { - return luaL_error( L, "Can't list client in STATION_MODE mode" ); + return luaL_error( L, "Can't list clients in STATION mode" ); } char temp[64]; @@ -1800,10 +1800,9 @@ static int wifi_ap_listclient( lua_State* L ) { c_sprintf(temp, MACSTR, MAC2STR(station->bssid)); wifi_add_sprintf_field(L, temp, IPSTR, IP2STR(&station->ip)); - next_station = STAILQ_NEXT(station, next); - c_free(station); - station = next_station; + station = STAILQ_NEXT(station, next); } + wifi_softap_free_station_info(); return 1; } diff --git a/app/modules/wifi_common.h b/app/modules/wifi_common.h index 122e4615..789633a3 100644 --- a/app/modules/wifi_common.h +++ b/app/modules/wifi_common.h @@ -19,21 +19,17 @@ 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) -{ +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); + 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); +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; } } @@ -47,13 +43,13 @@ void wifi_change_default_host_name(void); #endif #if defined(EVENT_DEBUG) || defined(NODE_DEBUG) -#define EVENT_DBG(...) c_printf(__VA_ARGS__) +#define EVENT_DBG(fmt, ...) c_printf("\n EVENT_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__) + #else #define EVENT_DBG(...) //c_printf(__VA_ARGS__) #endif -enum wifi_suspension_state -{ +enum wifi_suspension_state{ WIFI_AWAKE = 0, WIFI_SUSPENSION_PENDING = 1, WIFI_SUSPENDED = 2 diff --git a/app/modules/wifi_eventmon.c b/app/modules/wifi_eventmon.c index 66bd9827..06bce2a3 100644 --- a/app/modules/wifi_eventmon.c +++ b/app/modules/wifi_eventmon.c @@ -22,13 +22,6 @@ //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 #ifdef LUA_USE_MODULES_WIFI_MONITOR @@ -62,9 +55,11 @@ int wifi_event_monitor_register(lua_State* L) } } +static sint32_t event_queue_ref = LUA_NOREF; + static void wifi_event_monitor_handle_event_cb(System_Event_t *evt) { - EVENT_DBG("\n\twifi_event_monitor_handle_event_cb is called\n"); + EVENT_DBG("was called (Event:%d)", evt->event); #ifdef LUA_USE_MODULES_WIFI_MONITOR if (hook_fn && hook_fn(evt)) { @@ -79,38 +74,66 @@ static void wifi_event_monitor_handle_event_cb(System_Event_t *evt) evt->event == EVENT_SOFTAPMODE_STADISCONNECTED || evt->event == EVENT_SOFTAPMODE_PROBEREQRECVED || evt->event == EVENT_OPMODE_CHANGED))) { - 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; + lua_State* L = lua_getstate(); + if(event_queue_ref == LUA_NOREF){ //if event queue has not been created, create it now + lua_newtable(L); + event_queue_ref = luaL_ref(L, LUA_REGISTRYINDEX); } - c_memcpy(temp->evt, evt, sizeof(System_Event_t)); //copy event data to new struct + lua_rawgeti(L, LUA_REGISTRYINDEX, event_queue_ref); - 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"); + System_Event_t* evt_tmp = lua_newuserdata(L, sizeof(System_Event_t)); + c_memcpy(evt_tmp, evt, sizeof(System_Event_t)); //copy event data to new struct + sint32_t evt_ud_ref = luaL_ref(L, LUA_REGISTRYINDEX); + size_t queue_len = lua_objlen(L, -1); + + //add event to queue + lua_pushnumber(L, queue_len+1); + lua_pushnumber(L, evt_ud_ref); + lua_rawset(L, -3); + + if(queue_len == 0){ //if queue was empty, post task + EVENT_DBG("Posting task"); 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"); - } - } -} + else{ + EVENT_DBG("Appending queue, items in queue: %d", lua_objlen(L, -1)); + } + lua_pop(L, 1); + } //else{} //there are no callbacks registered, so the event can't be processed +} 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 + lua_rawgeti(L, LUA_REGISTRYINDEX, event_queue_ref); + int index = 1; + lua_rawgeti(L, 1, index); + sint32 event_ref = lua_tonumber(L, -1); + lua_pop(L, 1); - EVENT_DBG("\t\tevent %u\n", evt->event); + //remove event reference from queue + int queue_length = lua_objlen(L, 1); + lua_rawgeti(L, 1, index); + for(; index0){ + task_post_low(wifi_event_monitor_task_id, false); //post task to process next item in queue + EVENT_DBG("%d events left in queue, posting task", queue_length); + } + lua_pop(L, 1); //pop event queue from stack if(wifi_event_cb_ref[evt->event] != LUA_NOREF) // check if user has registered a callback { @@ -130,107 +153,97 @@ static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 pri switch (evt->event) { case EVENT_STAMODE_CONNECTED: - EVENT_DBG("\n\tSTAMODE_CONNECTED\n"); + EVENT_DBG("Event: %d (STAMODE_CONNECTED)", EVENT_STAMODE_CONNECTED); 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", + EVENT_DBG("Connected to SSID %s, Channel %d", evt->event_info.connected.ssid, evt->event_info.connected.channel); break; case EVENT_STAMODE_DISCONNECTED: - EVENT_DBG("\n\tSTAMODE_DISCONNECTED\n"); + EVENT_DBG("Event: %d (STAMODE_DISCONNECTED)", EVENT_STAMODE_DISCONNECTED); 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", + EVENT_DBG("Disconnect from SSID %s, reason %d", evt->event_info.disconnected.ssid, evt->event_info.disconnected.reason); break; case EVENT_STAMODE_AUTHMODE_CHANGE: - EVENT_DBG("\n\tSTAMODE_AUTHMODE_CHANGE\n"); + EVENT_DBG("Event: %d (STAMODE_AUTHMODE_CHANGE)", EVENT_STAMODE_AUTHMODE_CHANGE); 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", + EVENT_DBG("Authmode: %u -> %u", 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"); + EVENT_DBG("Event: %d (STAMODE_GOT_IP)", EVENT_STAMODE_GOT_IP); 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", + EVENT_DBG("IP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "", 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"); + EVENT_DBG("Event: %d (STAMODE_DHCP_TIMEOUT)", EVENT_STAMODE_DHCP_TIMEOUT); break; case EVENT_SOFTAPMODE_STACONNECTED: - EVENT_DBG("\n\tSOFTAPMODE_STACONNECTED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_STACONNECTED)", EVENT_SOFTAPMODE_STACONNECTED); 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", + EVENT_DBG("Station: " MACSTR "join, AID = %d", MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid); break; case EVENT_SOFTAPMODE_STADISCONNECTED: - EVENT_DBG("\n\tSOFTAPMODE_STADISCONNECTED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_STADISCONNECTED)", EVENT_SOFTAPMODE_STADISCONNECTED); 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", + EVENT_DBG("station: " MACSTR "leave, AID = %d", MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid); break; case EVENT_SOFTAPMODE_PROBEREQRECVED: - EVENT_DBG("\n\tSOFTAPMODE_PROBEREQRECVED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_PROBEREQRECVED)", EVENT_SOFTAPMODE_PROBEREQRECVED); 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", + EVENT_DBG("Station PROBEREQ: " MACSTR " RSSI = %d", MAC2STR(evt->event_info.ap_probereqrecved.mac), evt->event_info.ap_probereqrecved.rssi); break; case EVENT_OPMODE_CHANGED: - EVENT_DBG("\n\tOPMODE_CHANGED\n"); + EVENT_DBG("Event: %d (OPMODE_CHANGED)", EVENT_OPMODE_CHANGED); wifi_add_int_field(L, "old_mode", evt->event_info.opmode_changed.old_opmode); wifi_add_int_field(L, "new_mode", evt->event_info.opmode_changed.new_opmode); - EVENT_DBG("\topmode: %u -> %u\n", + EVENT_DBG("opmode: %u -> %u", evt->event_info.opmode_changed.old_opmode, evt->event_info.opmode_changed.new_opmode); break; default://if event is not implemented, return event id - EVENT_DBG("\n\tswitch/case default\n"); + EVENT_DBG("Event: %d (switch/case default)", evt->event); wifi_add_sprintf_field(L, "info", "event %u not implemented", evt->event); break; } + + luaL_unref(L, LUA_REGISTRYINDEX, event_ref); //the userdata containing event info is no longer needed + event_ref = LUA_NOREF; + 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 + return; } #ifdef WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE