666 lines
21 KiB
C++
666 lines
21 KiB
C++
/*
|
|
; Project: Open Vehicle Monitor System
|
|
; Date: 14th March 2017
|
|
;
|
|
; Changes:
|
|
; 1.0 Initial release
|
|
;
|
|
; (C) 2011 Michael Stegen / Stegen Electronics
|
|
; (C) 2011-2017 Mark Webb-Johnson
|
|
; (C) 2011 Sonny Chen @ EPRO/DX
|
|
;
|
|
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
; of this software and associated documentation files (the "Software"), to deal
|
|
; in the Software without restriction, including without limitation the rights
|
|
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
; copies of the Software, and to permit persons to whom the Software is
|
|
; furnished to do so, subject to the following conditions:
|
|
;
|
|
; The above copyright notice and this permission notice shall be included in
|
|
; all copies or substantial portions of the Software.
|
|
;
|
|
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
; THE SOFTWARE.
|
|
*/
|
|
|
|
#include "ovms_log.h"
|
|
static const char *TAG = "events";
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <esp_event_loop.h>
|
|
#include <esp_task_wdt.h>
|
|
#include "ovms_module.h"
|
|
#include "ovms_events.h"
|
|
#include "ovms_command.h"
|
|
#include "ovms_script.h"
|
|
#include "ovms_boot.h"
|
|
|
|
#ifdef CONFIG_OVMS_COMP_OTA
|
|
#include "ovms_ota.h"
|
|
#endif
|
|
|
|
OvmsEvents MyEvents __attribute__ ((init_priority (1200)));
|
|
|
|
typedef void (*event_signal_done_fn)(const char* event, void* data);
|
|
|
|
bool EventMap::GetCompletion(OvmsWriter* writer, const char* token) const
|
|
{
|
|
unsigned int index = 0;
|
|
bool match = false;
|
|
writer->SetCompletion(index, NULL);
|
|
if (token)
|
|
{
|
|
size_t len = strlen(token);
|
|
for (const_iterator it = begin(); it != end(); ++it)
|
|
{
|
|
if (it->first.compare("*") == 0)
|
|
continue;
|
|
if (it->first.compare(0, len, token) == 0)
|
|
{
|
|
writer->SetCompletion(index++, it->first.c_str());
|
|
match = true;
|
|
}
|
|
}
|
|
}
|
|
return match;
|
|
}
|
|
|
|
void EventStdFree(const char* event, void* data)
|
|
{
|
|
free(data);
|
|
}
|
|
|
|
void EventLaunchTask(void *pvParameters)
|
|
{
|
|
OvmsEvents* me = (OvmsEvents*)pvParameters;
|
|
|
|
me->EventTask();
|
|
}
|
|
|
|
void event_trace(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv)
|
|
{
|
|
if (strcmp(cmd->GetName(),"on")==0)
|
|
MyEvents.m_trace = true;
|
|
else
|
|
MyEvents.m_trace = false;
|
|
|
|
writer->printf("Event tracing is now %s\n",cmd->GetName());
|
|
}
|
|
|
|
void event_status(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv)
|
|
{
|
|
writer->printf("Event map has %d listeners, and queue has %d/%d entries\n",
|
|
MyEvents.Map().size(),
|
|
uxQueueMessagesWaiting(MyEvents.m_taskqueue),
|
|
CONFIG_OVMS_HW_EVENT_QUEUE_SIZE);
|
|
|
|
EventCallbackEntry* cbe = MyEvents.m_current_callback;
|
|
if (cbe != NULL)
|
|
{
|
|
writer->printf("Currently dispatching:\n");
|
|
writer->printf(" Event: %s\n",MyEvents.m_current_event.c_str());
|
|
writer->printf(" To: %s\n",cbe->m_caller.c_str());
|
|
writer->printf(" For: %u second(s)\n",monotonictime-MyEvents.m_current_started);
|
|
}
|
|
}
|
|
|
|
void event_list(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv)
|
|
{
|
|
std::string event;
|
|
for (EventMap::const_iterator itm=MyEvents.Map().begin(); itm != MyEvents.Map().end(); ++itm)
|
|
{
|
|
if (argc > 0 && itm->first.find(argv[0]) == std::string::npos)
|
|
continue;
|
|
event.append(itm->first);
|
|
event.append(": ");
|
|
EventCallbackList* el = itm->second;
|
|
for (EventCallbackList::iterator itc=el->begin(); itc!=el->end(); )
|
|
{
|
|
EventCallbackEntry* ec = *itc;
|
|
event.append(ec->m_caller);
|
|
if (++itc != el->end())
|
|
event.append(", ");
|
|
}
|
|
event.append("\n");
|
|
}
|
|
writer->printf("%s", event.c_str());
|
|
}
|
|
|
|
int event_validate(OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv, bool complete)
|
|
{
|
|
int argpos = 0;
|
|
for (int i=0; i < argc; i++)
|
|
argpos += (argv[i][0] != '-') ? 1 : 0;
|
|
if (argpos == 1 && MyEvents.Map().GetCompletion(writer, argv[argc-1]))
|
|
return argc;
|
|
return -1;
|
|
}
|
|
|
|
void event_raise(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv)
|
|
{
|
|
std::string event;
|
|
uint32_t delay_ms = 0;
|
|
|
|
for (int i=0; i<argc; i++)
|
|
{
|
|
if (argv[i][0] == '-')
|
|
{
|
|
if (argv[i][1] != 'd')
|
|
{
|
|
cmd->PutUsage(writer);
|
|
return;
|
|
}
|
|
delay_ms = atol(argv[i]+2);
|
|
}
|
|
else
|
|
event = argv[i];
|
|
}
|
|
|
|
if (delay_ms)
|
|
{
|
|
writer->printf("Raising event in %u ms: %s\n", delay_ms, event.c_str());
|
|
MyEvents.SignalEvent(event, NULL, (size_t)0, delay_ms);
|
|
}
|
|
else
|
|
{
|
|
writer->printf("Raising event: %s\n", event.c_str());
|
|
MyEvents.SignalEvent(event, NULL);
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_OVMS_SC_JAVASCRIPT_DUKTAPE
|
|
|
|
static duk_ret_t DukOvmsRaiseEvent(duk_context *ctx)
|
|
{
|
|
const char *event = duk_to_string(ctx,0);
|
|
uint32_t delay_ms = duk_is_number(ctx,1) ? duk_to_uint32(ctx,1) : 0;
|
|
|
|
if (event != NULL)
|
|
{
|
|
MyEvents.SignalEvent(event, NULL, (size_t)0, delay_ms);
|
|
}
|
|
return 0; /* no return value */
|
|
}
|
|
|
|
#endif // #ifdef CONFIG_OVMS_SC_JAVASCRIPT_DUKTAPE
|
|
|
|
OvmsEvents::OvmsEvents()
|
|
{
|
|
ESP_LOGI(TAG, "Initialising EVENTS (1200)");
|
|
|
|
m_current_callback = NULL;
|
|
|
|
#ifdef CONFIG_OVMS_DEV_DEBUGEVENTS
|
|
m_trace = true;
|
|
#else
|
|
m_trace = false;
|
|
#endif // #ifdef CONFIG_OVMS_DEV_DEBUGEVENTS
|
|
|
|
ESP_ERROR_CHECK(esp_event_loop_init(ReceiveSystemEvent, (void*)this));
|
|
|
|
// Register our commands
|
|
OvmsCommand* cmd_event = MyCommandApp.RegisterCommand("event","EVENT framework", event_status, "", 0, 0, false);
|
|
cmd_event->RegisterCommand("status","Show status of event system",event_status);
|
|
cmd_event->RegisterCommand("list","List registered events",event_list,"[<key>]", 0, 1);
|
|
cmd_event->RegisterCommand("raise","Raise a textual event",event_raise,"[-d<delay_ms>] <event>", 1, 2, true, event_validate);
|
|
OvmsCommand* cmd_eventtrace = cmd_event->RegisterCommand("trace","EVENT trace framework");
|
|
cmd_eventtrace->RegisterCommand("on","Turn event tracing ON",event_trace);
|
|
cmd_eventtrace->RegisterCommand("off","Turn event tracing OFF",event_trace);
|
|
|
|
m_taskqueue = xQueueCreate(CONFIG_OVMS_HW_EVENT_QUEUE_SIZE,sizeof(event_queue_t));
|
|
xTaskCreatePinnedToCore(EventLaunchTask, "OVMS Events", 8192, (void*)this, 8, &m_taskid, CORE(1));
|
|
AddTaskToMap(m_taskid);
|
|
|
|
#ifdef CONFIG_OVMS_SC_JAVASCRIPT_DUKTAPE
|
|
DuktapeObjectRegistration* dto = new DuktapeObjectRegistration("OvmsEvents");
|
|
dto->RegisterDuktapeFunction(DukOvmsRaiseEvent, 2, "Raise");
|
|
MyDuktape.RegisterDuktapeObject(dto);
|
|
#endif // #ifdef CONFIG_OVMS_SC_JAVASCRIPT_DUKTAPE
|
|
}
|
|
|
|
OvmsEvents::~OvmsEvents()
|
|
{
|
|
}
|
|
|
|
void OvmsEvents::EventTask()
|
|
{
|
|
event_queue_t msg;
|
|
|
|
esp_task_wdt_add(NULL); // WATCHDOG is active for this task
|
|
while(1)
|
|
{
|
|
if (xQueueReceive(m_taskqueue, &msg, pdMS_TO_TICKS(5000)) == pdTRUE)
|
|
{
|
|
esp_task_wdt_reset(); // Reset WATCHDOG timer for this task
|
|
switch(msg.type)
|
|
{
|
|
case EVENT_none:
|
|
break;
|
|
case EVENT_signal:
|
|
m_current_event = msg.body.signal.event;
|
|
HandleQueueSignalEvent(&msg);
|
|
esp_task_wdt_reset(); // Reset WATCHDOG timer for this task
|
|
m_current_event.clear();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifdef CONFIG_OVMS_COMP_OTA
|
|
// Timeout on xQueueReceive: ignore during OTA flash job:
|
|
OvmsMutexLock m_lock(&MyOTA.m_flashing, 0);
|
|
if (!m_lock.IsLocked())
|
|
continue;
|
|
#endif
|
|
// …no OTA flashing in progress => abort:
|
|
ESP_LOGE(TAG, "EventTask: [QueueTimeout] timer service / ticker timer has died => aborting");
|
|
m_current_event = "[QueueTimeout]";
|
|
m_current_started = monotonictime - 5;
|
|
MyCommandApp.CloseLogfile();
|
|
vTaskDelay(pdMS_TO_TICKS(100));
|
|
abort();
|
|
}
|
|
}
|
|
}
|
|
|
|
void OvmsEvents::HandleQueueSignalEvent(event_queue_t* msg)
|
|
{
|
|
// Log everything but the ticker & clock signals
|
|
if (!startsWith(m_current_event, "ticker.") && !startsWith(m_current_event, "clock."))
|
|
{
|
|
if (m_trace)
|
|
ESP_LOGI(TAG, "Signal(%s)",m_current_event.c_str());
|
|
else
|
|
ESP_LOGD(TAG, "Signal(%s)",m_current_event.c_str());
|
|
}
|
|
|
|
auto k = m_map.find(m_current_event);
|
|
if (k != m_map.end())
|
|
{
|
|
EventCallbackList* el = k->second;
|
|
if (el)
|
|
{
|
|
for (EventCallbackList::iterator itc=el->begin(); itc!=el->end(); ++itc)
|
|
{
|
|
m_current_started = monotonictime;
|
|
m_current_callback = *itc;
|
|
m_current_callback->m_callback(m_current_event, msg->body.signal.data);
|
|
m_current_callback = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
k = m_map.find("*");
|
|
if (k != m_map.end())
|
|
{
|
|
EventCallbackList* el = k->second;
|
|
if (el)
|
|
{
|
|
for (EventCallbackList::iterator itc=el->begin(); itc!=el->end(); ++itc)
|
|
{
|
|
m_current_started = monotonictime;
|
|
m_current_callback = *itc;
|
|
m_current_callback->m_callback(m_current_event, msg->body.signal.data);
|
|
m_current_callback = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_current_started = monotonictime;
|
|
MyScripts.EventScript(m_current_event, msg->body.signal.data);
|
|
|
|
FreeQueueSignalEvent(msg);
|
|
}
|
|
|
|
void OvmsEvents::FreeQueueSignalEvent(event_queue_t* msg)
|
|
{
|
|
if (msg->body.signal.donefn != NULL)
|
|
{
|
|
msg->body.signal.donefn(msg->body.signal.event, msg->body.signal.data);
|
|
}
|
|
free(msg->body.signal.event);
|
|
}
|
|
|
|
void OvmsEvents::RegisterEvent(std::string caller, std::string event, EventCallback callback)
|
|
{
|
|
auto k = m_map.find(event);
|
|
if (k == m_map.end())
|
|
{
|
|
m_map[event] = new EventCallbackList();
|
|
k = m_map.find(event);
|
|
}
|
|
if (k == m_map.end())
|
|
{
|
|
ESP_LOGE(TAG, "Problem registering event %s for caller %s",event.c_str(),caller.c_str());
|
|
return;
|
|
}
|
|
|
|
EventCallbackList *el = k->second;
|
|
el->push_back(new EventCallbackEntry(caller,callback));
|
|
}
|
|
|
|
void OvmsEvents::DeregisterEvent(std::string caller)
|
|
{
|
|
EventMap::iterator itm=m_map.begin();
|
|
while (itm!=m_map.end())
|
|
{
|
|
EventCallbackList* el = itm->second;
|
|
EventCallbackList::iterator itc=el->begin();
|
|
while (itc!=el->end())
|
|
{
|
|
EventCallbackEntry* ec = *itc;
|
|
if (ec->m_caller == caller)
|
|
{
|
|
itc = el->erase(itc);
|
|
delete ec;
|
|
}
|
|
else
|
|
{
|
|
++itc;
|
|
}
|
|
}
|
|
if (el->empty())
|
|
{
|
|
itm = m_map.erase(itm);
|
|
delete el;
|
|
}
|
|
else
|
|
{
|
|
++itm;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CheckQueueOverflow(const char* from, char* event)
|
|
{
|
|
EventCallbackEntry* cbe = MyEvents.m_current_callback;
|
|
if (cbe != NULL)
|
|
{
|
|
ESP_LOGE(TAG, "%s: queue overflow (running %s->%s for %u sec), event '%s' dropped",
|
|
from,
|
|
MyEvents.m_current_event.c_str(),
|
|
cbe->m_caller.c_str(),
|
|
monotonictime-MyEvents.m_current_started,
|
|
event);
|
|
}
|
|
else
|
|
{
|
|
ESP_LOGE(TAG, "%s: queue overflow, event '%s' dropped", from, event);
|
|
}
|
|
if (strncmp(event, "ticker.", 7) != 0)
|
|
{
|
|
// We've dropped a potentially important event, system is instable now.
|
|
// As the event queue is full, a normal reboot is no option, so…
|
|
#ifdef CONFIG_OVMS_COMP_OTA
|
|
// …wait for a running OTA job to finish…
|
|
OvmsMutexLock m_lock(&MyOTA.m_flashing);
|
|
#endif
|
|
// …then abort:
|
|
ESP_LOGE(TAG, "%s: lost important event => aborting", from);
|
|
MyCommandApp.CloseLogfile();
|
|
vTaskDelay(pdMS_TO_TICKS(100));
|
|
abort();
|
|
}
|
|
}
|
|
|
|
void OvmsEvents::SignalScheduledEvent(TimerHandle_t timer)
|
|
{
|
|
OvmsMutexLock lock(&MyEvents.m_timers_mutex);
|
|
|
|
// retrieve timer payload message (event):
|
|
event_queue_t* msg = (event_queue_t*) pvTimerGetTimerID(timer);
|
|
vTimerSetTimerID(timer, NULL);
|
|
if (!msg)
|
|
{
|
|
// This should no longer happen, but keeping the test doesn't hurt.
|
|
// See: https://github.com/espressif/esp-idf/issues/8234
|
|
ESP_LOGW(TAG, "SignalScheduledEvent: duplicate callback invocation detected");
|
|
return;
|
|
}
|
|
|
|
// … and pass on to event task:
|
|
if (xQueueSend(MyEvents.m_taskqueue, msg, 0) != pdTRUE)
|
|
{
|
|
CheckQueueOverflow("SignalScheduledEvent", msg->body.signal.event);
|
|
MyEvents.FreeQueueSignalEvent(msg);
|
|
}
|
|
|
|
delete msg;
|
|
MyEvents.m_timer_active[timer] = false;
|
|
}
|
|
|
|
bool OvmsEvents::ScheduleEvent(event_queue_t* msg, uint32_t delay_ms)
|
|
{
|
|
OvmsMutexLock lock(&m_timers_mutex);
|
|
TimerHandle_t timer;
|
|
TimerList::iterator it;
|
|
event_queue_t *msgdup = new event_queue_t(*msg);
|
|
int timerticks = pdMS_TO_TICKS(delay_ms); if (timerticks<1) timerticks=1;
|
|
|
|
if (!msgdup)
|
|
{
|
|
ESP_LOGE(TAG, "ScheduleEvent: message duplication failed, event dropped");
|
|
return false;
|
|
}
|
|
|
|
// find available timer:
|
|
for (it = m_timers.begin(); it != m_timers.end(); it++)
|
|
{
|
|
timer = *it;
|
|
// Note: xTimerIsTimerActive() must not be used here, it has a
|
|
// multicore race condition with FreeRTOS V8.2.0 (esp-idf 3.3):
|
|
// an expired timer is removed from the active list before its
|
|
// callback is executed, so while the callback is running, the
|
|
// timer already appears to be free. Workaround is to use our
|
|
// own timer status map:
|
|
if (!m_timer_active[timer])
|
|
break;
|
|
}
|
|
if (it == m_timers.end())
|
|
{
|
|
// create & register a new timer:
|
|
ESP_LOGI(TAG, "ScheduleEvent: creating new timer");
|
|
timer = xTimerCreate("ScheduleEvent", timerticks, pdFALSE, NULL, SignalScheduledEvent);
|
|
if (!timer)
|
|
{
|
|
ESP_LOGE(TAG, "ScheduleEvent: xTimerCreate failed, event dropped");
|
|
delete msgdup;
|
|
return false;
|
|
}
|
|
m_timers.push_back(timer);
|
|
m_timer_active[timer] = false;
|
|
}
|
|
|
|
// set payload, update & start the timer:
|
|
vTimerSetTimerID(timer, msgdup);
|
|
if (xTimerChangePeriod(timer, timerticks, 0) != pdPASS) // also starts the timer
|
|
{
|
|
ESP_LOGE(TAG, "ScheduleEvent: xTimerChangePeriod failed, event dropped");
|
|
vTimerSetTimerID(timer, NULL);
|
|
delete msgdup;
|
|
return false;
|
|
}
|
|
|
|
m_timer_active[timer] = true;
|
|
return true;
|
|
}
|
|
|
|
void OvmsEvents::SignalEvent(std::string event, void* data, event_signal_done_fn callback /*=NULL*/,
|
|
uint32_t delay_ms /*=0*/)
|
|
{
|
|
event_queue_t msg;
|
|
memset(&msg, 0, sizeof(msg));
|
|
|
|
msg.type = EVENT_signal;
|
|
msg.body.signal.event = (char*)ExternalRamMalloc(event.size()+1);
|
|
strcpy(msg.body.signal.event, event.c_str());
|
|
msg.body.signal.data = data;
|
|
msg.body.signal.donefn = callback;
|
|
|
|
if (delay_ms == 0)
|
|
{
|
|
if (xQueueSend(m_taskqueue, &msg, 0) != pdTRUE)
|
|
{
|
|
CheckQueueOverflow("SignalEvent", msg.body.signal.event);
|
|
FreeQueueSignalEvent(&msg);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ScheduleEvent(&msg, delay_ms) != true)
|
|
{
|
|
ESP_LOGE(TAG, "SignalEvent: no timer available, event '%s' dropped", msg.body.signal.event);
|
|
FreeQueueSignalEvent(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OvmsEvents::SignalEvent(std::string event, void* data, size_t length,
|
|
uint32_t delay_ms /*=0*/)
|
|
{
|
|
event_queue_t msg;
|
|
memset(&msg, 0, sizeof(msg));
|
|
|
|
msg.type = EVENT_signal;
|
|
msg.body.signal.event = (char*)ExternalRamMalloc(event.size()+1);
|
|
strcpy(msg.body.signal.event, event.c_str());
|
|
if (data != NULL)
|
|
{
|
|
msg.body.signal.data = ExternalRamMalloc(length);
|
|
memcpy(msg.body.signal.data, data, length);
|
|
msg.body.signal.donefn = EventStdFree;
|
|
}
|
|
else
|
|
{
|
|
msg.body.signal.data = NULL;
|
|
msg.body.signal.donefn = NULL;
|
|
}
|
|
|
|
if (delay_ms == 0)
|
|
{
|
|
if (xQueueSend(m_taskqueue, &msg, 0) != pdTRUE)
|
|
{
|
|
CheckQueueOverflow("SignalEvent", msg.body.signal.event);
|
|
FreeQueueSignalEvent(&msg);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ScheduleEvent(&msg, delay_ms) != true)
|
|
{
|
|
ESP_LOGE(TAG, "SignalEvent: no timer available, event '%s' dropped", msg.body.signal.event);
|
|
FreeQueueSignalEvent(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
esp_err_t OvmsEvents::ReceiveSystemEvent(void *ctx, system_event_t *event)
|
|
{
|
|
OvmsEvents* e = (OvmsEvents*)ctx;
|
|
e->SignalEvent("system.event",(void*)event,sizeof(system_event_t));
|
|
e->SignalSystemEvent(event);
|
|
return ESP_OK;
|
|
}
|
|
|
|
void OvmsEvents::SignalSystemEvent(system_event_t *event)
|
|
{
|
|
switch (event->event_id)
|
|
{
|
|
case SYSTEM_EVENT_WIFI_READY: // ESP32 WiFi ready
|
|
SignalEvent("system.wifi.ready",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_SCAN_DONE: // ESP32 finish scanning AP
|
|
SignalEvent("system.wifi.scan.done",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_START: // ESP32 station start
|
|
SignalEvent("system.wifi.sta.start",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_STOP: // ESP32 station stop
|
|
SignalEvent("system.wifi.sta.stop",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_CONNECTED: // ESP32 station connected to AP
|
|
SignalEvent("system.wifi.sta.connected",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_DISCONNECTED: // ESP32 station disconnected from AP
|
|
SignalEvent("system.wifi.sta.disconnected",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: // the auth mode of AP connected by ESP32 station changed
|
|
SignalEvent("system.wifi.sta.authmodechange",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_GOT_IP: // ESP32 station got IP from connected AP
|
|
SignalEvent("network.interface.up", NULL);
|
|
SignalEvent("system.wifi.sta.gotip",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_LOST_IP: // ESP32 station lost IP and the IP is reset to 0
|
|
SignalEvent("system.wifi.sta.lostip",(void*)&event->event_info);
|
|
break;
|
|
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS: // ESP32 station wps succeeds in enrollee mode
|
|
SignalEvent("system.wifi.sta.wpser.success",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_WPS_ER_FAILED: // ESP32 station wps fails in enrollee mode
|
|
SignalEvent("system.wifi.sta.wpser.failed",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT: // ESP32 station wps timeout in enrollee mode
|
|
SignalEvent("system.wifi.sta.wpser.timeout",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_STA_WPS_ER_PIN: // ESP32 station wps pin code in enrollee mode
|
|
SignalEvent("system.wifi.sta.wpser.pin",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_AP_START: // ESP32 soft-AP start
|
|
SignalEvent("system.wifi.ap.start",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_AP_STOP: // ESP32 soft-AP stop
|
|
SignalEvent("system.wifi.ap.stop",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_AP_STACONNECTED: // a station connected to ESP32 soft-AP
|
|
SignalEvent("system.wifi.ap.sta.connected",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_AP_STADISCONNECTED: // a station disconnected from ESP32 soft-AP
|
|
SignalEvent("system.wifi.ap.sta.disconnected",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_AP_STAIPASSIGNED: // ESP32 soft-AP assigned an IP to a connected station
|
|
SignalEvent("system.wifi.ap.sta.ipassigned",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_AP_PROBEREQRECVED: // Receive probe request packet in soft-AP interface
|
|
SignalEvent("system.wifi.ap.proberx",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_AP_STA_GOT_IP6: // ESP32 station or ap interface v6IP addr is preferred
|
|
SignalEvent("system.wifi.ap.sta.gotip6",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_ETH_START: // ESP32 ethernet start
|
|
SignalEvent("system.eth.start",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_ETH_STOP: // ESP32 ethernet stop
|
|
SignalEvent("system.eth.stop",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_ETH_CONNECTED: // ESP32 ethernet phy link up
|
|
SignalEvent("system.eth.connected",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_ETH_DISCONNECTED: // ESP32 ethernet phy link down
|
|
SignalEvent("system.eth.disconnected",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
case SYSTEM_EVENT_ETH_GOT_IP: // ESP32 ethernet got IP from connected AP
|
|
SignalEvent("system.eth.gotip",(void*)&event->event_info,sizeof(event->event_info));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
EventCallbackEntry::EventCallbackEntry(std::string caller, EventCallback callback)
|
|
{
|
|
m_caller = caller;
|
|
m_callback = callback;
|
|
}
|
|
|
|
EventCallbackEntry::~EventCallbackEntry()
|
|
{
|
|
}
|