diff --git a/SUMMARY.md b/SUMMARY.md index 0421b1b..6e54118 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -14,10 +14,7 @@ * Common API * [FS](ltapi/classfs_1_1_f_s.md) * [Preferences](ltapi/class_i_preferences.md) - * [WiFi API](ltapi/class_i_wi_fi_generic_class.md) - * [Station](ltapi/class_i_wi_fi_s_t_a_class.md) - * [Access Point](ltapi/class_i_wi_fi_a_p_class.md) - * [Scanning](ltapi/class_i_wi_fi_scan_class.md) + * [WiFi API](ltapi/class_wi_fi_class.md) * [TCP Client](ltapi/class_i_wi_fi_client.md) * [SSL Client](ltapi/class_i_wi_fi_client_secure.md) * [TCP Server](ltapi/class_i_wi_fi_server.md) diff --git a/arduino/libretuya/api/Events.h b/arduino/libretuya/api/Events.h index 1197d87..dc128e4 100644 --- a/arduino/libretuya/api/Events.h +++ b/arduino/libretuya/api/Events.h @@ -22,10 +22,10 @@ #pragma once +#include +#include #include -#include "WiFiEvents.h" - typedef enum { ARDUINO_EVENT_WIFI_READY = 0, /**< ESP32 WiFi ready */ ARDUINO_EVENT_WIFI_SCAN_DONE, /**< ESP32 finish scanning AP */ diff --git a/arduino/libretuya/api/WiFi.h b/arduino/libretuya/api/WiFi.h deleted file mode 100644 index c76636c..0000000 --- a/arduino/libretuya/api/WiFi.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - WiFi.h - esp32 Wifi support. - Based on WiFi.h from Arduino WiFi shield library. - Copyright (c) 2011-2014 Arduino. All right reserved. - Modified by Ivan Grokhotkov, December 2014 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include - -#include -#include -#include -#include - -#include "Events.h" -#include "WiFiType.h" - -class IWiFiClass { - public: - virtual void printDiag(Print &dest) = 0; -}; - -class IWiFiGenericClass { - public: - virtual int32_t channel(void) = 0; - virtual bool mode(WiFiMode mode) = 0; - virtual WiFiMode getMode() = 0; - virtual WiFiStatus status() = 0; - - virtual bool enableSTA(bool enable) = 0; - virtual bool enableAP(bool enable) = 0; - - virtual bool setSleep(bool enable) = 0; - virtual bool getSleep() = 0; - - virtual bool setTxPower(int power) = 0; - virtual int getTxPower() = 0; - - virtual int hostByName(const char *hostname, IPAddress &aResult) { - aResult = hostByName(hostname); - return true; - } - - virtual IPAddress hostByName(const char *hostname) = 0; - - static IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet); - static IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet); - static uint8_t calculateSubnetCIDR(IPAddress subnetMask); - static String macToString(uint8_t *mac); - - protected: - static std::vector handlers; - - public: - uint16_t onEvent(EventCb callback, EventId eventId = ARDUINO_EVENT_MAX); - uint16_t onEvent(EventFuncCb callback, EventId eventId = ARDUINO_EVENT_MAX); - uint16_t onEvent(EventSysCb callback, EventId eventId = ARDUINO_EVENT_MAX); - void removeEvent(EventCb callback, EventId eventId); - void removeEvent(EventSysCb callback, EventId eventId); - void removeEvent(uint16_t id); - - protected: - static void postEvent(EventId eventId, EventInfo eventInfo); -}; - -class IWiFiSTAClass { - public: - virtual WiFiStatus begin( - const char *ssid, - const char *passphrase = NULL, - int32_t channel = 0, - const uint8_t *bssid = NULL, - bool connect = true - ) = 0; - virtual WiFiStatus begin( - char *ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t *bssid = NULL, bool connect = true - ) = 0; - - virtual bool config( - IPAddress localIP, - IPAddress gateway, - IPAddress subnet, - IPAddress dns1 = (uint32_t)0x00000000, - IPAddress dns2 = (uint32_t)0x00000000 - ) = 0; - - virtual bool reconnect() = 0; - virtual bool disconnect(bool wifiOff = false) = 0; - - virtual bool isConnected(); - - virtual bool setAutoReconnect(bool autoReconnect) = 0; - virtual bool getAutoReconnect() = 0; - - virtual WiFiStatus waitForConnectResult(unsigned long timeout) = 0; - - virtual IPAddress localIP() = 0; - virtual uint8_t *macAddress(uint8_t *mac) = 0; - virtual String macAddress() = 0; - virtual IPAddress subnetMask() = 0; - virtual IPAddress gatewayIP() = 0; - virtual IPAddress dnsIP(uint8_t dns_no = 0) = 0; - virtual IPAddress broadcastIP() = 0; - virtual IPAddress networkID() = 0; - virtual uint8_t subnetCIDR() = 0; - virtual bool enableIpV6() = 0; - virtual IPv6Address localIPv6() = 0; - virtual const char *getHostname() = 0; - virtual bool setHostname(const char *hostname) = 0; - virtual bool setMacAddress(const uint8_t *mac) = 0; - - inline bool hostname(const String &aHostname) { - return setHostname(aHostname.c_str()); - } - - virtual const String SSID() = 0; - virtual const String psk() = 0; - virtual uint8_t *BSSID() = 0; - virtual String BSSIDstr() = 0; - virtual int8_t RSSI() = 0; - virtual WiFiAuthMode getEncryption() = 0; -}; - -class IWiFiScanClass { - public: - virtual int16_t scanNetworks( - bool async = false, - bool showHidden = false, - bool passive = false, - uint32_t maxMsPerChannel = 300, - uint8_t channel = 0 - ) = 0; - virtual bool getNetworkInfo( - uint8_t networkItem, - String &ssid, - WiFiAuthMode &encryptionType, - int32_t &RSSI, - uint8_t *&BSSID, - int32_t &channel - ) = 0; - - virtual int16_t scanComplete() = 0; - virtual void scanDelete() = 0; - - virtual String SSID(uint8_t networkItem) = 0; - virtual WiFiAuthMode encryptionType(uint8_t networkItem) = 0; - virtual int32_t RSSI(uint8_t networkItem) = 0; - virtual uint8_t *BSSID(uint8_t networkItem) = 0; - virtual String BSSIDstr(uint8_t networkItem) = 0; - virtual int32_t channel(uint8_t networkItem) = 0; -}; - -class IWiFiAPClass { - public: - virtual bool softAP( - const char *ssid, const char *passphrase = NULL, int channel = 1, bool ssidHidden = false, int maxClients = 4 - ) = 0; - virtual bool softAPConfig(IPAddress localIP, IPAddress gateway, IPAddress subnet) = 0; - virtual bool softAPdisconnect(bool wifiOff = false) = 0; - - virtual uint8_t softAPgetStationNum() = 0; - - virtual IPAddress softAPIP() = 0; - virtual IPAddress softAPBroadcastIP() = 0; - virtual IPAddress softAPNetworkID() = 0; - virtual uint8_t softAPSubnetCIDR() = 0; - virtual bool softAPenableIpV6() = 0; - virtual IPv6Address softAPIPv6() = 0; - virtual const char *softAPgetHostname() = 0; - virtual bool softAPsetHostname(const char *hostname) = 0; - virtual uint8_t *softAPmacAddress(uint8_t *mac) = 0; - virtual String softAPmacAddress(void) = 0; - virtual const String softAPSSID(void) = 0; -}; diff --git a/arduino/libretuya/api/WiFi/WiFi.cpp b/arduino/libretuya/api/WiFi/WiFi.cpp new file mode 100644 index 0000000..c7d7a93 --- /dev/null +++ b/arduino/libretuya/api/WiFi/WiFi.cpp @@ -0,0 +1,46 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + +#include "WiFi.h" + +void WiFiClass::printDiag(Print &dest) { + const char *modes[] = {"NULL", "STA", "AP", "STA+AP"}; + const char *enc[] = {"Open", "WEP", "WPA PSK", "WPA2 PSK", "WPA/WPA2", "WPA", "WPA2"}; + + dest.print("Mode: "); + dest.println(modes[getMode()]); + + if (getMode() & WIFI_MODE_STA) { + dest.println("-- Station --"); + dest.print("SSID: "); + dest.println(SSID()); + if (isConnected()) { + dest.print("BSSID: "); + dest.println(BSSIDstr()); + dest.print("RSSI: "); + dest.println(RSSI()); + dest.print("Encryption: "); + dest.println(enc[getEncryption()]); + dest.print("IP: "); + dest.println(localIP()); + dest.print("MAC: "); + dest.println(macAddress()); + dest.print("Hostname: "); + dest.println(getHostname()); + } + } + + if (getMode() & WIFI_MODE_AP) { + dest.println("-- Access Point --"); + dest.print("SSID: "); + dest.println(softAPSSID()); + dest.print("IP: "); + dest.println(softAPIP()); + dest.print("MAC: "); + dest.println(softAPmacAddress()); + dest.print("Hostname: "); + dest.println(softAPgetHostname()); + } +} + +WiFiClass WiFi; +WiFiClass *pWiFi = NULL; diff --git a/arduino/libretuya/api/WiFi/WiFi.h b/arduino/libretuya/api/WiFi/WiFi.h new file mode 100644 index 0000000..bc887f6 --- /dev/null +++ b/arduino/libretuya/api/WiFi/WiFi.h @@ -0,0 +1,187 @@ +/* + WiFi.h - esp32 Wifi support. + Based on WiFi.h from Arduino WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + Modified by Ivan Grokhotkov, December 2014 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include "WiFiType.h" +// family's data structure +#include + +class WiFiClass { + public: + // must be public for WiFiEvents & WiFiScan static handlers + WiFiData data; + WiFiScanData *scan = NULL; + + public: /* WiFi.cpp */ + WiFiClass(); + ~WiFiClass(); + void printDiag(Print &dest); + + public: /* WiFiGeneric.cpp */ + int32_t channel(void); + bool mode(WiFiMode mode); + WiFiMode getMode(); + WiFiStatus status(); + + bool enableSTA(bool enable); + bool enableAP(bool enable); + + bool setSleep(bool enable); + bool getSleep(); + + bool setTxPower(int power); + int getTxPower(); + + int hostByName(const char *hostname, IPAddress &aResult); + IPAddress hostByName(const char *hostname); + + static IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet); + static IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet); + static uint8_t calculateSubnetCIDR(IPAddress subnetMask); + static String macToString(uint8_t *mac); + + protected: /* WiFiEvents.cpp */ + static std::vector handlers; + + public: /* WiFiEvents.cpp */ + uint16_t onEvent(EventCb callback, EventId eventId = ARDUINO_EVENT_MAX); + uint16_t onEvent(EventFuncCb callback, EventId eventId = ARDUINO_EVENT_MAX); + uint16_t onEvent(EventSysCb callback, EventId eventId = ARDUINO_EVENT_MAX); + void removeEvent(EventCb callback, EventId eventId); + void removeEvent(EventSysCb callback, EventId eventId); + void removeEvent(uint16_t id); + static void postEvent(EventId eventId, EventInfo eventInfo); + + public: /* WiFiSTA.cpp */ + WiFiStatus begin( + const char *ssid, + const char *passphrase = NULL, + int32_t channel = 0, + const uint8_t *bssid = NULL, + bool connect = true + ); + WiFiStatus + begin(char *ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t *bssid = NULL, bool connect = true); + + bool config( + IPAddress localIP, + IPAddress gateway, + IPAddress subnet, + IPAddress dns1 = (uint32_t)0x00000000, + IPAddress dns2 = (uint32_t)0x00000000 + ); + + bool reconnect(const uint8_t *bssid = NULL); + bool disconnect(bool wifiOff = false); + + bool isConnected(); + + bool setAutoReconnect(bool autoReconnect); + bool getAutoReconnect(); + + WiFiStatus waitForConnectResult(unsigned long timeout); + + IPAddress localIP(); + uint8_t *macAddress(uint8_t *mac); + String macAddress(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsIP(uint8_t dns_no = 0); + IPAddress broadcastIP(); + IPAddress networkID(); + uint8_t subnetCIDR(); + bool enableIpV6(); + IPv6Address localIPv6(); + const char *getHostname(); + bool setHostname(const char *hostname); + bool setMacAddress(const uint8_t *mac); + + inline bool hostname(const String &aHostname) { + return setHostname(aHostname.c_str()); + } + + const String SSID(); + const String psk(); + uint8_t *BSSID(); + String BSSIDstr(); + int8_t RSSI(); + WiFiAuthMode getEncryption(); + + public: /* WiFiScan.cpp */ + int16_t scanNetworks( + bool async = false, + bool showHidden = false, + bool passive = false, + uint32_t maxMsPerChannel = 300, + uint8_t channel = 0 + ); + bool getNetworkInfo( + uint8_t networkItem, + String &ssid, + WiFiAuthMode &encryptionType, + int32_t &RSSI, + uint8_t *&BSSID, + int32_t &channel + ); + + int16_t scanComplete(); + void scanInit(); + void scanDelete(); + + String SSID(uint8_t networkItem); + WiFiAuthMode encryptionType(uint8_t networkItem); + int32_t RSSI(uint8_t networkItem); + uint8_t *BSSID(uint8_t networkItem); + String BSSIDstr(uint8_t networkItem); + int32_t channel(uint8_t networkItem); + + public: /* WiFiAP.cpp */ + bool softAP( + const char *ssid, const char *passphrase = NULL, int channel = 1, bool ssidHidden = false, int maxClients = 4 + ); + bool softAPConfig(IPAddress localIP, IPAddress gateway, IPAddress subnet); + bool softAPdisconnect(bool wifiOff = false); + + uint8_t softAPgetStationNum(); + + IPAddress softAPIP(); + IPAddress softAPBroadcastIP(); + IPAddress softAPNetworkID(); + uint8_t softAPSubnetCIDR(); + IPAddress softAPSubnetMask(); + bool softAPenableIpV6(); + IPv6Address softAPIPv6(); + const char *softAPgetHostname(); + bool softAPsetHostname(const char *hostname); + uint8_t *softAPmacAddress(uint8_t *mac); + String softAPmacAddress(void); + const String softAPSSID(void); +}; + +extern WiFiClass WiFi; +extern WiFiClass *pWiFi; diff --git a/arduino/libretuya/api/WiFi/WiFiAP.cpp b/arduino/libretuya/api/WiFi/WiFiAP.cpp new file mode 100644 index 0000000..4a26ea5 --- /dev/null +++ b/arduino/libretuya/api/WiFi/WiFiAP.cpp @@ -0,0 +1,23 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + +#include "WiFi.h" + +IPAddress WiFiClass::softAPBroadcastIP() { + return calculateBroadcast(softAPIP(), softAPSubnetMask()); +} + +IPAddress WiFiClass::softAPNetworkID() { + return calculateNetworkID(softAPIP(), softAPSubnetMask()); +} + +uint8_t WiFiClass::softAPSubnetCIDR() { + return calculateSubnetCIDR(softAPSubnetMask()); +} + +__attribute__((weak)) bool WiFiClass::softAPenableIpV6() { + return false; +} + +__attribute__((weak)) IPv6Address WiFiClass::softAPIPv6() { + return IPv6Address(); +} diff --git a/arduino/libretuya/api/WiFi.cpp b/arduino/libretuya/api/WiFi/WiFiEvents.cpp similarity index 73% rename from arduino/libretuya/api/WiFi.cpp rename to arduino/libretuya/api/WiFi/WiFiEvents.cpp index 73514db..bb93b99 100644 --- a/arduino/libretuya/api/WiFi.cpp +++ b/arduino/libretuya/api/WiFi/WiFiEvents.cpp @@ -2,9 +2,9 @@ #include "WiFi.h" -std::vector IWiFiGenericClass::handlers; +std::vector WiFiClass::handlers; -uint16_t IWiFiGenericClass::onEvent(EventCb callback, EventId eventId) { +uint16_t WiFiClass::onEvent(EventCb callback, EventId eventId) { if (!callback) return 0; EventHandler handler; @@ -14,7 +14,7 @@ uint16_t IWiFiGenericClass::onEvent(EventCb callback, EventId eventId) { return handler.id; } -uint16_t IWiFiGenericClass::onEvent(EventFuncCb callback, EventId eventId) { +uint16_t WiFiClass::onEvent(EventFuncCb callback, EventId eventId) { if (!callback) return 0; EventHandler handler; @@ -24,7 +24,7 @@ uint16_t IWiFiGenericClass::onEvent(EventFuncCb callback, EventId eventId) { return handler.id; } -uint16_t IWiFiGenericClass::onEvent(EventSysCb callback, EventId eventId) { +uint16_t WiFiClass::onEvent(EventSysCb callback, EventId eventId) { if (!callback) return 0; EventHandler handler; @@ -34,7 +34,7 @@ uint16_t IWiFiGenericClass::onEvent(EventSysCb callback, EventId eventId) { return handler.id; } -void IWiFiGenericClass::removeEvent(EventCb callback, EventId eventId) { +void WiFiClass::removeEvent(EventCb callback, EventId eventId) { if (!callback) return; for (uint16_t i = 0; i < handlers.size(); i++) { @@ -45,7 +45,7 @@ void IWiFiGenericClass::removeEvent(EventCb callback, EventId eventId) { } } -void IWiFiGenericClass::removeEvent(EventSysCb callback, EventId eventId) { +void WiFiClass::removeEvent(EventSysCb callback, EventId eventId) { if (!callback) return; for (uint16_t i = 0; i < handlers.size(); i++) { @@ -56,7 +56,7 @@ void IWiFiGenericClass::removeEvent(EventSysCb callback, EventId eventId) { } } -void IWiFiGenericClass::removeEvent(uint16_t id) { +void WiFiClass::removeEvent(uint16_t id) { for (uint16_t i = 0; i < handlers.size(); i++) { EventHandler handler = handlers[i]; if (handler.id == id) { @@ -65,7 +65,7 @@ void IWiFiGenericClass::removeEvent(uint16_t id) { } } -void IWiFiGenericClass::postEvent(EventId eventId, EventInfo eventInfo) { +void WiFiClass::postEvent(EventId eventId, EventInfo eventInfo) { for (auto handler : handlers) { if (handler.eventId != ARDUINO_EVENT_MAX && handler.eventId != eventId) continue; diff --git a/arduino/libretuya/api/WiFiEvents.h b/arduino/libretuya/api/WiFi/WiFiEvents.h similarity index 100% rename from arduino/libretuya/api/WiFiEvents.h rename to arduino/libretuya/api/WiFi/WiFiEvents.h diff --git a/arduino/libretuya/api/WiFi/WiFiGeneric.cpp b/arduino/libretuya/api/WiFi/WiFiGeneric.cpp new file mode 100644 index 0000000..76350ef --- /dev/null +++ b/arduino/libretuya/api/WiFi/WiFiGeneric.cpp @@ -0,0 +1,73 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + +#include "WiFi.h" + +bool WiFiClass::enableSTA(bool enable) { + WiFiMode currentMode = getMode(); + if (((currentMode & WIFI_MODE_STA) != 0) != enable) { + return mode((WiFiMode)(currentMode ^ WIFI_MODE_STA)); + } + return true; +} + +bool WiFiClass::enableAP(bool enable) { + WiFiMode currentMode = getMode(); + if (((currentMode & WIFI_MODE_AP) != 0) != enable) { + return mode((WiFiMode)(currentMode ^ WIFI_MODE_AP)); + } + return true; +} + +int WiFiClass::hostByName(const char *hostname, IPAddress &aResult) { + aResult = hostByName(hostname); + return true; +} + +IPAddress WiFiClass::calculateNetworkID(IPAddress ip, IPAddress subnet) { + IPAddress networkID; + + for (size_t i = 0; i < 4; i++) + networkID[i] = subnet[i] & ip[i]; + + return networkID; +} + +IPAddress WiFiClass::calculateBroadcast(IPAddress ip, IPAddress subnet) { + IPAddress broadcastIp; + + for (int i = 0; i < 4; i++) + broadcastIp[i] = ~subnet[i] | ip[i]; + + return broadcastIp; +} + +uint8_t WiFiClass::calculateSubnetCIDR(IPAddress subnetMask) { + uint8_t CIDR = 0; + + for (uint8_t i = 0; i < 4; i++) { + if (subnetMask[i] == 0x80) // 128 + CIDR += 1; + else if (subnetMask[i] == 0xC0) // 192 + CIDR += 2; + else if (subnetMask[i] == 0xE0) // 224 + CIDR += 3; + else if (subnetMask[i] == 0xF0) // 242 + CIDR += 4; + else if (subnetMask[i] == 0xF8) // 248 + CIDR += 5; + else if (subnetMask[i] == 0xFC) // 252 + CIDR += 6; + else if (subnetMask[i] == 0xFE) // 254 + CIDR += 7; + else if (subnetMask[i] == 0xFF) // 255 + CIDR += 8; + } + + return CIDR; +} + +String WiFiClass::macToString(uint8_t *mac) { + char macStr[18]; // 6*2 + 5*':' + '\0' + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return macStr; +} diff --git a/arduino/libretuya/api/WiFi/WiFiSTA.cpp b/arduino/libretuya/api/WiFi/WiFiSTA.cpp new file mode 100644 index 0000000..684cc63 --- /dev/null +++ b/arduino/libretuya/api/WiFi/WiFiSTA.cpp @@ -0,0 +1,48 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + +#include "WiFi.h" + +WiFiStatus WiFiClass::begin(char *ssid, char *passphrase, int32_t channel, const uint8_t *bssid, bool connect) { + return begin((const char *)ssid, (const char *)passphrase, channel, bssid, connect); +} + +bool WiFiClass::isConnected() { + return status() == WL_CONNECTED; +} + +WiFiStatus WiFiClass::waitForConnectResult(unsigned long timeout) { + if ((getMode() & WIFI_MODE_STA) == 0) { + return WL_DISCONNECTED; + } + unsigned long start = millis(); + while ((!status() || status() >= WL_DISCONNECTED) && (millis() - start) < timeout) { + delay(100); + } + return status(); +} + +String WiFiClass::macAddress(void) { + uint8_t mac[6]; + macAddress(mac); + return macToString(mac); +} + +IPAddress WiFiClass::networkID() { + return calculateNetworkID(gatewayIP(), subnetMask()); +} + +uint8_t WiFiClass::subnetCIDR() { + return calculateSubnetCIDR(subnetMask()); +} + +String WiFiClass::BSSIDstr() { + return macToString(BSSID()); +} + +__attribute__((weak)) bool WiFiClass::enableIpV6() { + return false; +} + +__attribute__((weak)) IPv6Address WiFiClass::localIPv6() { + return IPv6Address(); +} diff --git a/arduino/libretuya/api/WiFi/WiFiScan.cpp b/arduino/libretuya/api/WiFi/WiFiScan.cpp new file mode 100644 index 0000000..7859904 --- /dev/null +++ b/arduino/libretuya/api/WiFi/WiFiScan.cpp @@ -0,0 +1,76 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + +#include "WiFi.h" + +bool WiFiClass::getNetworkInfo( + uint8_t networkItem, String &ssid, WiFiAuthMode &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel +) { + ssid = SSID(networkItem); + encType = encryptionType(networkItem); + rssi = RSSI(networkItem); + bssid = BSSID(networkItem); + channel = this->channel(networkItem); +} + +int16_t WiFiClass::scanComplete() { + if (!scan) + return 0; + if (scan->running) + return WIFI_SCAN_RUNNING; + return scan->count; +} + +void WiFiClass::scanInit() { + if (scan) + return; + scan = (WiFiScanData *)zalloc(sizeof(WiFiScanData)); +} + +void WiFiClass::scanDelete() { + if (!scan) + return; + for (uint8_t i = 0; i < scan->count; i++) { + free(scan->ssid[i]); + } + free(scan->ssid); + free(scan->auth); + free(scan->rssi); + free(scan->bssid); + free(scan->channel); + free(scan); + scan = NULL; +} + +String WiFiClass::SSID(uint8_t networkItem) { + if (!scan || networkItem >= scan->count) + return ""; + return scan->ssid[networkItem]; +} + +WiFiAuthMode WiFiClass::encryptionType(uint8_t networkItem) { + if (!scan || networkItem >= scan->count) + return WIFI_AUTH_INVALID; + return scan->auth[networkItem]; +} + +int32_t WiFiClass::RSSI(uint8_t networkItem) { + if (!scan || networkItem >= scan->count) + return 0; + return scan->rssi[networkItem]; +} + +uint8_t *WiFiClass::BSSID(uint8_t networkItem) { + if (!scan || networkItem >= scan->count) + return NULL; + return scan->bssid[networkItem].addr; +} + +String WiFiClass::BSSIDstr(uint8_t networkItem) { + return macToString(BSSID(networkItem)); +} + +int32_t WiFiClass::channel(uint8_t networkItem) { + if (!scan || networkItem >= scan->count) + return 0; + return scan->channel[networkItem]; +} diff --git a/arduino/libretuya/api/WiFiType.h b/arduino/libretuya/api/WiFi/WiFiType.h similarity index 93% rename from arduino/libretuya/api/WiFiType.h rename to arduino/libretuya/api/WiFi/WiFiType.h index 2f40a9c..09561dd 100644 --- a/arduino/libretuya/api/WiFiType.h +++ b/arduino/libretuya/api/WiFi/WiFiType.h @@ -21,6 +21,8 @@ #pragma once +#include + #define WIFI_SCAN_RUNNING (-1) #define WIFI_SCAN_FAILED (-2) @@ -38,6 +40,10 @@ #define WiFiEventInfo_t arduino_event_info_t #define WiFiEventId_t uint16_t +typedef struct { + uint8_t addr[6]; +} WiFiMacAddr; + struct esp_ip6_addr { uint32_t addr[4]; uint8_t zone; @@ -121,3 +127,13 @@ typedef enum { WIFI_REASON_AP_TSF_RESET = 206, WIFI_REASON_ROAMING = 207, } wifi_err_reason_t; + +typedef struct { + bool running = false; + uint8_t count = 0; + char **ssid = NULL; + WiFiAuthMode *auth = NULL; + int32_t *rssi = NULL; + WiFiMacAddr *bssid = NULL; + int32_t *channel = NULL; +} WiFiScanData; diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp index 3a082a6..cc9f75b 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp @@ -1,6 +1,5 @@ /* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ -#include "WiFi.h" #include "WiFiPriv.h" rtw_network_info_t wifi = {0}; @@ -26,54 +25,14 @@ void reset_wifi_struct(void) { } WiFiClass::WiFiClass() { - _scanSem = xSemaphoreCreateBinary(); + data.scanSem = xSemaphoreCreateBinary(); } WiFiClass::~WiFiClass() { - vSemaphoreDelete(_scanSem); + vSemaphoreDelete(data.scanSem); } -void WiFiClass::printDiag(Print &dest) { - const char *modes[] = {"NULL", "STA", "AP", "STA+AP"}; - const char *enc[] = {"Open", "WEP", "WPA PSK", "WPA2 PSK", "WPA/WPA2", "WPA", "WPA2"}; - - dest.print("Mode: "); - dest.println(modes[getMode()]); - - if (wifi_mode & WIFI_MODE_STA) { - dest.println("-- Station --"); - dest.print("SSID: "); - dest.println(SSID()); - if (isConnected()) { - dest.print("BSSID: "); - dest.println(BSSIDstr()); - dest.print("RSSI: "); - dest.println(RSSI()); - dest.print("Encryption: "); - dest.println(enc[getEncryption()]); - dest.print("IP: "); - dest.println(localIP()); - dest.print("MAC: "); - dest.println(macAddress()); - dest.print("Hostname: "); - dest.println(getHostname()); - } - } - - if (wifi_mode & WIFI_MODE_AP) { - dest.println("-- Access Point --"); - dest.print("SSID: "); - dest.println(softAPSSID()); - dest.print("IP: "); - dest.println(softAPIP()); - dest.print("MAC: "); - dest.println(softAPmacAddress()); - dest.print("Hostname: "); - dest.println(softAPgetHostname()); - } -} - -WiFiAuthMode WiFiClass::securityTypeToAuthMode(uint8_t type) { +WiFiAuthMode securityTypeToAuthMode(uint8_t type) { // the value reported in rtw_scan_result is rtw_encryption_t, even though it's rtw_security_t in the header file switch (type) { case RTW_ENCRYPTION_OPEN: @@ -91,5 +50,3 @@ WiFiAuthMode WiFiClass::securityTypeToAuthMode(uint8_t type) { } return WIFI_AUTH_INVALID; } - -WiFiClass WiFi; diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFi.h b/arduino/realtek-ambz/libraries/WiFi/WiFi.h index dcfede1..c386b1b 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFi.h +++ b/arduino/realtek-ambz/libraries/WiFi/WiFi.h @@ -3,183 +3,8 @@ #pragma once #include -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include -#include -#include - -#ifdef __cplusplus -} // extern "C" -#endif +#include #include "WiFiClient.h" #include "WiFiClientSecure.h" #include "WiFiServer.h" - -class WiFiClass : public IWiFiClass, - public IWiFiGenericClass, - public IWiFiSTAClass, - public IWiFiScanClass, - public IWiFiAPClass { - private: - static WiFiAuthMode securityTypeToAuthMode(uint8_t type); - - bool _initialized; - bool _sleep; - - bool _scanning = false; - SemaphoreHandle_t _scanSem; - uint8_t _netCount = 0; - char **_netSsid = NULL; - WiFiAuthMode *_netEncr = NULL; - int32_t *_netRssi = NULL; - rtw_mac_t *_netBssid = NULL; - int32_t *_netChannel = NULL; - - static rtw_result_t scanHandler(rtw_scan_handler_result_t *result); - - public: - // IWiFiClass - WiFiClass(); - ~WiFiClass(); - void printDiag(Print &dest); - - public: - // IWiFiGenericClass - int32_t channel(void); - - bool mode(WiFiMode mode) override; - WiFiMode getMode(); - WiFiStatus status(); - - bool enableSTA(bool enable); - bool enableAP(bool enable); - - bool setSleep(bool enable); - bool getSleep(); - - bool setTxPower(int power); - int getTxPower(); - - IPAddress hostByName(const char *hostname); - - static IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet); - static IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet); - static uint8_t calculateSubnetCIDR(IPAddress subnetMask); - static String macToString(uint8_t *mac); - - static void handleRtwEvent(uint16_t event, char *data, int len, int flags); - - public: - // IWiFiSTAClass - WiFiStatus begin( - const char *ssid, - const char *passphrase = NULL, - int32_t channel = 0, - const uint8_t *bssid = NULL, - bool connect = true - ) override; - WiFiStatus - begin(char *ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t *bssid = NULL, bool connect = true); - - bool config( - IPAddress localIP, - IPAddress gateway, - IPAddress subnet, - IPAddress dns1 = (uint32_t)0x00000000, - IPAddress dns2 = (uint32_t)0x00000000 - ); - - inline bool reconnect() { - return reconnect(NULL); - } - - bool reconnect(const uint8_t *bssid = NULL); - bool disconnect(bool wifiOff = false); - - bool isConnected() override; - - bool setAutoReconnect(bool autoReconnect); - bool getAutoReconnect(); - - WiFiStatus waitForConnectResult(unsigned long timeout); - - IPAddress localIP(); - uint8_t *macAddress(uint8_t *mac); - String macAddress(); - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsIP(uint8_t dns_no); - IPAddress broadcastIP(); - IPAddress networkID(); - uint8_t subnetCIDR(); - bool enableIpV6(); - IPv6Address localIPv6(); - const char *getHostname(); - bool setHostname(const char *hostname); - bool setMacAddress(const uint8_t *mac); - - const String SSID(); - const String psk(); - uint8_t *BSSID(); - String BSSIDstr(); - int8_t RSSI(); - WiFiAuthMode getEncryption(); - - public: - // IWiFiScanClass - int16_t scanNetworks( - bool async = false, - bool showHidden = false, - bool passive = false, - uint32_t maxMsPerChannel = 300, - uint8_t channel = 0 - ); - bool getNetworkInfo( - uint8_t networkItem, - String &ssid, - WiFiAuthMode &encryptionType, - int32_t &RSSI, - uint8_t *&BSSID, - int32_t &channel - ); - - int16_t scanComplete(); - void scanDelete(); - - String SSID(uint8_t networkItem); - WiFiAuthMode encryptionType(uint8_t networkItem); - int32_t RSSI(uint8_t networkItem); - uint8_t *BSSID(uint8_t networkItem); - String BSSIDstr(uint8_t networkItem); - int32_t channel(uint8_t networkItem); - - public: - // IWiFiAPClass - bool softAP( - const char *ssid, const char *passphrase = NULL, int channel = 1, bool ssidHidden = false, int maxClients = 4 - ); - bool softAPConfig(IPAddress localIP, IPAddress gateway, IPAddress subnet); - bool softAPdisconnect(bool wifiOff = false); - - uint8_t softAPgetStationNum(); - - IPAddress softAPIP(); - IPAddress softAPBroadcastIP(); - IPAddress softAPNetworkID(); - uint8_t softAPSubnetCIDR(); - bool softAPenableIpV6(); - IPv6Address softAPIPv6(); - const char *softAPgetHostname(); - bool softAPsetHostname(const char *hostname); - uint8_t *softAPmacAddress(uint8_t *mac); - String softAPmacAddress(void); - const String softAPSSID(void); -}; - -extern WiFiClass WiFi; diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp index 8efb06d..3471239 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp @@ -1,6 +1,5 @@ /* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ -#include "WiFi.h" #include "WiFiPriv.h" typedef struct { @@ -127,24 +126,8 @@ IPAddress WiFiClass::softAPIP() { return LwIP_GetIP(NETIF_RTW_AP); } -IPAddress WiFiClass::softAPBroadcastIP() { - return calculateBroadcast(softAPIP(), LwIP_GetMASK(NETIF_RTW_AP)); -} - -IPAddress WiFiClass::softAPNetworkID() { - return calculateNetworkID(softAPIP(), LwIP_GetMASK(NETIF_RTW_AP)); -} - -uint8_t WiFiClass::softAPSubnetCIDR() { - return calculateSubnetCIDR(LwIP_GetMASK(NETIF_RTW_AP)); -} - -bool WiFiClass::softAPenableIpV6() { - return false; -} - -IPv6Address WiFiClass::softAPIPv6() { - return IPv6Address(); +IPAddress WiFiClass::softAPSubnetMask() { + return LwIP_GetMASK(NETIF_RTW_AP); } const char *WiFiClass::softAPgetHostname() { diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiData.h b/arduino/realtek-ambz/libraries/WiFi/WiFiData.h new file mode 100644 index 0000000..188ae1e --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiData.h @@ -0,0 +1,22 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-23. */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#ifdef __cplusplus +} // extern "C" +#endif + +typedef struct { + bool initialized; + bool sleep; + SemaphoreHandle_t scanSem; +} WiFiData; diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp index 5962ed1..c71133e 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiEvents.cpp @@ -1,6 +1,5 @@ /* Copyright (c) Kuba Szczodrzyński 2022-05-16. */ -#include "WiFi.h" #include "WiFiPriv.h" #include @@ -10,8 +9,6 @@ static xQueueHandle wifiEventQueueHandle = NULL; static xTaskHandle wifiEventTaskHandle = NULL; -WiFiClass *pWiFi = NULL; - // C code to support SDK-defined events (in wifi_conf.c) extern "C" { // SDK events @@ -86,7 +83,7 @@ void wifi_indication(rtw_event_indicate_t event, char *buf, int buf_len, int fla ev->flags = flags; xQueueSend(wifiEventQueueHandle, &ev, portMAX_DELAY); } else { - WiFiClass::handleRtwEvent(event, buf, buf_len, flags); + handleRtwEvent(event, buf, buf_len, flags); } } @@ -94,7 +91,7 @@ static void wifiEventTask(void *arg) { rtw_event_t *data = NULL; for (;;) { if (xQueueReceive(wifiEventQueueHandle, &data, portMAX_DELAY) == pdTRUE) { - WiFiClass::handleRtwEvent(data->event, data->buf, data->buf_len, data->flags); + handleRtwEvent(data->event, data->buf, data->buf_len, data->flags); if (data->buf) { // free memory allocated in wifi_indication free(data->buf); @@ -117,12 +114,14 @@ void startWifiTask() { } } -void WiFiClass::handleRtwEvent(uint16_t event, char *data, int len, int flags) { +void handleRtwEvent(uint16_t event, char *data, int len, int flags) { + if (!pWiFi) + return; // failsafe if (flags == -2) { // already an Arduino event, just pass it EventId eventId = (EventId)len; EventInfo *eventInfo = (EventInfo *)data; - postEvent(eventId, *eventInfo); + pWiFi->postEvent(eventId, *eventInfo); free(eventInfo); return; } @@ -165,9 +164,10 @@ void WiFiClass::handleRtwEvent(uint16_t event, char *data, int len, int flags) { break; case WIFI_EVENT_SCAN_DONE: - eventId = ARDUINO_EVENT_WIFI_SCAN_DONE; - eventInfo.wifi_scan_done.status = 0; - eventInfo.wifi_scan_done.number = pWiFi->_netCount; + 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; @@ -202,5 +202,5 @@ void WiFiClass::handleRtwEvent(uint16_t event, char *data, int len, int flags) { return; } - postEvent(eventId, eventInfo); + pWiFi->postEvent(eventId, eventInfo); } diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp index 1e6ae0d..652f1ff 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp @@ -1,17 +1,13 @@ /* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ -#include "WiFi.h" #include "WiFiPriv.h" int32_t WiFiClass::channel() { - int channel; + int channel = 0; wifi_get_channel(&channel); return channel; } -extern WiFiClass *pWiFi; -extern void startWifiTask(); - bool WiFiClass::mode(WiFiMode mode) { // store a pointer to WiFi for WiFiEvents.cpp pWiFi = this; @@ -23,12 +19,12 @@ bool WiFiClass::mode(WiFiMode mode) { LT_HEAP_I(); startWifiTask(); - if (!currentMode && mode && !_initialized) { + if (!currentMode && mode && !data.initialized) { // initialize wifi first LT_I("Initializing LwIP"); LwIP_Init(); reset_wifi_struct(); - _initialized = true; + data.initialized = true; } LT_HEAP_I(); if (currentMode) { @@ -62,7 +58,7 @@ bool WiFiClass::mode(WiFiMode mode) { } WiFiMode WiFiClass::getMode() { - if (!_initialized) + if (!data.initialized) return WIFI_MODE_NULL; return (WiFiMode)wifi_mode; } @@ -75,22 +71,6 @@ WiFiStatus WiFiClass::status() { } } -bool WiFiClass::enableSTA(bool enable) { - WiFiMode currentMode = getMode(); - if (((currentMode & WIFI_MODE_STA) != 0) != enable) { - return mode((WiFiMode)(currentMode ^ WIFI_MODE_STA)); - } - return true; -} - -bool WiFiClass::enableAP(bool enable) { - WiFiMode currentMode = getMode(); - if (((currentMode & WIFI_MODE_AP) != 0) != enable) { - return mode((WiFiMode)(currentMode ^ WIFI_MODE_AP)); - } - return true; -} - bool WiFiClass::setSleep(bool enable) { LT_D_WG("WiFi sleep mode %u", enable); if (enable) @@ -98,12 +78,12 @@ bool WiFiClass::setSleep(bool enable) { return false; else if (wifi_disable_powersave() != RTW_SUCCESS) return false; - _sleep = enable; + data.sleep = enable; return true; } bool WiFiClass::getSleep() { - return _sleep; + return data.sleep; } bool WiFiClass::setTxPower(int power) { @@ -125,52 +105,3 @@ IPAddress WiFiClass::hostByName(const char *hostname) { } return IPAddress(); } - -IPAddress WiFiClass::calculateNetworkID(IPAddress ip, IPAddress subnet) { - IPAddress networkID; - - for (size_t i = 0; i < 4; i++) - networkID[i] = subnet[i] & ip[i]; - - return networkID; -} - -IPAddress WiFiClass::calculateBroadcast(IPAddress ip, IPAddress subnet) { - IPAddress broadcastIp; - - for (int i = 0; i < 4; i++) - broadcastIp[i] = ~subnet[i] | ip[i]; - - return broadcastIp; -} - -uint8_t WiFiClass::calculateSubnetCIDR(IPAddress subnetMask) { - uint8_t CIDR = 0; - - for (uint8_t i = 0; i < 4; i++) { - if (subnetMask[i] == 0x80) // 128 - CIDR += 1; - else if (subnetMask[i] == 0xC0) // 192 - CIDR += 2; - else if (subnetMask[i] == 0xE0) // 224 - CIDR += 3; - else if (subnetMask[i] == 0xF0) // 242 - CIDR += 4; - else if (subnetMask[i] == 0xF8) // 248 - CIDR += 5; - else if (subnetMask[i] == 0xFC) // 252 - CIDR += 6; - else if (subnetMask[i] == 0xFE) // 254 - CIDR += 7; - else if (subnetMask[i] == 0xFF) // 255 - CIDR += 8; - } - - return CIDR; -} - -String WiFiClass::macToString(uint8_t *mac) { - char macStr[ETH_ALEN * 3]; - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return macStr; -} diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h b/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h index e51e00c..a571eaf 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h @@ -2,6 +2,8 @@ #pragma once +#include "WiFi.h" + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -23,12 +25,14 @@ extern "C" { #define LWIP_COMPAT_SOCKETS 0 #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -40,10 +44,7 @@ extern struct netif xnetif[NET_IF_NUM]; } // extern "C" #endif -#include - -#include "WiFi.h" - +// WiFi.cpp extern rtw_network_info_t wifi; extern rtw_ap_info_t ap; extern rtw_wifi_setting_t wifi_setting; @@ -51,6 +52,10 @@ extern unsigned char sta_password[65]; extern unsigned char ap_password[65]; extern void reset_wifi_struct(void); extern rtw_mode_t wifi_mode; +extern WiFiAuthMode securityTypeToAuthMode(uint8_t type); +// WiFiEvents.cpp +extern void startWifiTask(); +extern void handleRtwEvent(uint16_t event, char *data, int len, int flags); #define NETIF_RTW_STA &xnetif[RTW_STA_INTERFACE] #define NETIF_RTW_AP (wifi_mode == WIFI_MODE_APSTA ? &xnetif[RTW_AP_INTERFACE] : NETIF_RTW_STA) diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp index fcd2c19..818e0e6 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp @@ -1,12 +1,7 @@ /* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ -#include "WiFi.h" #include "WiFiPriv.h" -WiFiStatus WiFiClass::begin(char *ssid, char *passphrase, int32_t channel, const uint8_t *bssid, bool connect) { - return begin((const char *)ssid, (const char *)passphrase, channel, bssid, connect); -} - WiFiStatus WiFiClass::begin(const char *ssid, const char *passphrase, int32_t channel, const uint8_t *bssid, bool connect) { if (!enableSTA(true)) @@ -134,10 +129,6 @@ bool WiFiClass::disconnect(bool wifiOff) { return ret == RTW_SUCCESS; } -bool WiFiClass::isConnected() { - return status() == WL_CONNECTED; -} - bool WiFiClass::setAutoReconnect(bool autoReconnect) { return wifi_set_autoreconnect(autoReconnect) == RTW_SUCCESS; } @@ -148,17 +139,6 @@ bool WiFiClass::getAutoReconnect() { return autoReconnect; } -WiFiStatus WiFiClass::waitForConnectResult(unsigned long timeout) { - if ((wifi_mode & WIFI_MODE_STA) == 0) { - return WL_DISCONNECTED; - } - unsigned long start = millis(); - while ((!status() || status() >= WL_DISCONNECTED) && (millis() - start) < timeout) { - delay(100); - } - return status(); -} - IPAddress WiFiClass::localIP() { if (!wifi_mode) return IPAddress(); @@ -172,12 +152,6 @@ uint8_t *WiFiClass::macAddress(uint8_t *mac) { return mac; } -String WiFiClass::macAddress(void) { - uint8_t mac[ETH_ALEN]; - macAddress(mac); - return macToString(mac); -} - IPAddress WiFiClass::subnetMask() { return LwIP_GetMASK(NETIF_RTW_STA); } @@ -196,22 +170,6 @@ IPAddress WiFiClass::broadcastIP() { return LwIP_GetBC(NETIF_RTW_STA); } -IPAddress WiFiClass::networkID() { - return calculateNetworkID(gatewayIP(), subnetMask()); -} - -uint8_t WiFiClass::subnetCIDR() { - return calculateSubnetCIDR(subnetMask()); -} - -bool WiFiClass::enableIpV6() { - return false; -} - -IPv6Address WiFiClass::localIPv6() { - return IPv6Address(); -} - const char *WiFiClass::getHostname() { return netif_get_hostname(NETIF_RTW_STA); } @@ -244,10 +202,6 @@ uint8_t *WiFiClass::BSSID() { return bssid; } -String WiFiClass::BSSIDstr() { - return macToString(BSSID()); -} - int8_t WiFiClass::RSSI() { int rssi = 0; wifi_get_rssi(&rssi); @@ -256,5 +210,5 @@ int8_t WiFiClass::RSSI() { WiFiAuthMode WiFiClass::getEncryption() { wifi_get_setting(NETNAME_STA, &wifi_setting); - return WiFiClass::securityTypeToAuthMode(wifi_setting.security_type); + return securityTypeToAuthMode(wifi_setting.security_type); } diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp index c3fcf1e..80780bc 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp @@ -1,124 +1,60 @@ /* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ -#include "WiFi.h" #include "WiFiPriv.h" -rtw_result_t WiFiClass::scanHandler(rtw_scan_handler_result_t *result) { - WiFiClass *cls = (WiFiClass *)result->user_data; +static rtw_result_t scanHandler(rtw_scan_handler_result_t *result) { + WiFiClass *cls = (WiFiClass *)result->user_data; + WiFiScanData *scan = cls->scan; + if (!scan) + return RTW_SUCCESS; if (result->scan_complete == RTW_TRUE) { - cls->_scanning = false; - xSemaphoreGive(cls->_scanSem); + scan->running = false; + xSemaphoreGive(cls->data.scanSem); return RTW_SUCCESS; } rtw_scan_result_t *net = &result->ap_details; net->SSID.val[net->SSID.len] = '\0'; - uint8_t newSize = cls->_netCount + 1; - cls->_netSsid = (char **)realloc(cls->_netSsid, newSize * sizeof(char *)); - cls->_netEncr = (WiFiAuthMode *)realloc(cls->_netEncr, newSize * sizeof(WiFiAuthMode)); - cls->_netRssi = (int32_t *)realloc(cls->_netRssi, newSize * sizeof(int32_t)); - cls->_netBssid = (rtw_mac_t *)realloc(cls->_netBssid, newSize * sizeof(rtw_mac_t)); - cls->_netChannel = (int32_t *)realloc(cls->_netChannel, newSize * sizeof(int32_t)); + uint8_t newSize = scan->count + 1; + scan->ssid = (char **)realloc(scan->ssid, newSize * sizeof(char *)); + scan->auth = (WiFiAuthMode *)realloc(scan->auth, newSize * sizeof(WiFiAuthMode)); + scan->rssi = (int32_t *)realloc(scan->rssi, newSize * sizeof(int32_t)); + scan->bssid = (WiFiMacAddr *)realloc(scan->bssid, newSize * sizeof(WiFiMacAddr)); + scan->channel = (int32_t *)realloc(scan->channel, newSize * sizeof(int32_t)); - cls->_netSsid[cls->_netCount] = (char *)malloc((net->SSID.len + 1) * sizeof(char)); - strcpy(cls->_netSsid[cls->_netCount], (char *)net->SSID.val); - cls->_netEncr[cls->_netCount] = WiFiClass::securityTypeToAuthMode(net->security); - cls->_netRssi[cls->_netCount] = net->signal_strength; - memcpy(cls->_netBssid[cls->_netCount].octet, net->BSSID.octet, ETH_ALEN); - cls->_netChannel[cls->_netCount] = net->channel; - cls->_netCount++; + scan->ssid[scan->count] = (char *)malloc((net->SSID.len + 1) * sizeof(char)); + strcpy(scan->ssid[scan->count], (char *)net->SSID.val); + scan->auth[scan->count] = securityTypeToAuthMode(net->security); + scan->rssi[scan->count] = net->signal_strength; + memcpy(scan->bssid[scan->count].addr, net->BSSID.octet, ETH_ALEN); + scan->channel[scan->count] = net->channel; + scan->count++; return RTW_SUCCESS; } int16_t WiFiClass::scanNetworks(bool async, bool showHidden, bool passive, uint32_t maxMsPerChannel, uint8_t channel) { - if (_scanning) + if (scan && scan->running) return WIFI_SCAN_RUNNING; if (wifi_mode == WIFI_MODE_NULL) enableSTA(true); scanDelete(); + scanInit(); LT_I("Starting WiFi scan"); if (wifi_scan_networks(scanHandler, this) != RTW_SUCCESS) return WIFI_SCAN_FAILED; - _scanning = true; + scan->running = true; if (!async) { LT_I("Waiting for results"); - xSemaphoreTake(_scanSem, 1); // reset the semaphore quickly - xSemaphoreTake(_scanSem, pdMS_TO_TICKS(maxMsPerChannel * 20)); - return _netCount; + xSemaphoreTake(data.scanSem, 1); // reset the semaphore quickly + xSemaphoreTake(data.scanSem, pdMS_TO_TICKS(maxMsPerChannel * 20)); + return scan->count; } return WIFI_SCAN_RUNNING; } - -bool WiFiClass::getNetworkInfo( - uint8_t networkItem, String &ssid, WiFiAuthMode &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel -) { - ssid = SSID(networkItem); - encType = encryptionType(networkItem); - rssi = RSSI(networkItem); - bssid = BSSID(networkItem); - channel = this->channel(networkItem); -} - -int16_t WiFiClass::scanComplete() { - if (_scanning) - return WIFI_SCAN_RUNNING; - return _netCount; -} - -void WiFiClass::scanDelete() { - for (uint8_t i = 0; i < _netCount; i++) { - free(_netSsid[i]); - } - free(_netSsid); - free(_netEncr); - free(_netRssi); - free(_netBssid); - free(_netChannel); - _netCount = 0; - _netSsid = NULL; - _netEncr = NULL; - _netRssi = NULL; - _netBssid = NULL; - _netChannel = NULL; -} - -String WiFiClass::SSID(uint8_t networkItem) { - if (networkItem >= _netCount) - return ""; - return _netSsid[networkItem]; -} - -WiFiAuthMode WiFiClass::encryptionType(uint8_t networkItem) { - if (networkItem >= _netCount) - return WIFI_AUTH_INVALID; - return _netEncr[networkItem]; -} - -int32_t WiFiClass::RSSI(uint8_t networkItem) { - if (networkItem >= _netCount) - return 0; - return _netRssi[networkItem]; -} - -uint8_t *WiFiClass::BSSID(uint8_t networkItem) { - if (networkItem >= _netCount) - return NULL; - return _netBssid[networkItem].octet; -} - -String WiFiClass::BSSIDstr(uint8_t networkItem) { - return macToString(BSSID(networkItem)); -} - -int32_t WiFiClass::channel(uint8_t networkItem) { - if (networkItem >= _netCount) - return 0; - return _netChannel[networkItem]; -} diff --git a/builder/arduino-common.py b/builder/arduino-common.py index e4b1215..a3ec38c 100644 --- a/builder/arduino-common.py +++ b/builder/arduino-common.py @@ -59,7 +59,7 @@ env.AddLibrary( name="libretuya_api", base_dir=LT_ARDUINO_DIR, srcs=[ - "+", + "+", "+", "+", "+",