diff --git a/README.md b/README.md index 9c64963..1662982 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ SPI | ❌ | ❌ Wire | ❗ | ❌ **OTHER LIBRARIES** | | Wi-Fi STA/AP/Mixed | ✔️ | ✔️ -Wi-Fi Events | ✔️ | ❌ +Wi-Fi Events | ✔️ | ✔️ TCP Client (SSL) | ✔️ (✔️) | ✔️ (❗) TCP Server | ✔️ | ✔️ IPv6 | ❌ | ❌ diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiEvents.cpp b/arduino/beken-72xx/libraries/WiFi/WiFiEvents.cpp new file mode 100644 index 0000000..cdf36ee --- /dev/null +++ b/arduino/beken-72xx/libraries/WiFi/WiFiEvents.cpp @@ -0,0 +1,144 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-07-10. */ + +#include "WiFiPriv.h" + +#include + +static xQueueHandle wifiEventQueueHandle = NULL; +static xTaskHandle wifiEventTaskHandle = NULL; + +static const rw_evt_type eventConnected = RW_EVT_STA_CONNECTED; + +// callback for bk_wlan_status_register_cb() +static void wifiStatusCallback(rw_evt_type *pEvent) { + if (wifiEventQueueHandle && wifiEventTaskHandle) { + xQueueSend(wifiEventQueueHandle, pEvent, portMAX_DELAY); + } else { + wifiEventHandler(*pEvent); + } +} + +static void wifiEventTask(void *arg) { + rw_evt_type event = RW_EVT_MAX; + for (;;) { + if (xQueueReceive(wifiEventQueueHandle, &event, portMAX_DELAY) == pdTRUE) { + wifiEventHandler(event); + } + } +} + +void wifiEventSendArduino(EventId event) { + event = (EventId)(RW_EVT_ARDUINO | event); + wifiStatusCallback((rw_evt_type *)&event); +} + +void startWifiTask() { + if (!wifiEventQueueHandle) { + LT_HEAP_I(); + wifiEventQueueHandle = xQueueCreate(32, sizeof(rw_evt_type)); + LT_HEAP_I(); + } + if (!wifiEventTaskHandle) { + LT_HEAP_I(); + xTaskCreate(wifiEventTask, "wifievent", 512, NULL, 4, &wifiEventTaskHandle); + LT_HEAP_I(); + } + bk_wlan_status_register_cb((FUNC_1PARAM_PTR)wifiStatusCallback); +} + +void wifiEventHandler(rw_evt_type event) { + if (!pWiFi) + return; // failsafe + + LT_D_WG("WiFi event %u", event); + + EventId eventId; + EventInfo eventInfo; + String ssid; + + memset(&eventInfo, 0, sizeof(EventInfo)); + + switch (event) { + case RW_EVT_STA_IDLE: + eventId = ARDUINO_EVENT_WIFI_READY; + break; + + case RW_EVT_STA_BEACON_LOSE: + case RW_EVT_STA_PASSWORD_WRONG: + case RW_EVT_STA_NO_AP_FOUND: + case RW_EVT_STA_ASSOC_FULL: + case RW_EVT_STA_DISCONNECTED: + case RW_EVT_STA_CONNECT_FAILED: + eventId = ARDUINO_EVENT_WIFI_STA_DISCONNECTED; + eventInfo.wifi_sta_disconnected.ssid_len = 0; + switch (event) { + case RW_EVT_STA_BEACON_LOSE: + eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_BEACON_TIMEOUT; + break; + case RW_EVT_STA_PASSWORD_WRONG: + eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_AUTH_FAIL; + break; + case RW_EVT_STA_NO_AP_FOUND: + eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_NO_AP_FOUND; + break; + case RW_EVT_STA_ASSOC_FULL: + eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_ASSOC_TOOMANY; + break; + case RW_EVT_STA_DISCONNECTED: + eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_ASSOC_LEAVE; + break; + case RW_EVT_STA_CONNECT_FAILED: + eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_CONNECTION_FAIL; + break; + default: + eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_UNSPECIFIED; + break; + } + break; + + case RW_EVT_STA_CONNECTED: + eventId = ARDUINO_EVENT_WIFI_STA_CONNECTED; + ssid = pWiFi->SSID(); + eventInfo.wifi_sta_connected.ssid_len = ssid.length(); + eventInfo.wifi_sta_connected.channel = pWiFi->channel(); + eventInfo.wifi_sta_connected.authmode = pWiFi->getEncryption(); + memcpy(eventInfo.wifi_sta_connected.ssid, ssid.c_str(), eventInfo.wifi_sta_connected.ssid_len + 1); + memcpy(eventInfo.wifi_sta_connected.bssid, pWiFi->BSSID(), 6); + break; + + case RW_EVT_STA_GOT_IP: + eventId = ARDUINO_EVENT_WIFI_STA_GOT_IP; + eventInfo.got_ip.if_index = 0; + eventInfo.got_ip.ip_changed = true; + eventInfo.got_ip.ip_info.ip.addr = WiFi.localIP(); + eventInfo.got_ip.ip_info.netmask.addr = WiFi.subnetMask(); + eventInfo.got_ip.ip_info.gw.addr = WiFi.gatewayIP(); + break; + + case RW_EVT_AP_CONNECTED: + eventId = ARDUINO_EVENT_WIFI_AP_STACONNECTED; + // TODO station MAC + break; + + case RW_EVT_AP_DISCONNECTED: + eventId = ARDUINO_EVENT_WIFI_AP_STADISCONNECTED; + // TODO station MAC + break; + + case RW_EVT_ARDUINO | ARDUINO_EVENT_WIFI_SCAN_DONE: + eventId = ARDUINO_EVENT_WIFI_SCAN_DONE; + eventInfo.wifi_scan_done.status = 0; + if (pWiFi->scan) + eventInfo.wifi_scan_done.number = pWiFi->scan->count; + eventInfo.wifi_scan_done.scan_id = 0; + break; + + default: + if (event < RW_EVT_ARDUINO) + return; + eventId = (EventId)(event - RW_EVT_ARDUINO); + break; + } + + pWiFi->postEvent(eventId, eventInfo); +} diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp b/arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp index 332d725..6327f64 100644 --- a/arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp +++ b/arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp @@ -4,6 +4,7 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) { __wrap_bk_printf_disable(); + startWifiTask(); if (mode && !data.statusIp) { data.configSta = zalloc(sizeof(network_InitTypeDef_st)); @@ -31,9 +32,11 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) { if (sta == WLMODE_ENABLE) { LT_D_WG("Enabling STA"); bk_wlan_sta_init(NULL); + wifiEventSendArduino(ARDUINO_EVENT_WIFI_STA_START); } else if (sta == WLMODE_DISABLE) { LT_D_WG("Disabling STA"); bk_wlan_stop(BK_STATION); + wifiEventSendArduino(ARDUINO_EVENT_WIFI_STA_STOP); } LT_HEAP_I(); @@ -41,9 +44,11 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) { if (ap == WLMODE_ENABLE) { LT_D_WG("Enabling AP"); bk_wlan_ap_init(NULL); + wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_START); } else if (ap == WLMODE_DISABLE) { LT_D_WG("Disabling AP"); bk_wlan_stop(BK_SOFT_AP); + wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_STOP); } if (!mode) { diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiPriv.h b/arduino/beken-72xx/libraries/WiFi/WiFiPriv.h index 571b70b..7ac6cb8 100644 --- a/arduino/beken-72xx/libraries/WiFi/WiFiPriv.h +++ b/arduino/beken-72xx/libraries/WiFi/WiFiPriv.h @@ -40,6 +40,13 @@ extern uint8_t system_mac[6]; WiFiStatus eventTypeToStatus(uint8_t type); WiFiAuthMode securityTypeToAuthMode(uint8_t type); +// WiFiEvents.cpp +extern void wifiEventSendArduino(EventId event); +extern void startWifiTask(); +extern void wifiEventHandler(rw_evt_type event); + +#define RW_EVT_ARDUINO (1 << 7) + #define IP_FMT "%u.%u.%u.%u" #define STA_CFG ((network_InitTypeDef_st *)data.configSta) diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp b/arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp index 38877ba..1f2eff2 100644 --- a/arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp +++ b/arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp @@ -38,6 +38,8 @@ static void scanHandler(void *ctx, uint8_t param) { cls->data.scannedAt = millis(); + wifiEventSendArduino(ARDUINO_EVENT_WIFI_SCAN_DONE); + end: scan->running = false; xSemaphoreGive(cls->data.scanSem); diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp index c71133e..5d6e1c6 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp @@ -63,6 +63,9 @@ void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handl } } // extern "C" +// TODO queue handling is apparently done all wrong here +// (passing pointers to pointers in xQueueSend/xQueueReceive) + // function called by wext_wlan_indicate void wifi_indication(rtw_event_indicate_t event, char *buf, int buf_len, int flags) { LT_HEAP_I(); @@ -104,7 +107,7 @@ static void wifiEventTask(void *arg) { void startWifiTask() { if (!wifiEventQueueHandle) { LT_HEAP_I(); - wifiEventQueueHandle = xQueueCreate(32, sizeof(Event_t *)); + wifiEventQueueHandle = xQueueCreate(32, sizeof(rtw_event_t *)); LT_HEAP_I(); } if (!wifiEventTaskHandle) {