diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 10c6ebd448..b6f442e5cf 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -37,6 +37,7 @@ extern "C" { #include "binary.h" #include "esp8266_peri.h" #include "twi.h" +#include "core_esp8266_features.h" #define HIGH 0x1 #define LOW 0x0 @@ -247,8 +248,12 @@ void optimistic_yield(uint32_t interval_us); #include "Updater.h" #include "debug.h" +#ifndef _GLIBCXX_VECTOR +// arduino is not compatible with std::vector #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) +#endif + #define _min(a,b) ((a)<(b)?(a):(b)) #define _max(a,b) ((a)>(b)?(a):(b)) diff --git a/cores/esp8266/IPAddress.h b/cores/esp8266/IPAddress.h index b563c70446..4876358fca 100644 --- a/cores/esp8266/IPAddress.h +++ b/cores/esp8266/IPAddress.h @@ -56,6 +56,9 @@ class IPAddress: public Printable { bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; } + bool operator==(uint32_t addr) const { + return _address.dword == addr; + } bool operator==(const uint8_t* addr) const; // Overloaded index operator to allow getting and setting individual octets of the address diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index ae5d585392..0dc2023834 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -28,6 +28,8 @@ #define CORE_HAS_LIBB64 #define CORE_HAS_BASE64_CLASS +#define WIFI_HAS_EVENT_CALLBACK + #endif diff --git a/libraries/ESP8266WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino b/libraries/ESP8266WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino new file mode 100644 index 0000000000..bdad5be30a --- /dev/null +++ b/libraries/ESP8266WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino @@ -0,0 +1,48 @@ +/* + * This sketch shows the WiFi event usage + * + */ + +#include + +const char* ssid = "your-ssid"; +const char* password = "your-password"; + + +void WiFiEvent(WiFiEvent_t event) { + Serial.printf("[WiFi-event] event: %d\n", event); + + switch(event) { + case WIFI_EVENT_STAMODE_GOT_IP: + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + break; + case WIFI_EVENT_STAMODE_DISCONNECTED: + Serial.println("WiFi lost connection"); + break; + } +} + +void setup() { + Serial.begin(115200); + + // delete old config + WiFi.disconnect(true); + + delay(1000); + + WiFi.onEvent(WiFiEvent); + + WiFi.begin(ssid, password); + + Serial.println(); + Serial.println(); + Serial.println("Wait for WiFi... "); +} + + +void loop() { + delay(1000); +} + diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index a95bd1f7db..5ce0dab93f 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -1,23 +1,26 @@ /* - ESP8266WiFi.cpp - WiFi library for esp8266 + ESP8266WiFi.cpp - WiFi library for esp8266 - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. - 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 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. + 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 -*/ + 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 + + Reworked on 28 Dec 2015 by Markus Sattler + + */ #include "ESP8266WiFi.h" @@ -34,925 +37,23 @@ extern "C" { #include "lwip/dns.h" } -#include "WiFiClient.h" -#include "WiFiUdp.h" #include "debug.h" -extern "C" void esp_schedule(); -extern "C" void esp_yield(); - -ESP8266WiFiClass::ESP8266WiFiClass() -: _smartConfigStarted(false) -, _smartConfigDone(false) -, _useStaticIp(false) -, _persistent(true) -{ - uint8 m = wifi_get_opmode(); - _useClientMode = (m & WIFI_STA); - _useApMode = (m & WIFI_AP); - wifi_set_event_handler_cb((wifi_event_handler_cb_t)&ESP8266WiFiClass::_eventCallback); -} - -void ESP8266WiFiClass::persistent(bool persistent) -{ - _persistent = persistent; -} - - -void ESP8266WiFiClass::mode(WiFiMode m) -{ - if(wifi_get_opmode() == (uint8)m) { - return; - } - - if((m & WIFI_AP)) { - _useApMode = true; - } else { - _useApMode = false; - } - - if((m & WIFI_STA)) { - _useClientMode = true; - } else { - _useClientMode = false; - } - - _mode(m); -} - -WiFiMode ESP8266WiFiClass::getMode() -{ - return (WiFiMode)wifi_get_opmode(); -} - -void ESP8266WiFiClass::_mode(WiFiMode m) -{ - if(wifi_get_opmode() == (uint8)m) { - return; - } - - ETS_UART_INTR_DISABLE(); - if (_persistent) - wifi_set_opmode(m); - else - wifi_set_opmode_current(m); - ETS_UART_INTR_ENABLE(); - -} - -static bool sta_config_equal(const station_config& lhs, const station_config& rhs) -{ - if (strcmp(reinterpret_cast(lhs.ssid), reinterpret_cast(rhs.ssid)) != 0) - return false; - - if (strcmp(reinterpret_cast(lhs.password), reinterpret_cast(rhs.password)) != 0) - return false; - - if (lhs.bssid_set) { - if (!rhs.bssid_set) - return false; - - if (memcmp(lhs.bssid, rhs.bssid, 6) != 0) - return false; - } - else { - if (rhs.bssid_set) - return false; - } - - return true; -} - -int ESP8266WiFiClass::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid) -{ - return begin((const char*) ssid, (const char*) passphrase, channel, bssid); -} - -int ESP8266WiFiClass::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid) -{ - _useClientMode = true; - - if(_useApMode) { - // turn on AP+STA mode - _mode(WIFI_AP_STA); - } else { - // turn on STA mode - _mode(WIFI_STA); - } - - if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) { - // fail SSID too long or missing! - return WL_CONNECT_FAILED; - } - - if(passphrase && strlen(passphrase) > 63) { - // fail passphrase too long! - return WL_CONNECT_FAILED; - } - - struct station_config conf; - strcpy(reinterpret_cast(conf.ssid), ssid); - - if (passphrase) { - strcpy(reinterpret_cast(conf.password), passphrase); - } else { - *conf.password = 0; - } - - if (bssid) { - conf.bssid_set = 1; - memcpy((void *) &conf.bssid[0], (void *) bssid, 6); - } else { - conf.bssid_set = 0; - } - - struct station_config current_conf; - wifi_station_get_config(¤t_conf); - if (sta_config_equal(current_conf, conf)) { - DEBUGV("sta config unchanged"); - return status(); - } - - ETS_UART_INTR_DISABLE(); - if (_persistent) - wifi_station_set_config(&conf); - else - wifi_station_set_config_current(&conf); - wifi_station_connect(); - ETS_UART_INTR_ENABLE(); - - if(channel > 0 && channel <= 13) { - wifi_set_channel(channel); - } - - if(!_useStaticIp) - wifi_station_dhcpc_start(); - return status(); -} - -int ESP8266WiFiClass::begin() -{ - ETS_UART_INTR_DISABLE(); - wifi_station_connect(); - ETS_UART_INTR_ENABLE(); - - if(!_useStaticIp) - wifi_station_dhcpc_start(); - return status(); -} - -uint8_t ESP8266WiFiClass::waitForConnectResult(){ - if ((wifi_get_opmode() & 1) == 0)//1 and 3 have STA enabled - return WL_DISCONNECTED; - while (status() == WL_DISCONNECTED) - delay(100); - return status(); -} - - -// You will have to set the DNS-Server manually later since this will not enable DHCP2 -void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet) -{ - struct ip_info info; - info.ip.addr = static_cast(local_ip); - info.gw.addr = static_cast(gateway); - info.netmask.addr = static_cast(subnet); - - wifi_station_dhcpc_stop(); - wifi_set_ip_info(STATION_IF, &info); - - _useStaticIp = true; -} - -void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns) -{ - struct ip_info info; - info.ip.addr = static_cast(local_ip); - info.gw.addr = static_cast(gateway); - info.netmask.addr = static_cast(subnet); - - wifi_station_dhcpc_stop(); - wifi_set_ip_info(STATION_IF, &info); - - // Set DNS-Server - ip_addr_t d; - d.addr = static_cast(dns); - dns_setserver(0,&d); - - _useStaticIp = true; -} - -int ESP8266WiFiClass::softAPdisconnect(bool wifioff) -{ - struct softap_config conf; - *conf.ssid = 0; - *conf.password = 0; - ETS_UART_INTR_DISABLE(); - if (_persistent) - wifi_softap_set_config(&conf); - else - wifi_softap_set_config_current(&conf); - ETS_UART_INTR_ENABLE(); - - if(wifioff) { - _useApMode = false; - - if( _useClientMode) { - // turn on STA - _mode(WIFI_STA); - } else { - // turn wifi off - _mode(WIFI_OFF); - } - } - - return 0; -} - -int ESP8266WiFiClass::disconnect(bool wifioff) -{ - struct station_config conf; - *conf.ssid = 0; - *conf.password = 0; - ETS_UART_INTR_DISABLE(); - if (_persistent) - wifi_station_set_config(&conf); - else - wifi_station_set_config_current(&conf); - wifi_station_disconnect(); - ETS_UART_INTR_ENABLE(); - - if(wifioff) { - _useClientMode = false; - - if(_useApMode) { - // turn on AP - _mode(WIFI_AP); - } else { - // turn wifi off - _mode(WIFI_OFF); - } - } - - return 0; -} - -static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs) -{ - if (strcmp(reinterpret_cast(lhs.ssid), reinterpret_cast(rhs.ssid)) != 0) - return false; - if (strcmp(reinterpret_cast(lhs.password), reinterpret_cast(rhs.password)) != 0) - return false; - if (lhs.channel != rhs.channel) - return false; - if (lhs.ssid_hidden != rhs.ssid_hidden) - return false; - return true; -} - - -void ESP8266WiFiClass::softAP(const char* ssid) -{ - softAP(ssid, 0); -} - - -void ESP8266WiFiClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden) -{ - _useApMode = true; - if(_useClientMode) { - // turn on AP+STA mode - _mode(WIFI_AP_STA); - } else { - // turn on STA mode - _mode(WIFI_AP); - } - - if(!ssid || *ssid == 0 || strlen(ssid) > 31) { - // fail SSID too long or missing! - return; - } - - if(passphrase && strlen(passphrase) > 63) { - // fail passphrase to long! - return; - } - - struct softap_config conf; - wifi_softap_get_config(&conf); - strcpy(reinterpret_cast(conf.ssid), ssid); - conf.channel = channel; - conf.ssid_len = strlen(ssid); - conf.ssid_hidden = ssid_hidden; - conf.max_connection = 4; - conf.beacon_interval = 100; - - if (!passphrase || strlen(passphrase) == 0) - { - conf.authmode = AUTH_OPEN; - *conf.password = 0; - } - else - { - conf.authmode = AUTH_WPA2_PSK; - strcpy(reinterpret_cast(conf.password), passphrase); - } - - struct softap_config conf_current; - wifi_softap_get_config(&conf_current); - if (softap_config_equal(conf, conf_current)) - { - DEBUGV("softap config unchanged"); - return; - } - - ETS_UART_INTR_DISABLE(); - if (_persistent) - wifi_softap_set_config(&conf); - else - wifi_softap_set_config_current(&conf); - ETS_UART_INTR_ENABLE(); -} - -void ESP8266WiFiClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) -{ - struct ip_info info; - info.ip.addr = static_cast(local_ip); - info.gw.addr = static_cast(gateway); - info.netmask.addr = static_cast(subnet); - wifi_softap_dhcps_stop(); - wifi_set_ip_info(SOFTAP_IF, &info); - wifi_softap_dhcps_start(); -} - -uint8_t* ESP8266WiFiClass::macAddress(uint8_t* mac) -{ - wifi_get_macaddr(STATION_IF, mac); - return mac; -} - -String ESP8266WiFiClass::macAddress(void) -{ - uint8_t mac[6]; - char macStr[18] = {0}; - wifi_get_macaddr(STATION_IF, mac); - - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); -} - -uint8_t* ESP8266WiFiClass::softAPmacAddress(uint8_t* mac) -{ - wifi_get_macaddr(SOFTAP_IF, mac); - return mac; -} - -String ESP8266WiFiClass::softAPmacAddress(void) -{ - uint8_t mac[6]; - char macStr[18] = {0}; - wifi_get_macaddr(SOFTAP_IF, mac); - - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); -} - -IPAddress ESP8266WiFiClass::localIP() -{ - struct ip_info ip; - wifi_get_ip_info(STATION_IF, &ip); - return IPAddress(ip.ip.addr); -} - -IPAddress ESP8266WiFiClass::softAPIP() -{ - struct ip_info ip; - wifi_get_ip_info(SOFTAP_IF, &ip); - return IPAddress(ip.ip.addr); -} - -IPAddress ESP8266WiFiClass::subnetMask() -{ - struct ip_info ip; - wifi_get_ip_info(STATION_IF, &ip); - return IPAddress(ip.netmask.addr); -} - -IPAddress ESP8266WiFiClass::gatewayIP() -{ - struct ip_info ip; - wifi_get_ip_info(STATION_IF, &ip); - return IPAddress(ip.gw.addr); -} - -IPAddress ESP8266WiFiClass::dnsIP(int dns_no) -{ - ip_addr_t dns_ip = dns_getserver(dns_no); - return IPAddress(dns_ip.addr); -} - -String ESP8266WiFiClass::SSID() const -{ - static struct station_config conf; - wifi_station_get_config(&conf); - return String(reinterpret_cast(conf.ssid)); -} - -String ESP8266WiFiClass::psk() const -{ - static struct station_config conf; - wifi_station_get_config(&conf); - return String(reinterpret_cast(conf.password)); -} - -uint8_t* ESP8266WiFiClass::BSSID(void) -{ - static struct station_config conf; - wifi_station_get_config(&conf); - return reinterpret_cast(conf.bssid); -} - -String ESP8266WiFiClass::BSSIDstr(void) -{ - static struct station_config conf; - char mac[18] = {0}; - wifi_station_get_config(&conf); - sprintf(mac,"%02X:%02X:%02X:%02X:%02X:%02X", conf.bssid[0], conf.bssid[1], conf.bssid[2], conf.bssid[3], conf.bssid[4], conf.bssid[5]); - return String(mac); -} - - -int32_t ESP8266WiFiClass::channel(void) { - return wifi_get_channel(); -} - - -int32_t ESP8266WiFiClass::RSSI(void) { - return wifi_station_get_rssi(); -} - -extern "C" -{ - typedef STAILQ_HEAD(, bss_info) bss_info_head_t; -} - -void ESP8266WiFiClass::_scanDone(void* result, int status) -{ - if (status != OK) - { - ESP8266WiFiClass::_scanCount = 0; - ESP8266WiFiClass::_scanResult = 0; - } - else - { - - int i = 0; - bss_info_head_t* head = reinterpret_cast(result); +// ----------------------------------------------------------------------------------------------------------------------- +// ---------------------------------------------------------- Debug ------------------------------------------------------ +// ----------------------------------------------------------------------------------------------------------------------- - for (bss_info* it = STAILQ_FIRST(head); it; it = STAILQ_NEXT(it, next), ++i); - ESP8266WiFiClass::_scanCount = i; - if (i == 0) - { - ESP8266WiFiClass::_scanResult = 0; - } - else - { - bss_info* copied_info = new bss_info[i]; - i = 0; - for (bss_info* it = STAILQ_FIRST(head); it; it = STAILQ_NEXT(it, next), ++i) - { - memcpy(copied_info + i, it, sizeof(bss_info)); - } - - ESP8266WiFiClass::_scanResult = copied_info; - } - - } - - ESP8266WiFiClass::_scanStarted = false; - ESP8266WiFiClass::_scanComplete = true; - - if(!ESP8266WiFiClass::_scanAsync) { - esp_schedule(); - } -} - -int8_t ESP8266WiFiClass::scanComplete() { - - if(_scanStarted) { - return WIFI_SCAN_RUNNING; - } - - if(_scanComplete) { - return ESP8266WiFiClass::_scanCount; - } - - return WIFI_SCAN_FAILED; -} - -void ESP8266WiFiClass::scanDelete() -{ - if (ESP8266WiFiClass::_scanResult) - { - delete[] reinterpret_cast(ESP8266WiFiClass::_scanResult); - ESP8266WiFiClass::_scanResult = 0; - ESP8266WiFiClass::_scanCount = 0; - } - _scanComplete = false; -} - -int8_t ESP8266WiFiClass::scanNetworks(bool async, bool show_hidden) -{ - if(ESP8266WiFiClass::_scanStarted) { - return WIFI_SCAN_RUNNING; - } - - ESP8266WiFiClass::_scanAsync = async; - - if(_useApMode) { - // turn on AP+STA mode - _mode(WIFI_AP_STA); - } else { - // turn on STA mode - _mode(WIFI_STA); - } - - int status = wifi_station_get_connect_status(); - if (status != STATION_GOT_IP && status != STATION_IDLE) - { - disconnect(); - } - - scanDelete(); - - struct scan_config config; - config.ssid = 0; - config.bssid = 0; - config.channel = 0; - config.show_hidden = show_hidden; - if(wifi_station_scan(&config, reinterpret_cast(&ESP8266WiFiClass::_scanDone))) { - ESP8266WiFiClass::_scanComplete = false; - ESP8266WiFiClass::_scanStarted = true; - - if(ESP8266WiFiClass::_scanAsync) { - delay(0); // time for the OS to trigger the scan - return WIFI_SCAN_RUNNING; - } - - esp_yield(); - return ESP8266WiFiClass::_scanCount; - } else { - return WIFI_SCAN_FAILED; - } - -} - -void * ESP8266WiFiClass::_getScanInfoByIndex(int i) -{ - if (!ESP8266WiFiClass::_scanResult || (size_t)i > ESP8266WiFiClass::_scanCount) - { - return 0; - } - - return reinterpret_cast(ESP8266WiFiClass::_scanResult) + i; -} - -String ESP8266WiFiClass::SSID(uint8_t i) -{ - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return ""; - - return String(reinterpret_cast(it->ssid)); -} - -uint8_t * ESP8266WiFiClass::BSSID(uint8_t i) -{ - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return 0; - - return it->bssid; -} - -String ESP8266WiFiClass::BSSIDstr(uint8_t i) -{ - char mac[18] = {0}; - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return String(""); - - sprintf(mac,"%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]); - return String(mac); -} - -int32_t ESP8266WiFiClass::channel(uint8_t i) -{ - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return 0; - - return it->channel; -} - -bool ESP8266WiFiClass::isHidden(uint8_t i) -{ - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return false; - - return (it->is_hidden != 0); -} - -bool ESP8266WiFiClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &isHidden) -{ - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return false; - - ssid = (const char*)it->ssid; - encType = encryptionType(i); - rssi = it->rssi; - bssid = it->bssid; // move ptr - channel = it->channel; - isHidden = (it->is_hidden != 0); - - return true; -} - -int32_t ESP8266WiFiClass::RSSI(uint8_t i) -{ - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return 0; - - return it->rssi; -} - -uint8_t ESP8266WiFiClass::encryptionType(uint8_t i) -{ - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if (!it) - return -1; - - int authmode = it->authmode; - if (authmode == AUTH_OPEN) - return ENC_TYPE_NONE; - if (authmode == AUTH_WEP) - return ENC_TYPE_WEP; - if (authmode == AUTH_WPA_PSK) - return ENC_TYPE_TKIP; - if (authmode == AUTH_WPA2_PSK) - return ENC_TYPE_CCMP; - if (authmode == AUTH_WPA_WPA2_PSK) - return ENC_TYPE_AUTO; - return -1; -} - -wl_status_t ESP8266WiFiClass::status() -{ - int status = wifi_station_get_connect_status(); - - if (status == STATION_GOT_IP) - return WL_CONNECTED; - else if (status == STATION_NO_AP_FOUND) - return WL_NO_SSID_AVAIL; - else if (status == STATION_CONNECT_FAIL || status == STATION_WRONG_PASSWORD) - return WL_CONNECT_FAILED; - else if (status == STATION_IDLE) - return WL_IDLE_STATUS; - else - return WL_DISCONNECTED; -} - -void wifi_dns_found_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg) -{ - if (ipaddr) - (*reinterpret_cast(callback_arg)) = ipaddr->addr; - esp_schedule(); // resume the hostByName function -} - -int ESP8266WiFiClass::hostByName(const char* aHostname, IPAddress& aResult) -{ - ip_addr_t addr; - aResult = static_cast(0); - err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); - if (err == ERR_OK) - { - aResult = addr.addr; - } - else if (err == ERR_INPROGRESS) - { - esp_yield(); - // will return here when dns_found_callback fires - } - - return (aResult != 0) ? 1 : 0; -} - -String ESP8266WiFiClass::hostname(void) { - return String(wifi_station_get_hostname()); -} - -bool ESP8266WiFiClass::hostname(char* aHostname) { - if(strlen(aHostname) > 32) { - return false; - } - return wifi_station_set_hostname(aHostname); -} - -bool ESP8266WiFiClass::hostname(const char* aHostname) { - return hostname((char*) aHostname); -} - -bool ESP8266WiFiClass::hostname(String aHostname) { - return hostname((char*) aHostname.c_str()); -} - -//-------------------------------------------------------------- - -void wifi_wps_status_cb(wps_cb_status status) -{ - DEBUGV("wps cb status: %d\r\n", status); - switch (status) { - case WPS_CB_ST_SUCCESS: - if(!wifi_wps_disable()) { - DEBUGV("wps disable failed\n"); - } - wifi_station_connect(); - break; - case WPS_CB_ST_FAILED: - DEBUGV("wps FAILED\n"); - break; - case WPS_CB_ST_TIMEOUT: - DEBUGV("wps TIMEOUT\n"); - break; - case WPS_CB_ST_WEP: - DEBUGV("wps WEP\n"); - break; - } - // todo user function to get status - - esp_schedule(); // resume the beginWPSConfig function -} - -bool ESP8266WiFiClass::beginWPSConfig(void) { - - _useClientMode = true; - - if(_useApMode) { - // turn on AP+STA mode - _mode(WIFI_AP_STA); - } else { - // turn on STA mode - _mode(WIFI_STA); - } - - disconnect(); - - DEBUGV("wps begin\n"); - - if(!wifi_wps_disable()) { - DEBUGV("wps disable failed\n"); - return false; - } - - // so far only WPS_TYPE_PBC is supported (SDK 1.2.0) - if(!wifi_wps_enable(WPS_TYPE_PBC)) { - DEBUGV("wps enable failed\n"); - return false; - } - - if(!wifi_set_wps_cb((wps_st_cb_t) &wifi_wps_status_cb)) { - DEBUGV("wps cb failed\n"); - return false; - } - - if(!wifi_wps_start()) { - DEBUGV("wps start failed\n"); - return false; - } - - esp_yield(); - // will return here when wifi_wps_status_cb fires - - return true; -} - -//-------------------------------------------------------------- - - - -void ESP8266WiFiClass::beginSmartConfig() -{ - if (_smartConfigStarted) - return; - - if(_useApMode) { - // turn on AP+STA mode - _mode(WIFI_AP_STA); - } else { - // turn on STA mode - _mode(WIFI_STA); - } - - _smartConfigStarted = true; - _smartConfigDone = false; - - //SC_TYPE_ESPTOUCH use ESPTOUCH for smartconfig, or use SC_TYPE_AIRKISS for AIRKISS - smartconfig_start(reinterpret_cast(&ESP8266WiFiClass::_smartConfigCallback), 1); -} - -void ESP8266WiFiClass::stopSmartConfig() -{ - if (!_smartConfigStarted) - return; - - smartconfig_stop(); - _smartConfigStarted = false; -} - -bool ESP8266WiFiClass::smartConfigDone() -{ - if (!_smartConfigStarted) - return false; - - return _smartConfigDone; -} - -void ESP8266WiFiClass::_smartConfigCallback(uint32_t st, void* result) -{ - sc_status status = (sc_status) st; - if (status == SC_STATUS_LINK) { - station_config* sta_conf = reinterpret_cast(result); - - wifi_station_set_config(sta_conf); - wifi_station_disconnect(); - wifi_station_connect(); - - WiFi._smartConfigDone = true; - } - else if (status == SC_STATUS_LINK_OVER) { - WiFi.stopSmartConfig(); - } -} - - -//-------------------------------------------------------------- - -/** - * set Sleep mode - * @param type sleep_type_t - * @return bool - */ -bool ESP8266WiFiClass::setSleepMode(WiFiSleepType_t type) { - return wifi_set_sleep_type((sleep_type_t)type); -} /** - * get Sleep mode - * @return sleep_type_t + * Output WiFi settings to an object derived from Print interface (like Serial). + * @param p Print interface */ -WiFiSleepType_t ESP8266WiFiClass::getSleepMode() { - return (WiFiSleepType_t)wifi_get_sleep_type(); -} - -/** - * set phy Mode - * @param mode phy_mode_t - * @return bool - */ -bool ESP8266WiFiClass::setPhyMode(WiFiPhyMode_t mode) { - return wifi_set_phy_mode((phy_mode_t)mode); -} - -/** - * get phy Mode - * @return phy_mode_t - */ -WiFiPhyMode_t ESP8266WiFiClass::getPhyMode() { - return (WiFiPhyMode_t)wifi_get_phy_mode(); -} - -//-------------------------------------------------------------- - -void ESP8266WiFiClass::_eventCallback(void* arg) -{ - System_Event_t* event = reinterpret_cast(arg); - DEBUGV("wifi evt: %d\r\n", event->event); - - if (event->event == EVENT_STAMODE_DISCONNECTED) { - WiFiClient::stopAll(); - } -} - -void ESP8266WiFiClass::printDiag(Print& p) -{ - const char* modes[] = {"NULL", "STA", "AP", "STA+AP"}; +void ESP8266WiFiClass::printDiag(Print& p) { + const char* modes[] = { "NULL", "STA", "AP", "STA+AP" }; p.print("Mode: "); p.println(modes[wifi_get_opmode()]); - const char* phymodes[] = {"", "B", "G", "N"}; + const char* phymodes[] = { "", "B", "G", "N" }; p.print("PHY mode: "); p.println(phymodes[(int) wifi_get_phy_mode()]); @@ -968,7 +69,7 @@ void ESP8266WiFiClass::printDiag(Print& p) p.print("Auto connect: "); p.println(wifi_station_get_auto_connect()); - static struct station_config conf; + struct station_config conf; wifi_station_get_config(&conf); const char* ssid = reinterpret_cast(conf.ssid); @@ -988,12 +89,4 @@ void ESP8266WiFiClass::printDiag(Print& p) } -bool ESP8266WiFiClass::_scanAsync = false; -bool ESP8266WiFiClass::_scanStarted = false; -bool ESP8266WiFiClass::_scanComplete = false; - -size_t ESP8266WiFiClass::_scanCount = 0; -void* ESP8266WiFiClass::_scanResult = 0; - - ESP8266WiFiClass WiFi; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 5a7fe54c18..4e6ce8e042 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -1,23 +1,23 @@ /* - ESP8266WiFi.h - esp8266 Wifi support. - Based on WiFi.h from Ardiono 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 -*/ + ESP8266WiFi.h - esp8266 Wifi support. + Based on WiFi.h from Ardiono 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 + */ #ifndef WiFi_h #define WiFi_h @@ -25,415 +25,50 @@ #include extern "C" { - #include "include/wl_definitions.h" +#include "include/wl_definitions.h" } #include "IPAddress.h" + +#include "ESP8266WiFiType.h" +#include "ESP8266WiFiSTA.h" +#include "ESP8266WiFiAP.h" +#include "ESP8266WiFiScan.h" +#include "ESP8266WiFiGeneric.h" + #include "WiFiClient.h" #include "WiFiServer.h" #include "WiFiClientSecure.h" -#define WIFI_SCAN_RUNNING (-1) -#define WIFI_SCAN_FAILED (-2) - - -// Note: -// this enums need to be in sync with the SDK! - -enum WiFiMode { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 }; - -typedef enum { - WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3 -} WiFiPhyMode_t; - -typedef enum { - WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 2, WIFI_MODEM_SLEEP = 3 -} WiFiSleepType_t; - - -class ESP8266WiFiClass -{ -public: - - ESP8266WiFiClass(); - - void persistent(bool persistent); - - void mode(WiFiMode); - WiFiMode getMode(); - - /** - * Start Wifi connection - * if passphrase is set the most secure supported mode will be automatically selected - * @param ssid const char* Pointer to the SSID string. - * @param passphrase const char * Optional. Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal). - * @param bssid uint8_t[6] Optional. BSSID / MAC of AP - * @param channel Optional. Channel of AP - * @return - */ - int begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL); - int begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL); - - // Use sdk config to connect. - int begin(); - - - /* Wait for Wifi connection to reach a result - * returns the status reached or disconnect if STA is off - */ - uint8_t waitForConnectResult(); - - /* Set up an open access point - * - * param ssid: Pointer to the SSID string. - */ - void softAP(const char* ssid); - - - /* Set up a WPA2-secured access point - * - * param ssid: Pointer to the SSID string. - * param passphrase: Pointer to passphrase, 8 characters min. - * param channel: WiFi channel number, 1 - 13. - * param ssid_hidden: Network cloaking? 0 = broadcast SSID, 1 = hide SSID - */ - void softAP(const char* ssid, const char* passphrase, int channel = 1, int ssid_hidden = 0); - - /* Change Ip configuration settings disabling the dhcp client - * - * param local_ip: Static ip configuration - * param gateway: Static gateway configuration - * param subnet: Static Subnet mask - */ - void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet); - - /* Change Ip configuration settings disabling the dhcp client - * - * param local_ip: Static ip configuration - * param gateway: Static gateway configuration - * param subnet: Static Subnet mask - * param dns: Defined DNS - */ - void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns); - - /* Configure access point - * - * param local_ip: access point IP - * param gateway: gateway IP - * param subnet: subnet mask - */ - void softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet); - - /* - * Disconnect from the network (close AP) - * - * return: one value of wl_status_t enum - */ - int softAPdisconnect(bool wifioff = false); - - /* - * Disconnect from the network - * - * return: one value of wl_status_t enum - */ - int disconnect(bool wifioff = false); - - /* - * Get the station interface MAC address. - * - * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH - * return: String - */ - uint8_t* macAddress(uint8_t* mac); - String macAddress(void); - - /* - * Get the softAP interface MAC address. - * - * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH - * return: String - */ - uint8_t* softAPmacAddress(uint8_t* mac); - String softAPmacAddress(void); - - /* - * Get the station interface IP address. - * - * return: Ip address value - */ - IPAddress localIP(); - - /* - * Get the softAP interface IP address. - * - * return: Ip address value - */ - IPAddress softAPIP(); - - /* - * Get the interface subnet mask address. - * - * return: subnet mask address value - */ - IPAddress subnetMask(); - - /* - * Get the gateway ip address. - * - * return: gateway ip address value - */ - IPAddress gatewayIP(); - - /* - * Get the DNS ip address. - * - * return: DNS ip address value - */ - IPAddress dnsIP(int dns_no = 0); - - /* - * Return the current SSID associated with the network - * - * return: ssid string - */ - String SSID() const; - - /* - * Return the current pre shared key associated with the network - * - * return: psk string - */ - String psk() const; - - /* - * Return the current bssid / mac associated with the network if configured - * - * return: bssid uint8_t * - */ - uint8_t *BSSID(void); - - /* - * Return the current bssid / mac associated with the network if configured - * - * return: bssid string - */ - String BSSIDstr(void); - - /* - * Return the current channel associated with the network - * - * return: channel - */ - int32_t channel(void); - - /* - * Return the current network RSSI. - * - * return: RSSI value - */ - - int32_t RSSI(); - - - /* - * called to get the scan state in Async mode - * - * return -1 if scan not fin - * return -2 if scan not triggered - */ - int8_t scanComplete(); - - /* - * delete last scan result from RAM - */ - void scanDelete(); - - /* - * Start scan WiFi networks available - * - * return: Number of discovered networks - */ - int8_t scanNetworks(bool async = false, bool show_hidden = false); - - /* - * Return the SSID discovered during the network scan. - * - * param networkItem: specify from which network item want to get the information - * - * return: ssid string of the specified item on the networks scanned list - */ - String SSID(uint8_t networkItem); - - /* - * Return the encryption type of the networks discovered during the scanNetworks - * - * param networkItem: specify from which network item want to get the information - * - * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list - */ - uint8_t encryptionType(uint8_t networkItem); - - /* - * Return the RSSI of the networks discovered during the scanNetworks - * - * param networkItem: specify from which network item want to get the information - * - * return: signed value of RSSI of the specified item on the networks scanned list - */ - int32_t RSSI(uint8_t networkItem); - - - /** - * return MAC / BSSID of scanned wifi - * @param networkItem specify from which network item want to get the information - * @return uint8_t * MAC / BSSID of scanned wifi - */ - uint8_t * BSSID(uint8_t networkItem); - - /** - * return MAC / BSSID of scanned wifi - * @param networkItem specify from which network item want to get the information - * @return String MAC / BSSID of scanned wifi - */ - String BSSIDstr(uint8_t networkItem); - - /** - * return channel of scanned wifi - * @param networkItem specify from which network item want to get the information - * @return uint32_t channel of scanned wifi - */ - int32_t channel(uint8_t networkItem); - - /** - * return if the scanned wifi is Hidden (no SSID) - * @param networkItem specify from which network item want to get the information - * @return bool (true == hidden) - */ - bool isHidden(uint8_t networkItem); - - /** - * loads all infos from a scanned wifi in to the ptr parameters - * @param networkItem uint8_t - * @param ssid const char** - * @param encryptionType uint8_t * - * @param RSSI int32_t * - * @param BSSID uint8_t ** - * @param channel int32_t * - * @param isHidden bool * - * @return (true if ok) - */ - bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden); - - - /* - * Return Connection status. - * - * return: one of the value defined in wl_status_t - */ - wl_status_t status(); - - /* - * Resolve the given hostname to an IP address. - * param aHostname: Name to be resolved - * param aResult: IPAddress structure to store the returned IP address - * result: 1 if aIPAddrString was successfully converted to an IP address, - * else error code - */ - int hostByName(const char* aHostname, IPAddress& aResult); - - /* - * Get ESP8266 station DHCP hostname - */ - String hostname(void); - - /* - * Set ESP8266 station DHCP hostname - * hostname, max length:32 - */ - bool hostname(char* aHostname); - bool hostname(const char* aHostname); - bool hostname(String aHostname); - - - /** - * WPS config - * so far only WPS_TYPE_PBC is supported (SDK 1.2.0) - */ - bool beginWPSConfig(void); - - /* - * Output WiFi settings to an object derived from Print interface (like Serial). - * - */ - void printDiag(Print& dest); - - /* - * Start SmartConfig - * - */ - void beginSmartConfig(); - - /* - * Query SmartConfig status, to decide when stop config - * - */ - bool smartConfigDone(); - - /* - * Stop SmartConfig - * - */ - void stopSmartConfig(); - - friend class WiFiClient; - friend class WiFiServer; - - /** - * set Sleep mode - * @param type WiFiPhyMode_t - * @return bool - */ - bool setSleepMode(WiFiSleepType_t type); +class ESP8266WiFiClass : public ESP8266WiFiGenericClass, public ESP8266WiFiSTAClass, public ESP8266WiFiScanClass, public ESP8266WiFiAPClass { + public: - /** - * get Sleep mode - * @return sleep_type_t - */ - WiFiSleepType_t getSleepMode(); + // workaround same function name with different signature + using ESP8266WiFiGenericClass::channel; - /** - * set phy Mode - * @param mode phy_mode_t - * @return bool - */ - bool setPhyMode(WiFiPhyMode_t mode); + using ESP8266WiFiSTAClass::SSID; + using ESP8266WiFiSTAClass::RSSI; + using ESP8266WiFiSTAClass::BSSID; + using ESP8266WiFiSTAClass::BSSIDstr; - /** - * get phy Mode - * @return phy_mode_t - */ - WiFiPhyMode_t getPhyMode(); + using ESP8266WiFiScanClass::SSID; + using ESP8266WiFiScanClass::encryptionType; + using ESP8266WiFiScanClass::RSSI; + using ESP8266WiFiScanClass::BSSID; + using ESP8266WiFiScanClass::BSSIDstr; + using ESP8266WiFiScanClass::channel; + using ESP8266WiFiScanClass::isHidden; -protected: - void _mode(WiFiMode); - static void _scanDone(void* result, int status); - void * _getScanInfoByIndex(int i); - static void _smartConfigCallback(uint32_t status, void* result); - static void _eventCallback(void *event); - bool _smartConfigStarted; - bool _smartConfigDone; + // ---------------------------------------------------------------------------------------------- + // ------------------------------------------- Debug -------------------------------------------- + // ---------------------------------------------------------------------------------------------- - bool _useApMode; - bool _useClientMode; - bool _useStaticIp; - bool _persistent; + public: - static bool _scanAsync; - static bool _scanStarted; - static bool _scanComplete; + void printDiag(Print& dest); - static size_t _scanCount; - static void* _scanResult; + friend class WiFiClient; + friend class WiFiServer; }; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp new file mode 100644 index 0000000000..6c911263ab --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp @@ -0,0 +1,230 @@ +/* + ESP8266WiFiSTA.cpp - WiFi library for esp8266 + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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 + + Reworked on 28 Dec 2015 by Markus Sattler + + */ + +#include "ESP8266WiFi.h" +#include "ESP8266WiFiGeneric.h" +#include "ESP8266WiFiAP.h" + +extern "C" { +#include "c_types.h" +#include "ets_sys.h" +#include "os_type.h" +#include "osapi.h" +#include "mem.h" +#include "user_interface.h" +} + +#include "debug.h" + + + +// ----------------------------------------------------------------------------------------------------------------------- +// ---------------------------------------------------- Private functions ------------------------------------------------ +// ----------------------------------------------------------------------------------------------------------------------- + +static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs); + + + +/** + * compare two AP configurations + * @param lhs softap_config + * @param rhs softap_config + * @return equal + */ +static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs) { + if(strcmp(reinterpret_cast(lhs.ssid), reinterpret_cast(rhs.ssid)) != 0) { + return false; + } + if(strcmp(reinterpret_cast(lhs.password), reinterpret_cast(rhs.password)) != 0) { + return false; + } + if(lhs.channel != rhs.channel) { + return false; + } + if(lhs.ssid_hidden != rhs.ssid_hidden) { + return false; + } + return true; +} + +// ----------------------------------------------------------------------------------------------------------------------- +// ----------------------------------------------------- AP function ----------------------------------------------------- +// ----------------------------------------------------------------------------------------------------------------------- + + +/** + * Set up an access point + * @param ssid Pointer to the SSID (max 63 char). + * @param passphrase (for WPA2 min 8 char, for open use NULL) + * @param channel WiFi channel number, 1 - 13. + * @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID) + */ +bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden) { + + if(!WiFi.enableAP(true)) { + // enable AP failed + return false; + } + + if(!ssid || *ssid == 0 || strlen(ssid) > 31) { + // fail SSID too long or missing! + return false; + } + + if(passphrase && (strlen(passphrase) > 63 || strlen(passphrase) < 8)) { + // fail passphrase to long or short! + return false; + } + + struct softap_config conf; + strcpy(reinterpret_cast(conf.ssid), ssid); + conf.channel = channel; + conf.ssid_len = strlen(ssid); + conf.ssid_hidden = ssid_hidden; + conf.max_connection = 4; + conf.beacon_interval = 100; + + if(!passphrase || strlen(passphrase) == 0) { + conf.authmode = AUTH_OPEN; + *conf.password = 0; + } else { + conf.authmode = AUTH_WPA2_PSK; + strcpy(reinterpret_cast(conf.password), passphrase); + } + + struct softap_config conf_current; + wifi_softap_get_config(&conf_current); + if(softap_config_equal(conf, conf_current)) { + DEBUGV("softap config unchanged"); + return true; + } + + bool ret; + + ETS_UART_INTR_DISABLE(); + if(WiFi._persistent) { + ret = wifi_softap_set_config(&conf); + } else { + ret = wifi_softap_set_config_current(&conf); + } + ETS_UART_INTR_ENABLE(); + + return ret; +} + + +/** + * Configure access point + * @param local_ip access point IP + * @param gateway gateway IP + * @param subnet subnet mask + */ +bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) { + + if(!WiFi.enableAP(true)) { + // enable AP failed + return false; + } + + struct ip_info info; + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + wifi_softap_dhcps_stop(); + if(wifi_set_ip_info(SOFTAP_IF, &info)) { + return wifi_softap_dhcps_start(); + } + return false; +} + + + +/** + * Disconnect from the network (close AP) + * @param wifioff disable mode? + * @return one value of wl_status_t enum + */ +bool ESP8266WiFiAPClass::softAPdisconnect(bool wifioff) { + bool ret; + struct softap_config conf; + *conf.ssid = 0; + *conf.password = 0; + ETS_UART_INTR_DISABLE(); + if(WiFi._persistent) { + ret = wifi_softap_set_config(&conf); + } else { + ret = wifi_softap_set_config_current(&conf); + } + ETS_UART_INTR_ENABLE(); + + if(wifioff) { + ret = WiFi.enableAP(false); + } + + return ret; +} + + +/** + * Get the count of the Station / client that are connected to the softAP interface + * @return Stations count + */ +uint8_t ESP8266WiFiAPClass::softAPgetStationNum() { + return wifi_softap_get_station_num(); +} + +/** + * Get the softAP interface IP address. + * @return IPAddress softAP IP + */ +IPAddress ESP8266WiFiAPClass::softAPIP() { + struct ip_info ip; + wifi_get_ip_info(SOFTAP_IF, &ip); + return IPAddress(ip.ip.addr); +} + + +/** + * Get the softAP interface MAC address. + * @param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + * @return pointer to uint8_t* + */ +uint8_t* ESP8266WiFiAPClass::softAPmacAddress(uint8_t* mac) { + wifi_get_macaddr(SOFTAP_IF, mac); + return mac; +} + +/** + * Get the softAP interface MAC address. + * @return String mac + */ +String ESP8266WiFiAPClass::softAPmacAddress(void) { + uint8_t mac[6]; + char macStr[18] = { 0 }; + wifi_get_macaddr(SOFTAP_IF, mac); + + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiAP.h b/libraries/ESP8266WiFi/src/ESP8266WiFiAP.h new file mode 100644 index 0000000000..e248d81f85 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiAP.h @@ -0,0 +1,54 @@ +/* + ESP8266WiFiAP.h - esp8266 Wifi support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + Modified by Ivan Grokhotkov, December 2014 + Reworked by Markus Sattler, December 2015 + + 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 + */ + +#ifndef ESP8266WIFIAP_H_ +#define ESP8266WIFIAP_H_ + + +#include "ESP8266WiFiType.h" +#include "ESP8266WiFiGeneric.h" + + +class ESP8266WiFiAPClass { + + // ---------------------------------------------------------------------------------------------- + // ----------------------------------------- AP function ---------------------------------------- + // ---------------------------------------------------------------------------------------------- + + public: + + bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0); + bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet); + bool softAPdisconnect(bool wifioff = false); + + uint8_t softAPgetStationNum(); + + IPAddress softAPIP(); + + uint8_t* softAPmacAddress(uint8_t* mac); + String softAPmacAddress(void); + + protected: + +}; + +#endif /* ESP8266WIFIAP_H_*/ diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp new file mode 100644 index 0000000000..79f80c1aff --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -0,0 +1,343 @@ +/* + ESP8266WiFiGeneric.cpp - WiFi library for esp8266 + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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 + + Reworked on 28 Dec 2015 by Markus Sattler + + */ + +#include "ESP8266WiFi.h" +#include "ESP8266WiFiGeneric.h" + +extern "C" { +#include "c_types.h" +#include "ets_sys.h" +#include "os_type.h" +#include "osapi.h" +#include "mem.h" +#include "user_interface.h" + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/dns.h" +} + +#include "WiFiClient.h" +#include "WiFiUdp.h" + +#include "debug.h" + +#undef min +#undef max +#include + +extern "C" void esp_schedule(); +extern "C" void esp_yield(); + +// ----------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------- Generic WiFi function ----------------------------------------------- +// ----------------------------------------------------------------------------------------------------------------------- + +// arduino dont like std::vectors move static here +static std::vector cbEventList; + +bool ESP8266WiFiGenericClass::_persistent = true; +WiFiMode_t ESP8266WiFiGenericClass::_forceSleepLastMode = WIFI_OFF; + +ESP8266WiFiGenericClass::ESP8266WiFiGenericClass() { + wifi_set_event_handler_cb((wifi_event_handler_cb_t) &ESP8266WiFiGenericClass::_eventCallback); +} + +/** + * set callback function + * @param cbEvent WiFiEventCb + * @param event optional filter (WIFI_EVENT_MAX is all events) + */ +void ESP8266WiFiGenericClass::onEvent(WiFiEventCb cbEvent, WiFiEvent_t event) { + if(!cbEvent) { + return; + } + WiFiEventCbList_t newEventHandler; + newEventHandler.cb = cbEvent; + newEventHandler.event = event; + cbEventList.push_back(newEventHandler); +} + +/** + * removes a callback form event handler + * @param cbEvent WiFiEventCb + * @param event optional filter (WIFI_EVENT_MAX is all events) + */ +void ESP8266WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event) { + if(!cbEvent) { + return; + } + + for(uint32_t i = 0; i < cbEventList.size(); i++) { + WiFiEventCbList_t entry = cbEventList[i]; + if(entry.cb == cbEvent && entry.event == event) { + cbEventList.erase(cbEventList.begin() + i); + } + } +} + +/** + * callback for WiFi events + * @param arg + */ +void ESP8266WiFiGenericClass::_eventCallback(void* arg) { + System_Event_t* event = reinterpret_cast(arg); + DEBUGV("wifi evt: %d\n", event->event); + + if(event->event == EVENT_STAMODE_DISCONNECTED) { + DEBUGV("STA disconnect: %d\n", event->event_info.disconnected.reason); + WiFiClient::stopAll(); + } + + for(uint32_t i = 0; i < cbEventList.size(); i++) { + WiFiEventCbList_t entry = cbEventList[i]; + if(entry.cb) { + if(entry.event == (WiFiEvent_t) event->event || entry.event == WIFI_EVENT_MAX) { + entry.cb((WiFiEvent_t) event->event); + } + } + } +} + +/** + * Return the current channel associated with the network + * @return channel (1-13) + */ +int32_t ESP8266WiFiGenericClass::channel(void) { + return wifi_get_channel(); +} + +/** + * set Sleep mode + * @param type sleep_type_t + * @return bool + */ +bool ESP8266WiFiGenericClass::setSleepMode(WiFiSleepType_t type) { + return wifi_set_sleep_type((sleep_type_t) type); +} + +/** + * get Sleep mode + * @return sleep_type_t + */ +WiFiSleepType_t ESP8266WiFiGenericClass::getSleepMode() { + return (WiFiSleepType_t) wifi_get_sleep_type(); +} + +/** + * set phy Mode + * @param mode phy_mode_t + * @return bool + */ +bool ESP8266WiFiGenericClass::setPhyMode(WiFiPhyMode_t mode) { + return wifi_set_phy_mode((phy_mode_t) mode); +} + +/** + * get phy Mode + * @return phy_mode_t + */ +WiFiPhyMode_t ESP8266WiFiGenericClass::getPhyMode() { + return (WiFiPhyMode_t) wifi_get_phy_mode(); +} + +/** + * set the output power of WiFi + * @param dBm max: +20.5dBm min: 0dBm + */ +void ESP8266WiFiGenericClass::setOutputPower(float dBm) { + + if(dBm > 20.5) { + dBm = 20.5; + } else if(dBm < 0) { + dBm = 0; + } + + uint8_t val = (dBm*4.0f); + system_phy_set_max_tpw(val); +} + + +/** + * store WiFi config in SDK flash area + * @param persistent + */ +void ESP8266WiFiGenericClass::persistent(bool persistent) { + _persistent = persistent; +} + + +/** + * set new mode + * @param m WiFiMode_t + */ +bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) { + if(wifi_get_opmode() == (uint8) m) { + return true; + } + + bool ret = false; + + ETS_UART_INTR_DISABLE(); + if(_persistent) { + ret = wifi_set_opmode(m); + } else { + ret = wifi_set_opmode_current(m); + } + ETS_UART_INTR_ENABLE(); + + return ret; +} + +/** + * get WiFi mode + * @return WiFiMode + */ +WiFiMode_t ESP8266WiFiGenericClass::getMode() { + return (WiFiMode_t) wifi_get_opmode(); +} + +/** + * control STA mode + * @param enable bool + * @return ok + */ +bool ESP8266WiFiGenericClass::enableSTA(bool enable) { + + WiFiMode_t currentMode = getMode(); + bool isEnabled = ((currentMode & WIFI_STA) != 0); + + if(isEnabled != enable) { + if(enable) { + return mode((WiFiMode_t)(currentMode & WIFI_STA)); + } else { + return mode((WiFiMode_t)(currentMode & (~WIFI_STA))); + } + } else { + return true; + } +} + +/** + * control AP mode + * @param enable bool + * @return ok + */ +bool ESP8266WiFiGenericClass::enableAP(bool enable){ + + WiFiMode_t currentMode = getMode(); + bool isEnabled = ((currentMode & WIFI_AP) != 0); + + if(isEnabled != enable) { + if(enable) { + return mode((WiFiMode_t)(currentMode & WIFI_AP)); + } else { + return mode((WiFiMode_t)(currentMode & (~WIFI_AP))); + } + } else { + return true; + } +} + + +/** + * Disable WiFi for x us when value is not 0 + * @param sleep_time_in_us + * @return ok + */ +bool ESP8266WiFiGenericClass::forceSleepBegin(uint32 sleepUs) { + _forceSleepLastMode = getMode(); + if(!mode(WIFI_OFF)) { + return false; + } + + if(sleepUs == 0) { + sleepUs = 0xFFFFFFF; + } + + wifi_fpm_set_sleep_type(MODEM_SLEEP_T); + wifi_fpm_open(); + return (wifi_fpm_do_sleep(sleepUs) == 0); +} + +/** + * wake up WiFi Modem + * @return ok + */ +bool ESP8266WiFiGenericClass::forceSleepWake() { + wifi_fpm_do_wakeup(); + wifi_fpm_close(); + + // restore last mode + if(mode(_forceSleepLastMode)) { + if((_forceSleepLastMode & WIFI_STA) != 0){ + wifi_station_connect(); + } + return true; + } + return false; +} + + +// ----------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------ Generic Network function --------------------------------------------- +// ----------------------------------------------------------------------------------------------------------------------- + +void wifi_dns_found_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg); + +/** + * Resolve the given hostname to an IP address. + * @param aHostname Name to be resolved + * @param aResult IPAddress structure to store the returned IP address + * @return 1 if aIPAddrString was successfully converted to an IP address, + * else error code + */ +int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult) { + ip_addr_t addr; + aResult = static_cast(0); + err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); + if(err == ERR_OK) { + aResult = addr.addr; + } else if(err == ERR_INPROGRESS) { + esp_yield(); + // will return here when dns_found_callback fires + } + + return (aResult != 0) ? 1 : 0; +} + +/** + * DNS callback + * @param name + * @param ipaddr + * @param callback_arg + */ +void wifi_dns_found_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg) { + if(ipaddr) { + (*reinterpret_cast(callback_arg)) = ipaddr->addr; + } + esp_schedule(); // resume the hostByName function +} + + diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h new file mode 100644 index 0000000000..80a7c946fc --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h @@ -0,0 +1,89 @@ +/* + ESP8266WiFiGeneric.h - esp8266 Wifi support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + Modified by Ivan Grokhotkov, December 2014 + Reworked by Markus Sattler, December 2015 + + 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 + */ + +#ifndef ESP8266WIFIGENERIC_H_ +#define ESP8266WIFIGENERIC_H_ + +#include "ESP8266WiFiType.h" + +typedef void (*WiFiEventCb)(WiFiEvent_t event); + +typedef struct { + WiFiEventCb cb; + WiFiEvent_t event; +} WiFiEventCbList_t; + +class ESP8266WiFiGenericClass { + // ---------------------------------------------------------------------------------------------- + // -------------------------------------- Generic WiFi function --------------------------------- + // ---------------------------------------------------------------------------------------------- + + public: + + ESP8266WiFiGenericClass(); + + void onEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX); + void removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX); + + int32_t channel(void); + + bool setSleepMode(WiFiSleepType_t type); + WiFiSleepType_t getSleepMode(); + + bool setPhyMode(WiFiPhyMode_t mode); + WiFiPhyMode_t getPhyMode(); + + void setOutputPower(float dBm); + + void persistent(bool persistent); + + bool mode(WiFiMode_t); + WiFiMode_t getMode(); + + bool enableSTA(bool enable); + bool enableAP(bool enable); + + bool forceSleepBegin(uint32 sleepUs = 0); + bool forceSleepWake(); + + protected: + static bool _persistent; + static WiFiMode_t _forceSleepLastMode; + + static void _eventCallback(void *event); + + // ---------------------------------------------------------------------------------------------- + // ------------------------------------ Generic Network function -------------------------------- + // ---------------------------------------------------------------------------------------------- + + public: + + int hostByName(const char* aHostname, IPAddress& aResult); + + protected: + + friend class ESP8266WiFiSTAClass; + friend class ESP8266WiFiScanClass; + friend class ESP8266WiFiAPClass; +}; + +#endif /* ESP8266WIFIGENERIC_H_ */ diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp new file mode 100644 index 0000000000..0d34a5a64b --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -0,0 +1,657 @@ +/* + ESP8266WiFiSTA.cpp - WiFi library for esp8266 + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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 + + Reworked on 28 Dec 2015 by Markus Sattler + + */ + +#include "ESP8266WiFi.h" +#include "ESP8266WiFiGeneric.h" +#include "ESP8266WiFiSTA.h" + +extern "C" { +#include "c_types.h" +#include "ets_sys.h" +#include "os_type.h" +#include "osapi.h" +#include "mem.h" +#include "user_interface.h" +#include "smartconfig.h" +#include "lwip/err.h" +#include "lwip/dns.h" +} + +#include "debug.h" + +extern "C" void esp_schedule(); +extern "C" void esp_yield(); + +// ----------------------------------------------------------------------------------------------------------------------- +// ---------------------------------------------------- Private functions ------------------------------------------------ +// ----------------------------------------------------------------------------------------------------------------------- + +static bool sta_config_equal(const station_config& lhs, const station_config& rhs); + + +/** + * compare two STA configurations + * @param lhs station_config + * @param rhs station_config + * @return equal + */ +static bool sta_config_equal(const station_config& lhs, const station_config& rhs) { + if(strcmp(reinterpret_cast(lhs.ssid), reinterpret_cast(rhs.ssid)) != 0) { + return false; + } + + if(strcmp(reinterpret_cast(lhs.password), reinterpret_cast(rhs.password)) != 0) { + return false; + } + + if(lhs.bssid_set != rhs.bssid_set) { + return false; + } + + if(lhs.bssid_set) { + if(memcmp(lhs.bssid, rhs.bssid, 6) != 0) { + return false; + } + } + + return true; +} + +// ----------------------------------------------------------------------------------------------------------------------- +// ---------------------------------------------------- STA function ----------------------------------------------------- +// ----------------------------------------------------------------------------------------------------------------------- + +bool ESP8266WiFiSTAClass::_useStaticIp = false; + +/** + * Start Wifi connection + * if passphrase is set the most secure supported mode will be automatically selected + * @param ssid const char* Pointer to the SSID string. + * @param passphrase const char * Optional. Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal). + * @param bssid uint8_t[6] Optional. BSSID / MAC of AP + * @param channel Optional. Channel of AP + * @param connect Optional. call connect + * @return + */ +wl_status_t ESP8266WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { + + if(!WiFi.enableSTA(true)) { + // enable STA failed + return WL_CONNECT_FAILED; + } + + if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) { + // fail SSID too long or missing! + return WL_CONNECT_FAILED; + } + + if(passphrase && strlen(passphrase) > 63) { + // fail passphrase too long! + return WL_CONNECT_FAILED; + } + + struct station_config conf; + strcpy(reinterpret_cast(conf.ssid), ssid); + + if(passphrase) { + strcpy(reinterpret_cast(conf.password), passphrase); + } else { + *conf.password = 0; + } + + if(bssid) { + conf.bssid_set = 1; + memcpy((void *) &conf.bssid[0], (void *) bssid, 6); + } else { + conf.bssid_set = 0; + } + + struct station_config current_conf; + wifi_station_get_config(¤t_conf); + if(sta_config_equal(current_conf, conf)) { + DEBUGV("sta config unchanged"); + return status(); + } + + ETS_UART_INTR_DISABLE(); + + if(WiFi._persistent) { + wifi_station_set_config(&conf); + } else { + wifi_station_set_config_current(&conf); + } + + if(connect) { + wifi_station_connect(); + } + + ETS_UART_INTR_ENABLE(); + + if(channel > 0 && channel <= 13) { + wifi_set_channel(channel); + } + + if(!_useStaticIp) { + wifi_station_dhcpc_start(); + } + + return status(); +} + +wl_status_t ESP8266WiFiSTAClass::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); +} + +/** + * Use to connect to SDK config. + * @return wl_status_t + */ +wl_status_t ESP8266WiFiSTAClass::begin() { + + if(!WiFi.enableSTA(true)) { + // enable STA failed + return WL_CONNECT_FAILED; + } + + ETS_UART_INTR_DISABLE(); + wifi_station_connect(); + ETS_UART_INTR_ENABLE(); + + if(!_useStaticIp) { + wifi_station_dhcpc_start(); + } + return status(); +} + + +/** + * Change IP configuration settings disabling the dhcp client + * @param local_ip Static ip configuration + * @param gateway Static gateway configuration + * @param subnet Static Subnet mask + * @param dns1 Static DNS server 1 + * @param dns2 Static DNS server 2 + */ +bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) { + + if(!WiFi.enableSTA(true)) { + return false; + } + + struct ip_info info; + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + + wifi_station_dhcpc_stop(); + if(wifi_set_ip_info(STATION_IF, &info)) { + _useStaticIp = true; + } else { + return false; + } + ip_addr_t d; + + if(dns1 != (uint32_t)0x00000000) { + // Set DNS1-Server + d.addr = static_cast(dns1); + dns_setserver(0, &d); + } + + if(dns2 != (uint32_t)0x00000000) { + // Set DNS2-Server + d.addr = static_cast(dns2); + dns_setserver(1, &d); + } + + return true; +} + +/** + * will force a disconnect an then start reconnecting to AP + * @return ok + */ +bool ESP8266WiFiSTAClass::reconnect() { + if((WiFi.getMode() & WIFI_STA) != 0) { + if(wifi_station_disconnect()) { + return wifi_station_connect(); + } + } + return false; +} + +/** + * Disconnect from the network + * @param wifioff + * @return one value of wl_status_t enum + */ +bool ESP8266WiFiSTAClass::disconnect(bool wifioff) { + bool ret; + struct station_config conf; + *conf.ssid = 0; + *conf.password = 0; + + ETS_UART_INTR_DISABLE(); + if(WiFi._persistent) { + wifi_station_set_config(&conf); + } else { + wifi_station_set_config_current(&conf); + } + ret = wifi_station_disconnect(); + ETS_UART_INTR_ENABLE(); + + if(wifioff) { + WiFi.enableSTA(false); + } + + return ret; +} + +/** + * is STA interface connected? + * @return true if STA is connected to an AD + */ +bool ESP8266WiFiSTAClass::isConnected() { + return (status() == WL_CONNECTED); +} + + +/** + * Setting the ESP8266 station to connect to the AP (which is recorded) + * automatically or not when powered on. Enable auto-connect by default. + * @param autoConnect bool + * @return if saved + */ +bool ESP8266WiFiSTAClass::setAutoConnect(bool autoConnect) { + bool ret; + ETS_UART_INTR_DISABLE(); + ret = wifi_station_set_auto_connect(autoConnect); + ETS_UART_INTR_ENABLE(); + return ret; +} + +/** + * Checks if ESP8266 station mode will connect to AP + * automatically or not when it is powered on. + * @return auto connect + */ +bool ESP8266WiFiSTAClass::getAutoConnect() { + return (wifi_station_get_auto_connect() != 0); +} + +/** + * Set whether reconnect or not when the ESP8266 station is disconnected from AP. + * @param autoReconnect + * @return + */ +bool ESP8266WiFiSTAClass::setAutoReconnect(bool autoReconnect) { + return wifi_station_set_reconnect_policy(autoReconnect); +} + +/** + * Wait for WiFi connection to reach a result + * returns the status reached or disconnect if STA is off + * @return wl_status_t + */ +uint8_t ESP8266WiFiSTAClass::waitForConnectResult() { + //1 and 3 have STA enabled + if((wifi_get_opmode() & 1) == 0) { + return WL_DISCONNECTED; + } + while(status() == WL_DISCONNECTED) { + delay(100); + } + return status(); +} + +/** + * Get the station interface IP address. + * @return IPAddress station IP + */ +IPAddress ESP8266WiFiSTAClass::localIP() { + struct ip_info ip; + wifi_get_ip_info(STATION_IF, &ip); + return IPAddress(ip.ip.addr); +} + + +/** + * Get the station interface MAC address. + * @param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + * @return pointer to uint8_t * + */ +uint8_t* ESP8266WiFiSTAClass::macAddress(uint8_t* mac) { + wifi_get_macaddr(STATION_IF, mac); + return mac; +} + +/** + * Get the station interface MAC address. + * @return String mac + */ +String ESP8266WiFiSTAClass::macAddress(void) { + uint8_t mac[6]; + char macStr[18] = { 0 }; + wifi_get_macaddr(STATION_IF, mac); + + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + +/** + * Get the interface subnet mask address. + * @return IPAddress subnetMask + */ +IPAddress ESP8266WiFiSTAClass::subnetMask() { + struct ip_info ip; + wifi_get_ip_info(STATION_IF, &ip); + return IPAddress(ip.netmask.addr); +} + +/** + * Get the gateway ip address. + * @return IPAddress gatewayIP + */ +IPAddress ESP8266WiFiSTAClass::gatewayIP() { + struct ip_info ip; + wifi_get_ip_info(STATION_IF, &ip); + return IPAddress(ip.gw.addr); +} + +/** + * Get the DNS ip address. + * @param dns_no + * @return IPAddress DNS Server IP + */ +IPAddress ESP8266WiFiSTAClass::dnsIP(uint8_t dns_no) { + ip_addr_t dns_ip = dns_getserver(dns_no); + return IPAddress(dns_ip.addr); +} + + +/** + * Get ESP8266 station DHCP hostname + * @return hostname + */ +String ESP8266WiFiSTAClass::hostname(void) { + return String(wifi_station_get_hostname()); +} + + +/** + * Set ESP8266 station DHCP hostname + * @param aHostname max length:32 + * @return ok + */ +bool ESP8266WiFiSTAClass::hostname(char* aHostname) { + if(strlen(aHostname) > 32) { + return false; + } + return wifi_station_set_hostname(aHostname); +} + +/** + * Set ESP8266 station DHCP hostname + * @param aHostname max length:32 + * @return ok + */ +bool ESP8266WiFiSTAClass::hostname(const char* aHostname) { + return hostname((char*) aHostname); +} + +/** + * Set ESP8266 station DHCP hostname + * @param aHostname max length:32 + * @return ok + */ +bool ESP8266WiFiSTAClass::hostname(String aHostname) { + return hostname((char*) aHostname.c_str()); +} + +/** + * Return Connection status. + * @return one of the value defined in wl_status_t + * + */ +wl_status_t ESP8266WiFiSTAClass::status() { + station_status_t status = wifi_station_get_connect_status(); + + switch(status) { + case STATION_GOT_IP: + return WL_CONNECTED; + case STATION_NO_AP_FOUND: + return WL_NO_SSID_AVAIL; + case STATION_CONNECT_FAIL: + case STATION_WRONG_PASSWORD: + return WL_CONNECT_FAILED; + case STATION_IDLE: + return WL_IDLE_STATUS; + default: + return WL_DISCONNECTED; + } +} + +/** + * Return the current SSID associated with the network + * @return SSID + */ +String ESP8266WiFiSTAClass::SSID() const { + struct station_config conf; + wifi_station_get_config(&conf); + return String(reinterpret_cast(conf.ssid)); +} + +/** + * Return the current pre shared key associated with the network + * @return psk string + */ +String ESP8266WiFiSTAClass::psk() const { + struct station_config conf; + wifi_station_get_config(&conf); + return String(reinterpret_cast(conf.password)); +} + +/** + * Return the current bssid / mac associated with the network if configured + * @return bssid uint8_t * + */ +uint8_t* ESP8266WiFiSTAClass::BSSID(void) { + static struct station_config conf; + wifi_station_get_config(&conf); + return reinterpret_cast(conf.bssid); +} + +/** + * Return the current bssid / mac associated with the network if configured + * @return String bssid mac + */ +String ESP8266WiFiSTAClass::BSSIDstr(void) { + struct station_config conf; + char mac[18] = { 0 }; + wifi_station_get_config(&conf); + sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", conf.bssid[0], conf.bssid[1], conf.bssid[2], conf.bssid[3], conf.bssid[4], conf.bssid[5]); + return String(mac); +} + +/** + * Return the current network RSSI. + * @return RSSI value + */ +int32_t ESP8266WiFiSTAClass::RSSI(void) { + return wifi_station_get_rssi(); +} + + + +// ----------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------- STA remote configure ----------------------------------------------- +// ----------------------------------------------------------------------------------------------------------------------- + +void wifi_wps_status_cb(wps_cb_status status); + +/** + * WPS config + * so far only WPS_TYPE_PBC is supported (SDK 1.2.0) + * @return ok + */ +bool ESP8266WiFiSTAClass::beginWPSConfig(void) { + + if(!WiFi.enableSTA(true)) { + // enable STA failed + return false; + } + + disconnect(); + + DEBUGV("wps begin\n"); + + if(!wifi_wps_disable()) { + DEBUGV("wps disable failed\n"); + return false; + } + + // so far only WPS_TYPE_PBC is supported (SDK 1.2.0) + if(!wifi_wps_enable(WPS_TYPE_PBC)) { + DEBUGV("wps enable failed\n"); + return false; + } + + if(!wifi_set_wps_cb((wps_st_cb_t) &wifi_wps_status_cb)) { + DEBUGV("wps cb failed\n"); + return false; + } + + if(!wifi_wps_start()) { + DEBUGV("wps start failed\n"); + return false; + } + + esp_yield(); + // will return here when wifi_wps_status_cb fires + + return true; +} + +/** + * WPS callback + * @param status wps_cb_status + */ +void wifi_wps_status_cb(wps_cb_status status) { + DEBUGV("wps cb status: %d\r\n", status); + switch(status) { + case WPS_CB_ST_SUCCESS: + if(!wifi_wps_disable()) { + DEBUGV("wps disable failed\n"); + } + wifi_station_connect(); + break; + case WPS_CB_ST_FAILED: + DEBUGV("wps FAILED\n"); + break; + case WPS_CB_ST_TIMEOUT: + DEBUGV("wps TIMEOUT\n"); + break; + case WPS_CB_ST_WEP: + DEBUGV("wps WEP\n"); + break; + } + // TODO user function to get status + + esp_schedule(); // resume the beginWPSConfig function +} + + + +bool ESP8266WiFiSTAClass::_smartConfigStarted = false; +bool ESP8266WiFiSTAClass::_smartConfigDone = false; + +/** + * Start SmartConfig + */ +bool ESP8266WiFiSTAClass::beginSmartConfig() { + if(_smartConfigStarted) { + return false; + } + + if(!WiFi.enableSTA(true)) { + // enable STA failed + return false; + } + + if(smartconfig_start(reinterpret_cast(&ESP8266WiFiSTAClass::_smartConfigCallback), 1)) { + _smartConfigStarted = true; + _smartConfigDone = false; + return true; + } + return false; +} + + +/** + * Stop SmartConfig + */ +bool ESP8266WiFiSTAClass::stopSmartConfig() { + if(!_smartConfigStarted) { + return true; + } + + if(smartconfig_stop()) { + _smartConfigStarted = false; + return true; + } + return false; +} + +/** + * Query SmartConfig status, to decide when stop config + * @return smartConfig Done + */ +bool ESP8266WiFiSTAClass::smartConfigDone() { + if(!_smartConfigStarted) { + return false; + } + + return _smartConfigDone; +} + + +/** + * _smartConfigCallback + * @param st + * @param result + */ +void ESP8266WiFiSTAClass::_smartConfigCallback(uint32_t st, void* result) { + sc_status status = (sc_status) st; + if(status == SC_STATUS_LINK) { + station_config* sta_conf = reinterpret_cast(result); + + wifi_station_set_config(sta_conf); + wifi_station_disconnect(); + wifi_station_connect(); + + _smartConfigDone = true; + } else if(status == SC_STATUS_LINK_OVER) { + WiFi.stopSmartConfig(); + } +} + diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h new file mode 100644 index 0000000000..4e87f8826e --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -0,0 +1,107 @@ +/* + ESP8266WiFiSTA.h - esp8266 Wifi support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + Modified by Ivan Grokhotkov, December 2014 + Reworked by Markus Sattler, December 2015 + + 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 + */ + +#ifndef ESP8266WIFISTA_H_ +#define ESP8266WIFISTA_H_ + + +#include "ESP8266WiFiType.h" +#include "ESP8266WiFiGeneric.h" + + +class ESP8266WiFiSTAClass { + // ---------------------------------------------------------------------------------------------- + // ---------------------------------------- STA function ---------------------------------------- + // ---------------------------------------------------------------------------------------------- + + public: + + wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); + wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); + wl_status_t begin(); + + bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + + bool reconnect(); + bool disconnect(bool wifioff = false); + + bool isConnected(); + + bool setAutoConnect(bool autoConnect); + bool getAutoConnect(); + + bool setAutoReconnect(bool autoReconnect); + + uint8_t waitForConnectResult(); + + // STA network info + IPAddress localIP(); + + uint8_t * macAddress(uint8_t* mac); + String macAddress(); + + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsIP(uint8_t dns_no = 0); + + String hostname(); + bool hostname(char* aHostname); + bool hostname(const char* aHostname); + bool hostname(String aHostname); + + // STA WiFi info + wl_status_t status(); + String SSID() const; + String psk() const; + + uint8_t * BSSID(); + String BSSIDstr(); + + int32_t RSSI(); + + protected: + + static bool _useStaticIp; + + // ---------------------------------------------------------------------------------------------- + // ------------------------------------ STA remote configure ----------------------------------- + // ---------------------------------------------------------------------------------------------- + + public: + + bool beginWPSConfig(void); + + bool beginSmartConfig(); + bool stopSmartConfig(); + bool smartConfigDone(); + + protected: + + static bool _smartConfigStarted; + static bool _smartConfigDone; + + static void _smartConfigCallback(uint32_t status, void* result); + +}; + + +#endif /* ESP8266WIFISTA_H_ */ diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp new file mode 100644 index 0000000000..bf9edd2614 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -0,0 +1,322 @@ +/* + ESP8266WiFiScan.cpp - WiFi library for esp8266 + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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 + + Reworked on 28 Dec 2015 by Markus Sattler + + */ + +#include "ESP8266WiFi.h" +#include "ESP8266WiFiGeneric.h" +#include "ESP8266WiFiScan.h" + +extern "C" { +#include "c_types.h" +#include "ets_sys.h" +#include "os_type.h" +#include "osapi.h" +#include "mem.h" +#include "user_interface.h" +} + +#include "debug.h" + +extern "C" void esp_schedule(); +extern "C" void esp_yield(); + +// ----------------------------------------------------------------------------------------------------------------------- +// ---------------------------------------------------- Private functions ------------------------------------------------ +// ----------------------------------------------------------------------------------------------------------------------- + + + + +// ----------------------------------------------------------------------------------------------------------------------- +// ----------------------------------------------------- scan function --------------------------------------------------- +// ----------------------------------------------------------------------------------------------------------------------- + +bool ESP8266WiFiScanClass::_scanAsync = false; +bool ESP8266WiFiScanClass::_scanStarted = false; +bool ESP8266WiFiScanClass::_scanComplete = false; + +size_t ESP8266WiFiScanClass::_scanCount = 0; +void* ESP8266WiFiScanClass::_scanResult = 0; + +/** + * Start scan WiFi networks available + * @param async run in async mode + * @param show_hidden show hidden networks + * @return Number of discovered networks + */ +int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden) { + if(ESP8266WiFiScanClass::_scanStarted) { + return WIFI_SCAN_RUNNING; + } + + ESP8266WiFiScanClass::_scanAsync = async; + + WiFi.enableSTA(true); + + int status = wifi_station_get_connect_status(); + if(status != STATION_GOT_IP && status != STATION_IDLE) { + WiFi.disconnect(false); + } + + scanDelete(); + + struct scan_config config; + config.ssid = 0; + config.bssid = 0; + config.channel = 0; + config.show_hidden = show_hidden; + if(wifi_station_scan(&config, reinterpret_cast(&ESP8266WiFiScanClass::_scanDone))) { + ESP8266WiFiScanClass::_scanComplete = false; + ESP8266WiFiScanClass::_scanStarted = true; + + if(ESP8266WiFiScanClass::_scanAsync) { + delay(0); // time for the OS to trigger the scan + return WIFI_SCAN_RUNNING; + } + + esp_yield(); + return ESP8266WiFiScanClass::_scanCount; + } else { + return WIFI_SCAN_FAILED; + } + +} + + +/** + * called to get the scan state in Async mode + * @return scan result or status + * -1 if scan not fin + * -2 if scan not triggered + */ +int8_t ESP8266WiFiScanClass::scanComplete() { + + if(_scanStarted) { + return WIFI_SCAN_RUNNING; + } + + if(_scanComplete) { + return ESP8266WiFiScanClass::_scanCount; + } + + return WIFI_SCAN_FAILED; +} + +/** + * delete last scan result from RAM + */ +void ESP8266WiFiScanClass::scanDelete() { + if(ESP8266WiFiScanClass::_scanResult) { + delete[] reinterpret_cast(ESP8266WiFiScanClass::_scanResult); + ESP8266WiFiScanClass::_scanResult = 0; + ESP8266WiFiScanClass::_scanCount = 0; + } + _scanComplete = false; +} + + +/** + * loads all infos from a scanned wifi in to the ptr parameters + * @param networkItem uint8_t + * @param ssid const char** + * @param encryptionType uint8_t * + * @param RSSI int32_t * + * @param BSSID uint8_t ** + * @param channel int32_t * + * @param isHidden bool * + * @return (true if ok) + */ +bool ESP8266WiFiScanClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &isHidden) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return false; + } + + ssid = (const char*) it->ssid; + encType = encryptionType(i); + rssi = it->rssi; + bssid = it->bssid; // move ptr + channel = it->channel; + isHidden = (it->is_hidden != 0); + + return true; +} + + +/** + * Return the SSID discovered during the network scan. + * @param i specify from which network item want to get the information + * @return ssid string of the specified item on the networks scanned list + */ +String ESP8266WiFiScanClass::SSID(uint8_t i) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return ""; + } + + return String(reinterpret_cast(it->ssid)); +} + + +/** + * Return the encryption type of the networks discovered during the scanNetworks + * @param i specify from which network item want to get the information + * @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list + */ +uint8_t ESP8266WiFiScanClass::encryptionType(uint8_t i) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return -1; + } + + switch(it->authmode) { + case AUTH_OPEN: + return ENC_TYPE_NONE; + case AUTH_WEP: + return ENC_TYPE_WEP; + case AUTH_WPA_PSK: + return ENC_TYPE_TKIP; + case AUTH_WPA2_PSK: + return ENC_TYPE_CCMP; + case AUTH_WPA_WPA2_PSK: + return ENC_TYPE_AUTO; + default: + return -1; + } +} + +/** + * Return the RSSI of the networks discovered during the scanNetworks + * @param i specify from which network item want to get the information + * @return signed value of RSSI of the specified item on the networks scanned list + */ +int32_t ESP8266WiFiScanClass::RSSI(uint8_t i) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return 0; + } + return it->rssi; +} + + +/** + * return MAC / BSSID of scanned wifi + * @param i specify from which network item want to get the information + * @return uint8_t * MAC / BSSID of scanned wifi + */ +uint8_t * ESP8266WiFiScanClass::BSSID(uint8_t i) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return 0; + } + return it->bssid; +} + +/** + * return MAC / BSSID of scanned wifi + * @param i specify from which network item want to get the information + * @return String MAC / BSSID of scanned wifi + */ +String ESP8266WiFiScanClass::BSSIDstr(uint8_t i) { + char mac[18] = { 0 }; + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return String(""); + } + sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]); + return String(mac); +} + +int32_t ESP8266WiFiScanClass::channel(uint8_t i) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return 0; + } + return it->channel; +} + +/** + * return if the scanned wifi is Hidden (no SSID) + * @param networkItem specify from which network item want to get the information + * @return bool (true == hidden) + */ +bool ESP8266WiFiScanClass::isHidden(uint8_t i) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return false; + } + return (it->is_hidden != 0); +} + +/** + * private + * scan callback + * @param result void *arg + * @param status STATUS + */ +void ESP8266WiFiScanClass::_scanDone(void* result, int status) { + if(status != OK) { + ESP8266WiFiScanClass::_scanCount = 0; + ESP8266WiFiScanClass::_scanResult = 0; + } else { + + int i = 0; + bss_info_head_t* head = reinterpret_cast(result); + + for(bss_info* it = STAILQ_FIRST(head); it; it = STAILQ_NEXT(it, next), ++i) + ; + ESP8266WiFiScanClass::_scanCount = i; + if(i == 0) { + ESP8266WiFiScanClass::_scanResult = 0; + } else { + bss_info* copied_info = new bss_info[i]; + i = 0; + for(bss_info* it = STAILQ_FIRST(head); it; it = STAILQ_NEXT(it, next), ++i) { + memcpy(copied_info + i, it, sizeof(bss_info)); + } + + ESP8266WiFiScanClass::_scanResult = copied_info; + } + + } + + ESP8266WiFiScanClass::_scanStarted = false; + ESP8266WiFiScanClass::_scanComplete = true; + + if(!ESP8266WiFiScanClass::_scanAsync) { + esp_schedule(); + } +} + +/** + * + * @param i specify from which network item want to get the information + * @return bss_info * + */ +void * ESP8266WiFiScanClass::_getScanInfoByIndex(int i) { + if(!ESP8266WiFiScanClass::_scanResult || (size_t) i > ESP8266WiFiScanClass::_scanCount) { + return 0; + } + return reinterpret_cast(ESP8266WiFiScanClass::_scanResult) + i; +} + diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.h b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.h new file mode 100644 index 0000000000..9d0c964a28 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.h @@ -0,0 +1,68 @@ +/* + ESP8266WiFiScan.h - esp8266 Wifi support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + Modified by Ivan Grokhotkov, December 2014 + Reworked by Markus Sattler, December 2015 + + 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 + */ + +#ifndef ESP8266WIFISCAN_H_ +#define ESP8266WIFISCAN_H_ + +#include "ESP8266WiFiType.h" +#include "ESP8266WiFiGeneric.h" + +class ESP8266WiFiScanClass { + + // ---------------------------------------------------------------------------------------------- + // ----------------------------------------- scan function -------------------------------------- + // ---------------------------------------------------------------------------------------------- + + public: + + int8_t scanNetworks(bool async = false, bool show_hidden = false); + + int8_t scanComplete(); + void scanDelete(); + + // scan result + bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden); + + String SSID(uint8_t networkItem); + uint8_t 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); + bool isHidden(uint8_t networkItem); + + protected: + + static bool _scanAsync; + static bool _scanStarted; + static bool _scanComplete; + + static size_t _scanCount; + static void* _scanResult; + + static void _scanDone(void* result, int status); + static void * _getScanInfoByIndex(int i); + +}; + + +#endif /* ESP8266WIFISCAN_H_ */ diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiType.h b/libraries/ESP8266WiFi/src/ESP8266WiFiType.h new file mode 100644 index 0000000000..a5b10e93e6 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiType.h @@ -0,0 +1,66 @@ +/* + ESP8266WiFiType.h - esp8266 Wifi support. + Copyright (c) 2011-2014 Arduino. All right reserved. + Modified by Ivan Grokhotkov, December 2014 + Reworked by Markus Sattler, December 2015 + + 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 + */ + + +#ifndef ESP8266WIFITYPE_H_ +#define ESP8266WIFITYPE_H_ + +#include + +#define WIFI_SCAN_RUNNING (-1) +#define WIFI_SCAN_FAILED (-2) + +// Note: +// this enums need to be in sync with the SDK! + +typedef enum WiFiMode { + WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 +} WiFiMode_t; + +typedef enum { + WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3 +} WiFiPhyMode_t; + +typedef enum { + WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 2, WIFI_MODEM_SLEEP = 3 +} WiFiSleepType_t; + + +typedef enum { + WIFI_EVENT_STAMODE_CONNECTED = 0, + WIFI_EVENT_STAMODE_DISCONNECTED, + WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, + WIFI_EVENT_STAMODE_GOT_IP, + WIFI_EVENT_STAMODE_DHCP_TIMEOUT, + WIFI_EVENT_SOFTAPMODE_STACONNECTED, + WIFI_EVENT_SOFTAPMODE_STADISCONNECTED, + WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED, + WIFI_EVENT_MAX +} WiFiEvent_t; + + + +extern "C" { +typedef STAILQ_HEAD(, bss_info) +bss_info_head_t; +} + +#endif /* ESP8266WIFITYPE_H_ */ diff --git a/tools/sdk/include/user_interface.h b/tools/sdk/include/user_interface.h index c29443e548..470556c706 100644 --- a/tools/sdk/include/user_interface.h +++ b/tools/sdk/include/user_interface.h @@ -164,7 +164,7 @@ bool wifi_set_opmode_current(uint8 opmode); uint8 wifi_get_broadcast_if(void); bool wifi_set_broadcast_if(uint8 interface); -struct bss_info { +typedef struct bss_info { STAILQ_ENTRY(bss_info) next; uint8 bssid[6]; @@ -177,7 +177,7 @@ struct bss_info { sint16 freq_offset; sint16 freqcal_val; uint8 *esp_mesh_ie; -}; +} bss_info_t; typedef struct _scaninfo { STAILQ_HEAD(, bss_info) *pbss; @@ -222,21 +222,21 @@ bool wifi_station_set_auto_connect(uint8 set); bool wifi_station_set_reconnect_policy(bool set); -enum { +typedef enum { STATION_IDLE = 0, STATION_CONNECTING, STATION_WRONG_PASSWORD, STATION_NO_AP_FOUND, STATION_CONNECT_FAIL, STATION_GOT_IP -}; +} station_status_t; enum dhcp_status { DHCP_STOPPED, DHCP_STARTED }; -uint8 wifi_station_get_connect_status(void); +station_status_t wifi_station_get_connect_status(void); uint8 wifi_station_get_current_ap_id(void); bool wifi_station_ap_change(uint8 current_ap_id);