idf4: part 2.1 - uplift to new esp_event system events
Some parts dry-coded in the disabled modules; to be fixed when sorting out the deprecated/removed APIs used in said modules. Still untested beyond compile/linking.
This commit is contained in:
parent
379a8eb844
commit
62b3d06020
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "esp_netif_ip_addr.h"
|
||||
|
||||
// String buffer for a formatted MAC/BSSID
|
||||
#define MAC_STR_SZ (6*2+5+1)
|
||||
|
@ -47,4 +48,8 @@ void ipstr (char *out, const ip_addr_t *ip);
|
|||
void ip4str (char *out, const ip4_addr_t *ip);
|
||||
void ip6str (char *out, const ip6_addr_t *ip);
|
||||
|
||||
void ipstr_esp (char *out, const esp_ip_addr_t *ip);
|
||||
void ip4str_esp (char *out, const esp_ip4_addr_t *ip);
|
||||
void ip6str_esp (char *out, const esp_ip6_addr_t *ip);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,30 +49,33 @@
|
|||
* Registering is as simple as including this header file, then adding a
|
||||
* line for each event the module wishes to be notified about, e.g.:
|
||||
*
|
||||
* NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_GOT_IP, do_stuff_when_got_ip);
|
||||
* NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_DISCONNECTED, do_stuff_when_discon);
|
||||
* NODEMCU_ESP_EVENT(IP_EVENT, IP_EVENT_STA_GOT_IP, do_stuff_when_got_ip);
|
||||
* NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, do_stuff_when_discon);
|
||||
*
|
||||
* These registrations are done at link-time, and consume no additional RAM.
|
||||
* The event IDs are located in esp_event.h in the IDF.
|
||||
*/
|
||||
|
||||
// Event callback prototype
|
||||
typedef void (*nodemcu_esp_event_cb) (const system_event_t *event);
|
||||
typedef void (*nodemcu_esp_event_cb) (esp_event_base_t event_base, int32_t event_id, const void *event_data);
|
||||
|
||||
// Internal definitions
|
||||
typedef struct {
|
||||
system_event_id_t event_id;
|
||||
esp_event_base_t *event_base_ptr;
|
||||
int32_t event_id;
|
||||
nodemcu_esp_event_cb callback;
|
||||
} nodemcu_esp_event_reg_t;
|
||||
|
||||
extern nodemcu_esp_event_reg_t _esp_event_cb_table_start;
|
||||
extern nodemcu_esp_event_reg_t _esp_event_cb_table_end;
|
||||
|
||||
#define NODEMCU_ESP_EVENT(evcode, func) \
|
||||
#define NODEMCU_ESP_EVENT(evbase, evcode, func) \
|
||||
static const LOCK_IN_SECTION(esp_event_cb_table) \
|
||||
nodemcu_esp_event_reg_t MODULE_PASTE_(func,evcode) = { evcode, func };
|
||||
nodemcu_esp_event_reg_t MODULE_PASTE_(func,evbase##evcode) = { \
|
||||
.event_base_ptr = &evbase, \
|
||||
.event_id = evcode, \
|
||||
.callback = func };
|
||||
|
||||
_Static_assert(_Alignof(nodemcu_esp_event_reg_t) == 4, "Unexpected alignment of event registration - update linker script snippets to match!");
|
||||
_Static_assert(sizeof(nodemcu_esp_event_reg_t) == 8, "Unexpected size of array member - update the linker script snippets to match!");
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,9 +31,7 @@
|
|||
* @author Johny Mattsson <jmattsson@dius.com.au>
|
||||
*/
|
||||
#include "ip_fmt.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/ip4_addr.h"
|
||||
#include "esp_netif.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void macstr (char *str, const uint8_t *mac)
|
||||
|
@ -54,11 +52,32 @@ void ipstr (char *out, const ip_addr_t *ip)
|
|||
|
||||
void ip4str (char *out, const ip4_addr_t *ip)
|
||||
{
|
||||
ip4addr_ntoa_r (ip, out, IP_STR_SZ);
|
||||
ip4addr_ntoa_r(ip, out, IP_STR_SZ);
|
||||
}
|
||||
|
||||
|
||||
void ip6str (char *out, const ip6_addr_t *ip)
|
||||
{
|
||||
ip6addr_ntoa_r (ip, out, IP_STR_SZ);
|
||||
ip6addr_ntoa_r(ip, out, IP_STR_SZ);
|
||||
}
|
||||
|
||||
|
||||
void ipstr_esp (char *out, const esp_ip_addr_t *ip)
|
||||
{
|
||||
if (ip->type == ESP_IPADDR_TYPE_V4)
|
||||
ip4str (out, &ip->u_addr.ip4);
|
||||
else if (ip->type == ESP_IPADDR_TYPE_V6)
|
||||
ip6str (out, &ip->u_addr.ip6);
|
||||
}
|
||||
|
||||
|
||||
void ip4str_esp (char *out, const esp_ip4_addr_t *ip)
|
||||
{
|
||||
esp_ip4addr_ntoa(ip, out, IP_STR_SZ);
|
||||
}
|
||||
|
||||
|
||||
void ip6str_esp (char *out, const esp_ip6_addr_t *ip)
|
||||
{
|
||||
ip6addr_ntoa_r((ip6_addr_t *)ip, out, IP_STR_SZ);
|
||||
}
|
||||
|
|
|
@ -31,51 +31,62 @@
|
|||
#define SIG_LUA 0
|
||||
#define SIG_UARTINPUT 1
|
||||
|
||||
|
||||
static task_handle_t esp_event_task;
|
||||
static QueueHandle_t esp_event_queue;
|
||||
// We don't get argument size data from the esp_event dispatch, so it's
|
||||
// not possible to copy and forward events from the default event queue
|
||||
// to one running within our task context. To cope with this, we instead
|
||||
// have to effectively make a blocking inter-task call, by having our
|
||||
// default loop handler post a nodemcu task event with a pointer to the
|
||||
// event data, and then *block* until that task event has been processed.
|
||||
// This is less elegant than I would like, but trying to run the entire
|
||||
// LVM in the context of the system default event loop RTOS task is an
|
||||
// even worse idea, so here we are.
|
||||
typedef struct {
|
||||
esp_event_base_t event_base;
|
||||
int32_t event_id;
|
||||
void *event_data;
|
||||
} relayed_event_t;
|
||||
static task_handle_t relayed_event_task;
|
||||
static SemaphoreHandle_t relayed_event_handled;
|
||||
|
||||
|
||||
// The callback happens in the wrong task context, so we bounce the event
|
||||
// into our own queue so they all get handled in the same context as the
|
||||
// LVM, making life as easy as possible for us.
|
||||
esp_err_t bounce_events(void *ignored_ctx, system_event_t *event)
|
||||
// This function runs in the context of the system default event loop RTOS task
|
||||
static void relay_default_loop_events(
|
||||
void *arg, esp_event_base_t base, int32_t id, void *data)
|
||||
{
|
||||
if (!event)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
if (!esp_event_task || !esp_event_queue)
|
||||
return ESP_ERR_INVALID_STATE; // too early!
|
||||
|
||||
portBASE_TYPE ret = xQueueSendToBack (esp_event_queue, event, 0);
|
||||
if (ret != pdPASS)
|
||||
{
|
||||
NODE_ERR("failed to queue esp event %d", event->event_id);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// If the task_post() fails, it only means the event gets delayed, hence
|
||||
// we claim OK regardless.
|
||||
task_post_medium (esp_event_task, 0);
|
||||
return ESP_OK;
|
||||
(void)arg;
|
||||
relayed_event_t event = {
|
||||
.event_base = base,
|
||||
.event_id = id,
|
||||
.event_data = data,
|
||||
};
|
||||
_Static_assert(sizeof(&event) >= sizeof(task_param_t), "pointer-vs-int");
|
||||
// Only block if we actually posted the request, otherwise we'll deadlock!
|
||||
if (task_post_medium(relayed_event_task, (intptr_t)&event))
|
||||
xSemaphoreTake(relayed_event_handled, portMAX_DELAY);
|
||||
else
|
||||
printf("ERROR: failed to forward esp event %s/%d", base, id);
|
||||
}
|
||||
|
||||
|
||||
static void handle_esp_event (task_param_t param, task_prio_t prio)
|
||||
static void handle_default_loop_event(task_param_t param, task_prio_t prio)
|
||||
{
|
||||
(void)param;
|
||||
(void)prio;
|
||||
const relayed_event_t *event = (const relayed_event_t *)param;
|
||||
|
||||
system_event_t evt;
|
||||
while (xQueueReceive (esp_event_queue, &evt, 0) == pdPASS)
|
||||
nodemcu_esp_event_reg_t *evregs = &_esp_event_cb_table_start;
|
||||
for (; evregs < &_esp_event_cb_table_end; ++evregs)
|
||||
{
|
||||
nodemcu_esp_event_reg_t *evregs = &_esp_event_cb_table_start;
|
||||
for (; evregs < &_esp_event_cb_table_end; ++evregs)
|
||||
{
|
||||
if (evregs->event_id == evt.event_id)
|
||||
evregs->callback (&evt);
|
||||
}
|
||||
bool event_base_match =
|
||||
(evregs->event_base_ptr == NULL) || // ESP_EVENT_ANY_BASE marker
|
||||
(*evregs->event_base_ptr == event->event_base);
|
||||
bool event_id_match =
|
||||
(evregs->event_id == event->event_id) ||
|
||||
(evregs->event_id == ESP_EVENT_ANY_ID);
|
||||
|
||||
if (event_base_match && event_id_match)
|
||||
evregs->callback(event->event_base, event->event_id, event->event_data);
|
||||
}
|
||||
xSemaphoreGive(relayed_event_handled);
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,17 +152,21 @@ void nodemcu_init(void)
|
|||
}
|
||||
|
||||
|
||||
void app_main (void)
|
||||
void __attribute__((noreturn)) app_main(void)
|
||||
{
|
||||
task_init();
|
||||
|
||||
esp_event_queue =
|
||||
xQueueCreate (CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof (system_event_t));
|
||||
esp_event_task = task_get_id (handle_esp_event);
|
||||
|
||||
input_task = task_get_id (handle_input);
|
||||
|
||||
esp_event_loop_init(bounce_events, NULL);
|
||||
relayed_event_handled = xSemaphoreCreateBinary();
|
||||
relayed_event_task = task_get_id(handle_default_loop_event);
|
||||
|
||||
esp_event_loop_create_default();
|
||||
esp_event_handler_register(
|
||||
ESP_EVENT_ANY_BASE,
|
||||
ESP_EVENT_ANY_ID,
|
||||
relay_default_loop_events,
|
||||
NULL);
|
||||
|
||||
ConsoleSetup_t cfg;
|
||||
cfg.bit_rate = CONFIG_NODEMCU_CONSOLE_BIT_RATE;
|
||||
|
|
|
@ -72,35 +72,36 @@ static void eth_gpio_config_rmii( void )
|
|||
|
||||
// --- Event handling -----------------------------------------------------
|
||||
|
||||
typedef void (*fill_cb_arg_fn) (lua_State *L, const system_event_t *evt);
|
||||
typedef void (*fill_cb_arg_fn) (lua_State *L, const void *data);
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
system_event_id_t event_id;
|
||||
esp_event_base_t event_base_ptr;
|
||||
int32_t event_id;
|
||||
fill_cb_arg_fn fill_cb_arg;
|
||||
} event_desc_t;
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
static void eth_got_ip (lua_State *L, const system_event_t *evt);
|
||||
static void empty_arg (lua_State *L, const system_event_t *evt) {}
|
||||
static void eth_got_ip (lua_State *L, const void *data);
|
||||
static void empty_arg (lua_State *L, const void *data) {}
|
||||
|
||||
static const event_desc_t events[] =
|
||||
{
|
||||
{ "start", SYSTEM_EVENT_ETH_START, empty_arg },
|
||||
{ "stop", SYSTEM_EVENT_ETH_STOP, empty_arg },
|
||||
{ "connected", SYSTEM_EVENT_ETH_CONNECTED, empty_arg },
|
||||
{ "disconnected", SYSTEM_EVENT_ETH_DISCONNECTED, empty_arg },
|
||||
{ "got_ip", SYSTEM_EVENT_ETH_GOT_IP, eth_got_ip },
|
||||
{ "start", ÐERNET_EVENT, ETHERNET_EVENT_START, empty_arg },
|
||||
{ "stop", ÐERNET_EVENT, ETHERNET_EVENT_STOP, empty_arg },
|
||||
{ "connected", ÐERNET_EVENT, ETHERNET_EVENT_CONNECTED, empty_arg },
|
||||
{ "disconnected", ÐERNET_EVENT, ETHERNET_EVENT_DISCONNECTED, empty_arg },
|
||||
{ "got_ip", &IP_EVENT, IP_EVENT_GOT_IP, eth_got_ip },
|
||||
};
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
static int event_cb[ARRAY_LEN(events)];
|
||||
|
||||
static int eth_event_idx_by_id( system_event_id_t id )
|
||||
static int eth_event_idx_by_id( esp_event_base_t base, int32_t id )
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_LEN(events); ++i)
|
||||
if (events[i].event_id == id)
|
||||
if (*events[i].event_base_ptr == base && events[i].event_id == id)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
@ -114,9 +115,9 @@ static int eth_event_idx_by_name( const char *name )
|
|||
}
|
||||
|
||||
|
||||
static void eth_got_ip( lua_State *L, const system_event_t *evt )
|
||||
static void eth_got_ip( lua_State *L, const void *data )
|
||||
{
|
||||
(void)evt;
|
||||
(void)data;
|
||||
tcpip_adapter_ip_info_t ip_info;
|
||||
|
||||
memset(&ip_info, 0, sizeof(tcpip_adapter_ip_info_t));
|
||||
|
@ -140,9 +141,9 @@ static void eth_got_ip( lua_State *L, const system_event_t *evt )
|
|||
lua_setfield( L, -2, "gw" );
|
||||
}
|
||||
|
||||
static void on_event( const system_event_t *evt )
|
||||
static void on_event(esp_event_base_t base, int32_t id, const void *data)
|
||||
{
|
||||
int idx = eth_event_idx_by_id( evt->event_id );
|
||||
int idx = eth_event_idx_by_id( base, id );
|
||||
if (idx < 0 || event_cb[idx] == LUA_NOREF)
|
||||
return;
|
||||
|
||||
|
@ -151,18 +152,17 @@ static void on_event( const system_event_t *evt )
|
|||
lua_rawgeti( L, LUA_REGISTRYINDEX, event_cb[idx] );
|
||||
lua_pushstring( L, events[idx].name );
|
||||
lua_createtable( L, 0, 5 );
|
||||
events[idx].fill_cb_arg( L, evt );
|
||||
events[idx].fill_cb_arg( L, data );
|
||||
lua_pcall( L, 2, 0, 0 );
|
||||
|
||||
lua_settop( L, top );
|
||||
}
|
||||
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_ETH_START, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_ETH_STOP, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_ETH_CONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_ETH_DISCONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_ETH_GOT_IP, on_event);
|
||||
|
||||
NODEMCU_ESP_EVENT(ETHERNET_EVENT, ETHERNET_EVENT_START, on_event);
|
||||
NODEMCU_ESP_EVENT(ETHERNET_EVENT, ETHERNET_EVENT_STOP, on_event);
|
||||
NODEMCU_ESP_EVENT(ETHERNET_EVENT, ETHERNET_EVENT_CONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(ETHERNET_EVENT, ETHERNET_EVENT_DISCONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(IP_EVENT, IP_EVENT_ETH_GOT_IP, on_event);
|
||||
|
||||
|
||||
// Lua API
|
||||
|
|
|
@ -46,58 +46,65 @@
|
|||
#define DEFAULT_AP_BEACON 100
|
||||
|
||||
// --- Event handling ----------------------------------------------------
|
||||
static void ap_staconn (lua_State *L, const system_event_t *evt);
|
||||
static void ap_stadisconn (lua_State *L, const system_event_t *evt);
|
||||
static void ap_probe_req (lua_State *L, const system_event_t *evt);
|
||||
static void empty_arg (lua_State *L, const system_event_t *evt) {}
|
||||
static void ap_staconn (lua_State *L, const void *data);
|
||||
static void ap_stadisconn (lua_State *L, const void *data);
|
||||
static void ap_probe_req (lua_State *L, const void *data);
|
||||
static void empty_arg (lua_State *L, const void *data) {}
|
||||
|
||||
static const event_desc_t events[] =
|
||||
{
|
||||
{ "start", SYSTEM_EVENT_AP_START, empty_arg },
|
||||
{ "stop", SYSTEM_EVENT_AP_STOP, empty_arg },
|
||||
{ "sta_connected", SYSTEM_EVENT_AP_STACONNECTED, ap_staconn },
|
||||
{ "sta_disconnected", SYSTEM_EVENT_AP_STADISCONNECTED, ap_stadisconn },
|
||||
{ "probe_req", SYSTEM_EVENT_AP_PROBEREQRECVED, ap_probe_req }
|
||||
{ "start", &WIFI_EVENT, WIFI_EVENT_AP_START, empty_arg },
|
||||
{ "stop", &WIFI_EVENT, WIFI_EVENT_AP_STOP, empty_arg },
|
||||
{ "sta_connected", &WIFI_EVENT, WIFI_EVENT_AP_STACONNECTED, ap_staconn},
|
||||
{ "sta_disconnected", &WIFI_EVENT, WIFI_EVENT_AP_STADISCONNECTED, ap_stadisconn },
|
||||
{ "probe_req", &WIFI_EVENT, WIFI_EVENT_AP_PROBEREQRECVED, ap_probe_req },
|
||||
};
|
||||
|
||||
static int event_cb[ARRAY_LEN(events)];
|
||||
|
||||
static void ap_staconn (lua_State *L, const system_event_t *evt)
|
||||
static void ap_staconn (lua_State *L, const void *data)
|
||||
{
|
||||
const wifi_event_ap_staconnected_t *sta_connected =
|
||||
(const wifi_event_ap_staconnected_t *)data;
|
||||
char mac[MAC_STR_SZ];
|
||||
macstr (mac, evt->event_info.sta_connected.mac);
|
||||
macstr (mac, sta_connected->mac);
|
||||
lua_pushstring (L, mac);
|
||||
lua_setfield (L, -2, "mac");
|
||||
|
||||
lua_pushinteger (L, evt->event_info.sta_connected.aid);
|
||||
lua_pushinteger (L, sta_connected->aid);
|
||||
lua_setfield (L, -2, "id");
|
||||
}
|
||||
|
||||
static void ap_stadisconn (lua_State *L, const system_event_t *evt)
|
||||
static void ap_stadisconn (lua_State *L, const void *data)
|
||||
{
|
||||
const wifi_event_ap_stadisconnected_t *sta_disconnected =
|
||||
(const wifi_event_ap_stadisconnected_t *)data;
|
||||
|
||||
char mac[MAC_STR_SZ];
|
||||
macstr (mac, evt->event_info.sta_disconnected.mac);
|
||||
macstr (mac, sta_disconnected->mac);
|
||||
lua_pushstring (L, mac);
|
||||
lua_setfield (L, -2, "mac");
|
||||
|
||||
lua_pushinteger (L, evt->event_info.sta_disconnected.aid);
|
||||
lua_pushinteger (L, sta_disconnected->aid);
|
||||
lua_setfield (L, -2, "id");
|
||||
}
|
||||
|
||||
static void ap_probe_req (lua_State *L, const system_event_t *evt)
|
||||
static void ap_probe_req (lua_State *L, const void *data)
|
||||
{
|
||||
const wifi_event_ap_probe_req_rx_t *ap_probereqrecved =
|
||||
(const wifi_event_ap_probe_req_rx_t *)data;
|
||||
char str[MAC_STR_SZ];
|
||||
macstr (str, evt->event_info.ap_probereqrecved.mac);
|
||||
macstr (str, ap_probereqrecved->mac);
|
||||
lua_pushstring (L, str);
|
||||
lua_setfield (L, -2, "from");
|
||||
|
||||
lua_pushinteger (L, evt->event_info.ap_probereqrecved.rssi);
|
||||
lua_pushinteger (L, ap_probereqrecved->rssi);
|
||||
lua_setfield (L, -2, "rssi");
|
||||
}
|
||||
|
||||
static void on_event (const system_event_t *evt)
|
||||
static void on_event (esp_event_base_t base, int32_t id, const void *data)
|
||||
{
|
||||
int idx = wifi_event_idx_by_id (events, ARRAY_LEN(events), evt->event_id);
|
||||
int idx = wifi_event_idx_by_id (events, ARRAY_LEN(events), base, id);
|
||||
if (idx < 0 || event_cb[idx] == LUA_NOREF)
|
||||
return;
|
||||
|
||||
|
@ -105,15 +112,15 @@ static void on_event (const system_event_t *evt)
|
|||
lua_rawgeti (L, LUA_REGISTRYINDEX, event_cb[idx]);
|
||||
lua_pushstring (L, events[idx].name);
|
||||
lua_createtable (L, 0, 5);
|
||||
events[idx].fill_cb_arg (L, evt);
|
||||
events[idx].fill_cb_arg (L, data);
|
||||
lua_call (L, 2, 0);
|
||||
}
|
||||
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_START, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_STOP, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_STACONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_STADISCONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_PROBEREQRECVED, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_AP_START, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_AP_STOP, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_AP_STACONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_AP_STADISCONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_AP_PROBEREQRECVED, on_event);
|
||||
|
||||
void wifi_ap_init (void)
|
||||
{
|
||||
|
|
|
@ -51,10 +51,10 @@ int wifi_event_idx_by_name (const event_desc_t *table, unsigned n, const char *n
|
|||
return -1;
|
||||
}
|
||||
|
||||
int wifi_event_idx_by_id (const event_desc_t *table, unsigned n, system_event_id_t id)
|
||||
int wifi_event_idx_by_id (const event_desc_t *table, unsigned n, esp_event_base_t base, int32_t id)
|
||||
{
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
if (table[i].event_id == id)
|
||||
if (*table[i].event_base_ptr == base && table[i].event_id == id)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "lua.h"
|
||||
|
||||
// Shared sta/ap macros
|
||||
|
@ -51,18 +52,19 @@
|
|||
|
||||
// Shared event handling support
|
||||
|
||||
typedef void (*fill_cb_arg_fn) (lua_State *L, const system_event_t *evt);
|
||||
typedef void (*fill_cb_arg_fn) (lua_State *L, const void *data);
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
system_event_id_t event_id;
|
||||
esp_event_base_t *event_base_ptr;
|
||||
int32_t event_id;
|
||||
fill_cb_arg_fn fill_cb_arg;
|
||||
} event_desc_t;
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
int wifi_event_idx_by_name (const event_desc_t *table, unsigned n, const char *name);
|
||||
int wifi_event_idx_by_id (const event_desc_t *table, unsigned n, system_event_id_t id);
|
||||
int wifi_event_idx_by_id (const event_desc_t *table, unsigned n, esp_event_base_t base, int32_t id);
|
||||
|
||||
int wifi_on (lua_State *L, const event_desc_t *table, unsigned n, int *event_cb);
|
||||
|
||||
|
|
|
@ -43,93 +43,96 @@
|
|||
#include "nodemcu_esp_event.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "lwip/ip_addr.h"
|
||||
|
||||
static int scan_cb_ref = LUA_NOREF;
|
||||
|
||||
// --- Event handling -----------------------------------------------------
|
||||
|
||||
static void sta_conn (lua_State *L, const system_event_t *evt);
|
||||
static void sta_disconn (lua_State *L, const system_event_t *evt);
|
||||
static void sta_authmode (lua_State *L, const system_event_t *evt);
|
||||
static void sta_got_ip (lua_State *L, const system_event_t *evt);
|
||||
static void empty_arg (lua_State *L, const system_event_t *evt) {}
|
||||
static void sta_conn (lua_State *L, const void *data);
|
||||
static void sta_disconn (lua_State *L, const void *data);
|
||||
static void sta_authmode (lua_State *L, const void *data);
|
||||
static void sta_got_ip (lua_State *L, const void *data);
|
||||
static void empty_arg (lua_State *L, const void *data) {}
|
||||
|
||||
static const event_desc_t events[] =
|
||||
{
|
||||
{ "start", SYSTEM_EVENT_STA_START, empty_arg },
|
||||
{ "stop", SYSTEM_EVENT_STA_STOP, empty_arg },
|
||||
{ "connected", SYSTEM_EVENT_STA_CONNECTED, sta_conn },
|
||||
{ "disconnected", SYSTEM_EVENT_STA_DISCONNECTED, sta_disconn },
|
||||
{ "authmode_changed", SYSTEM_EVENT_STA_AUTHMODE_CHANGE, sta_authmode },
|
||||
{ "got_ip", SYSTEM_EVENT_STA_GOT_IP, sta_got_ip },
|
||||
{ "start", &WIFI_EVENT, WIFI_EVENT_STA_START, empty_arg},
|
||||
{ "stop", &WIFI_EVENT, WIFI_EVENT_STA_STOP, empty_arg},
|
||||
{ "connected", &WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, sta_conn },
|
||||
{ "disconnected", &WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, sta_disconn },
|
||||
{ "authmode_changed", &WIFI_EVENT, WIFI_EVENT_STA_AUTHMODE_CHANGE, sta_authmode },
|
||||
{ "got_ip", &IP_EVENT, IP_EVENT_STA_GOT_IP, sta_got_ip},
|
||||
};
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
static int event_cb[ARRAY_LEN(events)];
|
||||
|
||||
static void sta_conn (lua_State *L, const system_event_t *evt)
|
||||
static void sta_conn (lua_State *L, const void *data)
|
||||
{
|
||||
lua_pushlstring (L,
|
||||
(const char *)evt->event_info.connected.ssid,
|
||||
evt->event_info.connected.ssid_len);
|
||||
const wifi_event_sta_connected_t *connected =
|
||||
(const wifi_event_sta_connected_t *)data;
|
||||
lua_pushlstring (L, (const char *)connected->ssid, connected->ssid_len);
|
||||
lua_setfield (L, -2, "ssid");
|
||||
|
||||
char bssid_str[MAC_STR_SZ];
|
||||
macstr (bssid_str, evt->event_info.connected.bssid);
|
||||
macstr (bssid_str, connected->bssid);
|
||||
lua_pushstring (L, bssid_str);
|
||||
lua_setfield (L, -2, "bssid");
|
||||
|
||||
lua_pushinteger (L, evt->event_info.connected.channel);
|
||||
lua_pushinteger (L, connected->channel);
|
||||
lua_setfield (L, -2, "channel");
|
||||
|
||||
lua_pushinteger (L, evt->event_info.connected.authmode);
|
||||
lua_pushinteger (L, connected->authmode);
|
||||
lua_setfield (L, -2, "auth");
|
||||
}
|
||||
|
||||
static void sta_disconn (lua_State *L, const system_event_t *evt)
|
||||
static void sta_disconn (lua_State *L, const void *data)
|
||||
{
|
||||
lua_pushlstring (L,
|
||||
(const char *)evt->event_info.disconnected.ssid,
|
||||
evt->event_info.disconnected.ssid_len);
|
||||
const wifi_event_sta_disconnected_t *disconnected =
|
||||
(const wifi_event_sta_disconnected_t *)data;
|
||||
lua_pushlstring (L, (const char *)disconnected->ssid, disconnected->ssid_len);
|
||||
lua_setfield (L, -2, "ssid");
|
||||
|
||||
char bssid_str[MAC_STR_SZ];
|
||||
macstr (bssid_str, evt->event_info.disconnected.bssid);
|
||||
macstr(bssid_str, disconnected->bssid);
|
||||
lua_pushstring (L, bssid_str);
|
||||
lua_setfield (L, -2, "bssid");
|
||||
|
||||
lua_pushinteger (L, evt->event_info.disconnected.reason);
|
||||
lua_pushinteger (L, disconnected->reason);
|
||||
lua_setfield (L, -2, "reason");
|
||||
}
|
||||
|
||||
static void sta_authmode (lua_State *L, const system_event_t *evt)
|
||||
static void sta_authmode (lua_State *L, const void *data)
|
||||
{
|
||||
lua_pushinteger (L, evt->event_info.auth_change.old_mode);
|
||||
const wifi_event_sta_authmode_change_t *auth_change =
|
||||
(const wifi_event_sta_authmode_change_t *)data;
|
||||
lua_pushinteger (L, auth_change->old_mode);
|
||||
lua_setfield (L, -2, "old_mode");
|
||||
lua_pushinteger (L, evt->event_info.auth_change.new_mode);
|
||||
lua_pushinteger (L, auth_change->new_mode);
|
||||
lua_setfield (L, -2, "new_mode");
|
||||
}
|
||||
|
||||
static void sta_got_ip (lua_State *L, const system_event_t *evt)
|
||||
static void sta_got_ip (lua_State *L, const void *data)
|
||||
{
|
||||
const esp_netif_ip_info_t *ip_info =
|
||||
(const esp_netif_ip_info_t *)data;
|
||||
|
||||
char ipstr[IP_STR_SZ] = { 0 };
|
||||
ip4str (ipstr, &evt->event_info.got_ip.ip_info.ip);
|
||||
ip4str_esp (ipstr, &ip_info->ip);
|
||||
lua_pushstring (L, ipstr);
|
||||
lua_setfield (L, -2, "ip");
|
||||
|
||||
ip4str (ipstr, &evt->event_info.got_ip.ip_info.netmask);
|
||||
ip4str_esp (ipstr, &ip_info->netmask);
|
||||
lua_pushstring (L, ipstr);
|
||||
lua_setfield (L, -2, "netmask");
|
||||
|
||||
ip4str (ipstr, &evt->event_info.got_ip.ip_info.gw);
|
||||
ip4str_esp (ipstr, &ip_info->gw);
|
||||
lua_pushstring (L, ipstr);
|
||||
lua_setfield (L, -2, "gw");
|
||||
}
|
||||
|
||||
static void on_event (const system_event_t *evt)
|
||||
static void on_event (esp_event_base_t base, int32_t id, const void *data)
|
||||
{
|
||||
int idx = wifi_event_idx_by_id (events, ARRAY_LEN(events), evt->event_id);
|
||||
int idx = wifi_event_idx_by_id (events, ARRAY_LEN(events), base, id);
|
||||
if (idx < 0 || event_cb[idx] == LUA_NOREF)
|
||||
return;
|
||||
|
||||
|
@ -137,16 +140,17 @@ static void on_event (const system_event_t *evt)
|
|||
lua_rawgeti (L, LUA_REGISTRYINDEX, event_cb[idx]);
|
||||
lua_pushstring (L, events[idx].name);
|
||||
lua_createtable (L, 0, 5);
|
||||
events[idx].fill_cb_arg (L, evt);
|
||||
events[idx].fill_cb_arg (L, data);
|
||||
lua_call (L, 2, 0);
|
||||
}
|
||||
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_START, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_STOP, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_CONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_DISCONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_AUTHMODE_CHANGE, on_event);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_GOT_IP, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_START, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_STOP, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, on_event);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_AUTHMODE_CHANGE, on_event);
|
||||
NODEMCU_ESP_EVENT(IP_EVENT, IP_EVENT_STA_GOT_IP, on_event);
|
||||
// TODO: support WPS events?
|
||||
|
||||
void wifi_sta_init (void)
|
||||
{
|
||||
|
@ -158,9 +162,9 @@ void wifi_sta_init (void)
|
|||
// --- Helper functions -----------------------------------------------------
|
||||
|
||||
|
||||
static void do_connect (const system_event_t *evt)
|
||||
static void do_connect (esp_event_base_t base, int32_t id, const void *data)
|
||||
{
|
||||
(void)evt;
|
||||
(void)base; (void)id; (void)data;
|
||||
esp_wifi_connect ();
|
||||
}
|
||||
|
||||
|
@ -355,9 +359,9 @@ static int wifi_sta_getmac (lua_State *L)
|
|||
return wifi_getmac(WIFI_IF_STA, L);
|
||||
}
|
||||
|
||||
static void on_scan_done (const system_event_t *evt)
|
||||
static void on_scan_done(esp_event_base_t base, int32_t id, const void *data)
|
||||
{
|
||||
(void)evt;
|
||||
(void)data;
|
||||
|
||||
lua_State *L = lua_getstate ();
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, scan_cb_ref);
|
||||
|
@ -470,7 +474,7 @@ LROT_END(wifi_sta, NULL, 0)
|
|||
|
||||
|
||||
// Currently no auto-connect, so do that in response to events
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_START, do_connect);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_DISCONNECTED, do_connect);
|
||||
NODEMCU_ESP_EVENT(SYSTEM_EVENT_SCAN_DONE, on_scan_done);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_START, do_connect);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, do_connect);
|
||||
NODEMCU_ESP_EVENT(WIFI_EVENT, WIFI_EVENT_SCAN_DONE, on_scan_done);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue