diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f56a5eb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+# Precompiled Headers
+*.gch
+*.pch
+
+# PlatformIO folders
+.pio*
+
+# Documentation
+docs/*
+
+# Credentials
+credentials.h
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..6b12260
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,15 @@
+language: python
+python:
+ - '2.7'
+sudo: false
+cache:
+ directories:
+ - "~/.platformio"
+install:
+ - pip install -U platformio
+script:
+ - pushd examples/advanced && pio run && popd
+ - pushd examples/ap && pio run && popd
+ - pushd examples/basic && pio run && popd
+ - pushd examples/smartconfig && pio run && popd
+ - pushd examples/wps && pio run && popd
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..fbc37f6
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,72 @@
+# JustWifi change log
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## [2.0.0] 2018-06-11
+### Added
+- connected() member in class JustFifi
+
+## [2.0.0] 2018-06-11
+### Added
+- SmartConfig (a.k.a. ESP Touch) support
+- WPS Support
+- TravisCI build tests
+- Codacy code test
+
+### Changed
+- Complete refactor (check examples to adapt your code)
+- Changed license to LGPL-3.0
+
+## [1.2.0] 2018-05-20
+### Changed
+- Moved to GitHub
+
+## [1.1.9] 2018-05-08
+### Fixed
+- Removed unneeded reference to DNSServer.h
+
+## [1.1.8] 2018-04-23
+### Changed
+- Added options for power saving (Thanks to Pablo Pousada Rial)
+- Added Travis CI configuration (Thanks to @lobradov)
+
+## [1.1.7] 2018-04-10
+### Changed
+- Increasing hostname size to 32 chars
+
+## [1.1.6] 2018-01-10
+### Changed
+- Allow to register several callbacks
+- Changes in the information parameters for scanning and connecting callbacks
+- Updated example
+
+### Deprecated
+- onMessage method deprecated in favour of subscribe method
+
+## [1.1.5] 2017-09-22
+### Fixed
+- Fix bug when no hostname defined (#1)
+- When multiple routers have the same SSID, choose the one with strongest signal (#2). Thanks to Robert (robi772 @ bitbucket.org)!
+
+### Changed
+- Callbacks output more info about networks
+
+## [1.1.4] 2017-08-24
+### Fixed
+- Fixed code according to Arduino-ESP8266 issue https://github.com/esp8266/Arduino/issues/2186
+
+## [1.1.3] 2017-01-17
+### Changed
+- Disable autoconnect when using static IP
+
+## [1.1.2] 2017-01-11
+### Fixed
+- Do not disable STA mode after disconnect
+
+## [1.1.1] 2016-12-29
+### Fixed
+- Remove declaration from example, jw is a singleton
+
+## [1.1.0] 2016-09-29
+- Initial working version as standalone library
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0a04128
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b5f97cb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,46 @@
+# JustWifi
+
+JustWifi is a WIFI Manager library for the [Arduino Core for ESP8266][2]. The goal of the library is to manage ONLY the WIFI connection (no webserver, no mDNS,...) from code and in a reliable and flexible way.
+
+[![version](https://img.shields.io/badge/version-2.0.0-brightgreen.svg)](CHANGELOG.md)
+[![travis](https://travis-ci.org/xoseperez/justwifi.svg?branch=esp32)](https://travis-ci.org/xoseperez/justwifi)
+[![codacy](https://img.shields.io/codacy/grade/4ccbea0317c4415eb2d1c562feced407/esp32.svg)](https://www.codacy.com/app/xoseperez/justwifi/dashboard)
+[![license](https://img.shields.io/github/license/xoseperez/justwifi.svg)](LICENSE)
+
+[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=xose%2eperez%40gmail%2ecom&lc=US&no_note=0¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHostedGuest)
+[![twitter](https://img.shields.io/twitter/follow/xoseperez.svg?style=social)](https://twitter.com/intent/follow?screen_name=xoseperez)
+
+## Features
+
+The main features of the JustWifi library are:
+
+* Configure multiple possible networks
+* Scan wifi networks so it can try to connect to only those available, in order of signal strength
+* Smart Config support (when built with -DJUSTWIFI_ENABLE_SMARTCONFIG, tested with ESP8266 SmartConfig or IoT SmartConfig apps)
+* WPS support (when built with -DJUSTWIFI_ENABLE_WPS)
+* Fallback to AP mode
+* Configurable timeout to try to reconnect after AP fallback
+* AP+STA mode
+* Static IP (autoconnect is disabled when using static IP)
+* Single debug/action callback
+
+## Usage
+
+See examples.
+
+## License
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
diff --git a/examples/advanced/advanced.ino b/examples/advanced/advanced.ino
new file mode 100644
index 0000000..530c3e6
--- /dev/null
+++ b/examples/advanced/advanced.ino
@@ -0,0 +1,144 @@
+/*
+
+JustWifi - Advanced example
+
+This example shows how to use callbacks to enable other services like mDNS or
+a captive portal (when in AP mode only)
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+// -----------------------------------------------------------------------------
+// mDNS
+// -----------------------------------------------------------------------------
+
+#if defined(ARDUINO_ARCH_ESP32)
+ #include
+#else
+ #include
+#endif
+
+void mdnsCallback(justwifi_messages_t code, char * parameter) {
+
+ if (code == MESSAGE_CONNECTED) {
+
+ #if defined(ARDUINO_ARCH_ESP32)
+ String hostname = String(WiFi.getHostname());
+ #else
+ String hostname = WiFi.hostname();
+ #endif
+
+ // Configure mDNS
+ if (MDNS.begin((char *) hostname.c_str())) {
+ Serial.printf("[MDNS] OK\n");
+
+ // Publish as if there is an TELNET service available
+ MDNS.addService("telnet", "tcp", 22);
+
+ } else {
+ Serial.printf("[MDNS] FAIL\n");
+ }
+
+ }
+
+}
+
+// -----------------------------------------------------------------------------
+// Captive portal
+// -----------------------------------------------------------------------------
+
+#include
+
+DNSServer dnsServer;
+
+void captivePortalCallback(justwifi_messages_t code, char * parameter) {
+
+ if (code == MESSAGE_ACCESSPOINT_CREATED) {
+ if (!WiFi.isConnected()) dnsServer.start(53, "*", WiFi.softAPIP());
+ }
+
+ if (code == MESSAGE_CONNECTED) {
+ dnsServer.stop();
+ }
+
+}
+
+// -----------------------------------------------------------------------------
+
+void setup() {
+
+ Serial.begin(115200);
+ delay(2000);
+ Serial.println();
+ Serial.println();
+
+ // -------------------------------------------------------------------------
+
+ // Init object
+ jw.init();
+
+ // Set WIFI hostname (otherwise it would be ESP-XXXXXX)
+ jw.setHostname("justwifi");
+
+ // Callbacks
+ jw.subscribe(infoCallback);
+ jw.subscribe(mdnsCallback);
+ jw.subscribe(captivePortalCallback);
+
+ // -------------------------------------------------------------------------
+
+ // AP mode only as fallback
+ jw.enableAP(false);
+ jw.enableAPFallback(true);
+
+ // -------------------------------------------------------------------------
+
+ // Enable STA mode (connecting to a router)
+ jw.enableSTA(true);
+
+ // Configure it to scan available networks and connect in order of dBm
+ jw.enableScan(true);
+
+ // Clean existing network configuration
+ jw.cleanNetworks();
+
+ // Add a network with password
+ jw.addNetwork("home", "password");
+
+ // Add a network with static IP
+ jw.addNetwork("moms", "anotherpassword", "192.168.1.201", "192.168.1.1", "255.255.255.0");
+
+ // Add an open network
+ jw.addNetwork("work");
+
+ // -------------------------------------------------------------------------
+
+ Serial.println("[WIFI] Connecting Wifi...");
+
+}
+
+void loop() {
+
+ // This call takes care of it all
+ jw.loop();
+
+ // Small delay to give some breath
+ delay(10);
+
+}
diff --git a/examples/advanced/platformio.ini b/examples/advanced/platformio.ini
new file mode 100644
index 0000000..aa781f6
--- /dev/null
+++ b/examples/advanced/platformio.ini
@@ -0,0 +1,18 @@
+[platformio]
+env_default = d1_mini
+src_dir = .
+lib_dir = ../..
+
+[env:d1_mini]
+platform = espressif8266
+board = d1_mini
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
+
+[env:nano32]
+platform = espressif32
+board = nano32
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
diff --git a/examples/advanced/utils.ino b/examples/advanced/utils.ino
new file mode 100644
index 0000000..f230aed
--- /dev/null
+++ b/examples/advanced/utils.ino
@@ -0,0 +1,165 @@
+/*
+
+JustWifi - Basic debugging callback utils
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void infoWifi() {
+
+ if (WiFi.isConnected()) {
+
+ uint8_t * bssid = WiFi.BSSID();
+
+ Serial.printf("[WIFI] MODE STA -------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", WiFi.SSID().c_str());
+ Serial.printf("[WIFI] BSSID %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]
+ );
+ Serial.printf("[WIFI] CH %d\n", WiFi.channel());
+ Serial.printf("[WIFI] RSSI %d\n", WiFi.RSSI());
+ Serial.printf("[WIFI] IP %s\n", WiFi.localIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.macAddress().c_str());
+ Serial.printf("[WIFI] GW %s\n", WiFi.gatewayIP().toString().c_str());
+ Serial.printf("[WIFI] MASK %s\n", WiFi.subnetMask().toString().c_str());
+ Serial.printf("[WIFI] DNS %s\n", WiFi.dnsIP().toString().c_str());
+ #if defined(ARDUINO_ARCH_ESP32)
+ Serial.printf("[WIFI] HOST %s\n", WiFi.getHostname());
+ #else
+ Serial.printf("[WIFI] HOST %s\n", WiFi.hostname().c_str());
+ #endif
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+ if (WiFi.getMode() & WIFI_AP) {
+
+ Serial.printf("[WIFI] MODE AP --------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", jw.getAPSSID().c_str());
+ Serial.printf("[WIFI] IP %s\n", WiFi.softAPIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.softAPmacAddress().c_str());
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+}
+
+void infoCallback(justwifi_messages_t code, char * parameter) {
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_TURNING_OFF) {
+ Serial.printf("[WIFI] Turning OFF\n");
+ }
+
+ if (code == MESSAGE_TURNING_ON) {
+ Serial.printf("[WIFI] Turning ON\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_SCANNING) {
+ Serial.printf("[WIFI] Scanning\n");
+ }
+
+ if (code == MESSAGE_SCAN_FAILED) {
+ Serial.printf("[WIFI] Scan failed\n");
+ }
+
+ if (code == MESSAGE_NO_NETWORKS) {
+ Serial.printf("[WIFI] No networks found\n");
+ }
+
+ if (code == MESSAGE_NO_KNOWN_NETWORKS) {
+ Serial.printf("[WIFI] No known networks found\n");
+ }
+
+ if (code == MESSAGE_FOUND_NETWORK) {
+ Serial.printf("[WIFI] %s\n", parameter);
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_CONNECTING) {
+ Serial.printf("[WIFI] Connecting to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECT_WAITING) {
+ // too much noise
+ }
+
+ if (code == MESSAGE_CONNECT_FAILED) {
+ Serial.printf("[WIFI] Could not connect to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECTED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_DISCONNECTED) {
+ Serial.printf("[WIFI] Disconnected\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_ACCESSPOINT_CREATED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_DESTROYED) {
+ Serial.printf("[WIFI] Disconnecting access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_CREATING) {
+ Serial.printf("[WIFI] Creating access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_FAILED) {
+ Serial.printf("[WIFI] Could not create access point\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_WPS_START) {
+ Serial.printf("[WIFI] WPS started\n");
+ }
+
+ if (code == MESSAGE_WPS_SUCCESS) {
+ Serial.printf("[WIFI] WPS succeded!\n");
+ }
+
+ if (code == MESSAGE_WPS_ERROR) {
+ Serial.printf("[WIFI] WPS failed\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_SMARTCONFIG_START) {
+ Serial.printf("[WIFI] Smart Config started\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_SUCCESS) {
+ Serial.printf("[WIFI] Smart Config succeded!\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_ERROR) {
+ Serial.printf("[WIFI] Smart Config failed\n");
+ }
+
+};
diff --git a/examples/ap/ap.ino b/examples/ap/ap.ino
new file mode 100644
index 0000000..5af3bce
--- /dev/null
+++ b/examples/ap/ap.ino
@@ -0,0 +1,65 @@
+/*
+
+JustWifi - Access Point Example
+
+This example creates an access point.
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void setup() {
+
+ Serial.begin(115200);
+ delay(2000);
+ Serial.println();
+ Serial.println();
+
+ // -------------------------------------------------------------------------
+
+ // Init object
+ jw.init();
+
+ // Set WIFI hostname (otherwise it would be ESP-XXXXXX)
+ jw.setHostname("justwifi");
+
+ // Callbacks
+ jw.subscribe(infoCallback);
+
+ // -------------------------------------------------------------------------
+
+ // Set open access point, do not define to use the hostname
+ //jw.setSoftAP("justwifi");
+
+ // Set password protected access point
+ jw.setSoftAP("justwifi", "password");
+
+ // Enable AP
+ jw.enableAP(true);
+
+}
+
+void loop() {
+
+ // This call takes care of it all
+ jw.loop();
+
+ // Small delay to give some breath
+ delay(10);
+
+}
diff --git a/examples/ap/platformio.ini b/examples/ap/platformio.ini
new file mode 100644
index 0000000..aa781f6
--- /dev/null
+++ b/examples/ap/platformio.ini
@@ -0,0 +1,18 @@
+[platformio]
+env_default = d1_mini
+src_dir = .
+lib_dir = ../..
+
+[env:d1_mini]
+platform = espressif8266
+board = d1_mini
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
+
+[env:nano32]
+platform = espressif32
+board = nano32
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
diff --git a/examples/ap/utils.ino b/examples/ap/utils.ino
new file mode 100644
index 0000000..f230aed
--- /dev/null
+++ b/examples/ap/utils.ino
@@ -0,0 +1,165 @@
+/*
+
+JustWifi - Basic debugging callback utils
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void infoWifi() {
+
+ if (WiFi.isConnected()) {
+
+ uint8_t * bssid = WiFi.BSSID();
+
+ Serial.printf("[WIFI] MODE STA -------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", WiFi.SSID().c_str());
+ Serial.printf("[WIFI] BSSID %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]
+ );
+ Serial.printf("[WIFI] CH %d\n", WiFi.channel());
+ Serial.printf("[WIFI] RSSI %d\n", WiFi.RSSI());
+ Serial.printf("[WIFI] IP %s\n", WiFi.localIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.macAddress().c_str());
+ Serial.printf("[WIFI] GW %s\n", WiFi.gatewayIP().toString().c_str());
+ Serial.printf("[WIFI] MASK %s\n", WiFi.subnetMask().toString().c_str());
+ Serial.printf("[WIFI] DNS %s\n", WiFi.dnsIP().toString().c_str());
+ #if defined(ARDUINO_ARCH_ESP32)
+ Serial.printf("[WIFI] HOST %s\n", WiFi.getHostname());
+ #else
+ Serial.printf("[WIFI] HOST %s\n", WiFi.hostname().c_str());
+ #endif
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+ if (WiFi.getMode() & WIFI_AP) {
+
+ Serial.printf("[WIFI] MODE AP --------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", jw.getAPSSID().c_str());
+ Serial.printf("[WIFI] IP %s\n", WiFi.softAPIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.softAPmacAddress().c_str());
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+}
+
+void infoCallback(justwifi_messages_t code, char * parameter) {
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_TURNING_OFF) {
+ Serial.printf("[WIFI] Turning OFF\n");
+ }
+
+ if (code == MESSAGE_TURNING_ON) {
+ Serial.printf("[WIFI] Turning ON\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_SCANNING) {
+ Serial.printf("[WIFI] Scanning\n");
+ }
+
+ if (code == MESSAGE_SCAN_FAILED) {
+ Serial.printf("[WIFI] Scan failed\n");
+ }
+
+ if (code == MESSAGE_NO_NETWORKS) {
+ Serial.printf("[WIFI] No networks found\n");
+ }
+
+ if (code == MESSAGE_NO_KNOWN_NETWORKS) {
+ Serial.printf("[WIFI] No known networks found\n");
+ }
+
+ if (code == MESSAGE_FOUND_NETWORK) {
+ Serial.printf("[WIFI] %s\n", parameter);
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_CONNECTING) {
+ Serial.printf("[WIFI] Connecting to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECT_WAITING) {
+ // too much noise
+ }
+
+ if (code == MESSAGE_CONNECT_FAILED) {
+ Serial.printf("[WIFI] Could not connect to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECTED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_DISCONNECTED) {
+ Serial.printf("[WIFI] Disconnected\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_ACCESSPOINT_CREATED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_DESTROYED) {
+ Serial.printf("[WIFI] Disconnecting access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_CREATING) {
+ Serial.printf("[WIFI] Creating access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_FAILED) {
+ Serial.printf("[WIFI] Could not create access point\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_WPS_START) {
+ Serial.printf("[WIFI] WPS started\n");
+ }
+
+ if (code == MESSAGE_WPS_SUCCESS) {
+ Serial.printf("[WIFI] WPS succeded!\n");
+ }
+
+ if (code == MESSAGE_WPS_ERROR) {
+ Serial.printf("[WIFI] WPS failed\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_SMARTCONFIG_START) {
+ Serial.printf("[WIFI] Smart Config started\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_SUCCESS) {
+ Serial.printf("[WIFI] Smart Config succeded!\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_ERROR) {
+ Serial.printf("[WIFI] Smart Config failed\n");
+ }
+
+};
diff --git a/examples/basic/basic.ino b/examples/basic/basic.ino
new file mode 100644
index 0000000..8913f81
--- /dev/null
+++ b/examples/basic/basic.ino
@@ -0,0 +1,84 @@
+/*
+
+JustWifi - Basic example
+
+This example shows how to define different networks and enable network scanning
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void setup() {
+
+ Serial.begin(115200);
+ delay(2000);
+ Serial.println();
+ Serial.println();
+
+ // -------------------------------------------------------------------------
+
+ // Init object
+ jw.init();
+
+ // Set WIFI hostname (otherwise it would be ESP-XXXXXX)
+ jw.setHostname("justwifi");
+
+ // Callbacks
+ jw.subscribe(infoCallback);
+
+ // -------------------------------------------------------------------------
+
+ // AP mode only as fallback
+ jw.enableAP(false);
+ jw.enableAPFallback(true);
+
+ // -------------------------------------------------------------------------
+
+ // Enable STA mode (connecting to a router)
+ jw.enableSTA(true);
+
+ // Configure it to scan available networks and connect in order of dBm
+ jw.enableScan(true);
+
+ // Clean existing network configuration
+ jw.cleanNetworks();
+
+ // Add a network with password
+ jw.addNetwork("home", "password");
+
+ // Add a network with static IP
+ jw.addNetwork("moms", "anotherpassword", "192.168.1.201", "192.168.1.1", "255.255.255.0");
+
+ // Add an open network
+ jw.addNetwork("work");
+
+ // -------------------------------------------------------------------------
+
+ Serial.println("[WIFI] Connecting Wifi...");
+
+}
+
+void loop() {
+
+ // This call takes care of it all
+ jw.loop();
+
+ // Small delay to give some breath
+ delay(10);
+
+}
diff --git a/examples/basic/platformio.ini b/examples/basic/platformio.ini
new file mode 100644
index 0000000..aa781f6
--- /dev/null
+++ b/examples/basic/platformio.ini
@@ -0,0 +1,18 @@
+[platformio]
+env_default = d1_mini
+src_dir = .
+lib_dir = ../..
+
+[env:d1_mini]
+platform = espressif8266
+board = d1_mini
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
+
+[env:nano32]
+platform = espressif32
+board = nano32
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
diff --git a/examples/basic/utils.ino b/examples/basic/utils.ino
new file mode 100644
index 0000000..f230aed
--- /dev/null
+++ b/examples/basic/utils.ino
@@ -0,0 +1,165 @@
+/*
+
+JustWifi - Basic debugging callback utils
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void infoWifi() {
+
+ if (WiFi.isConnected()) {
+
+ uint8_t * bssid = WiFi.BSSID();
+
+ Serial.printf("[WIFI] MODE STA -------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", WiFi.SSID().c_str());
+ Serial.printf("[WIFI] BSSID %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]
+ );
+ Serial.printf("[WIFI] CH %d\n", WiFi.channel());
+ Serial.printf("[WIFI] RSSI %d\n", WiFi.RSSI());
+ Serial.printf("[WIFI] IP %s\n", WiFi.localIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.macAddress().c_str());
+ Serial.printf("[WIFI] GW %s\n", WiFi.gatewayIP().toString().c_str());
+ Serial.printf("[WIFI] MASK %s\n", WiFi.subnetMask().toString().c_str());
+ Serial.printf("[WIFI] DNS %s\n", WiFi.dnsIP().toString().c_str());
+ #if defined(ARDUINO_ARCH_ESP32)
+ Serial.printf("[WIFI] HOST %s\n", WiFi.getHostname());
+ #else
+ Serial.printf("[WIFI] HOST %s\n", WiFi.hostname().c_str());
+ #endif
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+ if (WiFi.getMode() & WIFI_AP) {
+
+ Serial.printf("[WIFI] MODE AP --------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", jw.getAPSSID().c_str());
+ Serial.printf("[WIFI] IP %s\n", WiFi.softAPIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.softAPmacAddress().c_str());
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+}
+
+void infoCallback(justwifi_messages_t code, char * parameter) {
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_TURNING_OFF) {
+ Serial.printf("[WIFI] Turning OFF\n");
+ }
+
+ if (code == MESSAGE_TURNING_ON) {
+ Serial.printf("[WIFI] Turning ON\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_SCANNING) {
+ Serial.printf("[WIFI] Scanning\n");
+ }
+
+ if (code == MESSAGE_SCAN_FAILED) {
+ Serial.printf("[WIFI] Scan failed\n");
+ }
+
+ if (code == MESSAGE_NO_NETWORKS) {
+ Serial.printf("[WIFI] No networks found\n");
+ }
+
+ if (code == MESSAGE_NO_KNOWN_NETWORKS) {
+ Serial.printf("[WIFI] No known networks found\n");
+ }
+
+ if (code == MESSAGE_FOUND_NETWORK) {
+ Serial.printf("[WIFI] %s\n", parameter);
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_CONNECTING) {
+ Serial.printf("[WIFI] Connecting to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECT_WAITING) {
+ // too much noise
+ }
+
+ if (code == MESSAGE_CONNECT_FAILED) {
+ Serial.printf("[WIFI] Could not connect to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECTED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_DISCONNECTED) {
+ Serial.printf("[WIFI] Disconnected\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_ACCESSPOINT_CREATED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_DESTROYED) {
+ Serial.printf("[WIFI] Disconnecting access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_CREATING) {
+ Serial.printf("[WIFI] Creating access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_FAILED) {
+ Serial.printf("[WIFI] Could not create access point\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_WPS_START) {
+ Serial.printf("[WIFI] WPS started\n");
+ }
+
+ if (code == MESSAGE_WPS_SUCCESS) {
+ Serial.printf("[WIFI] WPS succeded!\n");
+ }
+
+ if (code == MESSAGE_WPS_ERROR) {
+ Serial.printf("[WIFI] WPS failed\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_SMARTCONFIG_START) {
+ Serial.printf("[WIFI] Smart Config started\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_SUCCESS) {
+ Serial.printf("[WIFI] Smart Config succeded!\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_ERROR) {
+ Serial.printf("[WIFI] Smart Config failed\n");
+ }
+
+};
diff --git a/examples/smartconfig/platformio.ini b/examples/smartconfig/platformio.ini
new file mode 100644
index 0000000..af77b8d
--- /dev/null
+++ b/examples/smartconfig/platformio.ini
@@ -0,0 +1,20 @@
+[platformio]
+env_default = d1_mini
+src_dir = .
+lib_dir = ../..
+
+[env:d1_mini]
+platform = espressif8266
+board = d1_mini
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
+build_flags = -DJUSTWIFI_ENABLE_SMARTCONFIG -DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_WIFI -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
+
+[env:nano32]
+platform = espressif32
+board = nano32
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
+build_flags = -DJUSTWIFI_ENABLE_WPS -DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_WIFI
diff --git a/examples/smartconfig/smartconfig.ino b/examples/smartconfig/smartconfig.ino
new file mode 100644
index 0000000..c496c27
--- /dev/null
+++ b/examples/smartconfig/smartconfig.ino
@@ -0,0 +1,68 @@
+/*
+
+JustWifi - Smart Config example
+
+This example shows how to use Smart Config (a.k.a. ESP Touch) to
+provide the connection credentials to a device using a mobile app.
+
+Compatible apps:
+
+* ESP8266 SmartConfig
+* IoT SmartConfig
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void setup() {
+
+ Serial.begin(115200);
+ delay(2000);
+ Serial.println();
+ Serial.println();
+
+ // -------------------------------------------------------------------------
+
+ // Init object
+ jw.init();
+
+ // Set WIFI hostname (otherwise it would be ESP-XXXXXX)
+ jw.setHostname("justwifi");
+
+ // Callbacks
+ jw.subscribe(infoCallback);
+
+ // -------------------------------------------------------------------------
+
+ Serial.println("[WIFI] JustWifi Smart Config (ESP TOUCH) example");
+ Serial.println("[WIFI] Start your Smart Config APP...");
+
+ // Start Smartconfig join
+ jw.startSmartConfig();
+
+}
+
+void loop() {
+
+ // This call takes care of it all
+ jw.loop();
+
+ // Small delay to give some breath
+ delay(10);
+
+}
diff --git a/examples/smartconfig/utils.ino b/examples/smartconfig/utils.ino
new file mode 100644
index 0000000..f230aed
--- /dev/null
+++ b/examples/smartconfig/utils.ino
@@ -0,0 +1,165 @@
+/*
+
+JustWifi - Basic debugging callback utils
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void infoWifi() {
+
+ if (WiFi.isConnected()) {
+
+ uint8_t * bssid = WiFi.BSSID();
+
+ Serial.printf("[WIFI] MODE STA -------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", WiFi.SSID().c_str());
+ Serial.printf("[WIFI] BSSID %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]
+ );
+ Serial.printf("[WIFI] CH %d\n", WiFi.channel());
+ Serial.printf("[WIFI] RSSI %d\n", WiFi.RSSI());
+ Serial.printf("[WIFI] IP %s\n", WiFi.localIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.macAddress().c_str());
+ Serial.printf("[WIFI] GW %s\n", WiFi.gatewayIP().toString().c_str());
+ Serial.printf("[WIFI] MASK %s\n", WiFi.subnetMask().toString().c_str());
+ Serial.printf("[WIFI] DNS %s\n", WiFi.dnsIP().toString().c_str());
+ #if defined(ARDUINO_ARCH_ESP32)
+ Serial.printf("[WIFI] HOST %s\n", WiFi.getHostname());
+ #else
+ Serial.printf("[WIFI] HOST %s\n", WiFi.hostname().c_str());
+ #endif
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+ if (WiFi.getMode() & WIFI_AP) {
+
+ Serial.printf("[WIFI] MODE AP --------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", jw.getAPSSID().c_str());
+ Serial.printf("[WIFI] IP %s\n", WiFi.softAPIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.softAPmacAddress().c_str());
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+}
+
+void infoCallback(justwifi_messages_t code, char * parameter) {
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_TURNING_OFF) {
+ Serial.printf("[WIFI] Turning OFF\n");
+ }
+
+ if (code == MESSAGE_TURNING_ON) {
+ Serial.printf("[WIFI] Turning ON\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_SCANNING) {
+ Serial.printf("[WIFI] Scanning\n");
+ }
+
+ if (code == MESSAGE_SCAN_FAILED) {
+ Serial.printf("[WIFI] Scan failed\n");
+ }
+
+ if (code == MESSAGE_NO_NETWORKS) {
+ Serial.printf("[WIFI] No networks found\n");
+ }
+
+ if (code == MESSAGE_NO_KNOWN_NETWORKS) {
+ Serial.printf("[WIFI] No known networks found\n");
+ }
+
+ if (code == MESSAGE_FOUND_NETWORK) {
+ Serial.printf("[WIFI] %s\n", parameter);
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_CONNECTING) {
+ Serial.printf("[WIFI] Connecting to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECT_WAITING) {
+ // too much noise
+ }
+
+ if (code == MESSAGE_CONNECT_FAILED) {
+ Serial.printf("[WIFI] Could not connect to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECTED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_DISCONNECTED) {
+ Serial.printf("[WIFI] Disconnected\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_ACCESSPOINT_CREATED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_DESTROYED) {
+ Serial.printf("[WIFI] Disconnecting access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_CREATING) {
+ Serial.printf("[WIFI] Creating access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_FAILED) {
+ Serial.printf("[WIFI] Could not create access point\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_WPS_START) {
+ Serial.printf("[WIFI] WPS started\n");
+ }
+
+ if (code == MESSAGE_WPS_SUCCESS) {
+ Serial.printf("[WIFI] WPS succeded!\n");
+ }
+
+ if (code == MESSAGE_WPS_ERROR) {
+ Serial.printf("[WIFI] WPS failed\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_SMARTCONFIG_START) {
+ Serial.printf("[WIFI] Smart Config started\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_SUCCESS) {
+ Serial.printf("[WIFI] Smart Config succeded!\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_ERROR) {
+ Serial.printf("[WIFI] Smart Config failed\n");
+ }
+
+};
diff --git a/examples/wps/platformio.ini b/examples/wps/platformio.ini
new file mode 100644
index 0000000..79c6a02
--- /dev/null
+++ b/examples/wps/platformio.ini
@@ -0,0 +1,20 @@
+[platformio]
+env_default = d1_mini
+src_dir = .
+lib_dir = ../..
+
+[env:d1_mini]
+platform = espressif8266
+board = d1_mini
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
+build_flags = -DJUSTWIFI_ENABLE_WPS -DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_WIFI
+
+[env:nano32]
+platform = espressif32
+board = nano32
+framework = arduino
+upload_speed = 460800
+monitor_speed = 115200
+build_flags = -DJUSTWIFI_ENABLE_WPS -DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_WIFI
diff --git a/examples/wps/utils.ino b/examples/wps/utils.ino
new file mode 100644
index 0000000..f230aed
--- /dev/null
+++ b/examples/wps/utils.ino
@@ -0,0 +1,165 @@
+/*
+
+JustWifi - Basic debugging callback utils
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include
+
+void infoWifi() {
+
+ if (WiFi.isConnected()) {
+
+ uint8_t * bssid = WiFi.BSSID();
+
+ Serial.printf("[WIFI] MODE STA -------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", WiFi.SSID().c_str());
+ Serial.printf("[WIFI] BSSID %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]
+ );
+ Serial.printf("[WIFI] CH %d\n", WiFi.channel());
+ Serial.printf("[WIFI] RSSI %d\n", WiFi.RSSI());
+ Serial.printf("[WIFI] IP %s\n", WiFi.localIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.macAddress().c_str());
+ Serial.printf("[WIFI] GW %s\n", WiFi.gatewayIP().toString().c_str());
+ Serial.printf("[WIFI] MASK %s\n", WiFi.subnetMask().toString().c_str());
+ Serial.printf("[WIFI] DNS %s\n", WiFi.dnsIP().toString().c_str());
+ #if defined(ARDUINO_ARCH_ESP32)
+ Serial.printf("[WIFI] HOST %s\n", WiFi.getHostname());
+ #else
+ Serial.printf("[WIFI] HOST %s\n", WiFi.hostname().c_str());
+ #endif
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+ if (WiFi.getMode() & WIFI_AP) {
+
+ Serial.printf("[WIFI] MODE AP --------------------------------------\n");
+ Serial.printf("[WIFI] SSID %s\n", jw.getAPSSID().c_str());
+ Serial.printf("[WIFI] IP %s\n", WiFi.softAPIP().toString().c_str());
+ Serial.printf("[WIFI] MAC %s\n", WiFi.softAPmacAddress().c_str());
+ Serial.printf("[WIFI] ----------------------------------------------\n");
+
+ }
+
+}
+
+void infoCallback(justwifi_messages_t code, char * parameter) {
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_TURNING_OFF) {
+ Serial.printf("[WIFI] Turning OFF\n");
+ }
+
+ if (code == MESSAGE_TURNING_ON) {
+ Serial.printf("[WIFI] Turning ON\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_SCANNING) {
+ Serial.printf("[WIFI] Scanning\n");
+ }
+
+ if (code == MESSAGE_SCAN_FAILED) {
+ Serial.printf("[WIFI] Scan failed\n");
+ }
+
+ if (code == MESSAGE_NO_NETWORKS) {
+ Serial.printf("[WIFI] No networks found\n");
+ }
+
+ if (code == MESSAGE_NO_KNOWN_NETWORKS) {
+ Serial.printf("[WIFI] No known networks found\n");
+ }
+
+ if (code == MESSAGE_FOUND_NETWORK) {
+ Serial.printf("[WIFI] %s\n", parameter);
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_CONNECTING) {
+ Serial.printf("[WIFI] Connecting to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECT_WAITING) {
+ // too much noise
+ }
+
+ if (code == MESSAGE_CONNECT_FAILED) {
+ Serial.printf("[WIFI] Could not connect to %s\n", parameter);
+ }
+
+ if (code == MESSAGE_CONNECTED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_DISCONNECTED) {
+ Serial.printf("[WIFI] Disconnected\n");
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (code == MESSAGE_ACCESSPOINT_CREATED) {
+ infoWifi();
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_DESTROYED) {
+ Serial.printf("[WIFI] Disconnecting access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_CREATING) {
+ Serial.printf("[WIFI] Creating access point\n");
+ }
+
+ if (code == MESSAGE_ACCESSPOINT_FAILED) {
+ Serial.printf("[WIFI] Could not create access point\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_WPS_START) {
+ Serial.printf("[WIFI] WPS started\n");
+ }
+
+ if (code == MESSAGE_WPS_SUCCESS) {
+ Serial.printf("[WIFI] WPS succeded!\n");
+ }
+
+ if (code == MESSAGE_WPS_ERROR) {
+ Serial.printf("[WIFI] WPS failed\n");
+ }
+
+ // ------------------------------------------------------------------------
+
+ if (code == MESSAGE_SMARTCONFIG_START) {
+ Serial.printf("[WIFI] Smart Config started\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_SUCCESS) {
+ Serial.printf("[WIFI] Smart Config succeded!\n");
+ }
+
+ if (code == MESSAGE_SMARTCONFIG_ERROR) {
+ Serial.printf("[WIFI] Smart Config failed\n");
+ }
+
+};
diff --git a/examples/wps/wps.ino b/examples/wps/wps.ino
new file mode 100644
index 0000000..55769b2
--- /dev/null
+++ b/examples/wps/wps.ino
@@ -0,0 +1,61 @@
+/*
+
+JustWifi - WPS example
+
+This example shows how to use connect to a WiFi using WPS.
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+#include
+
+void setup() {
+
+ Serial.begin(115200);
+ delay(2000);
+ Serial.println();
+ Serial.println();
+
+ // -------------------------------------------------------------------------
+
+ // Init object
+ jw.init();
+
+ // Set WIFI hostname (otherwise it would be ESP-XXXXXX)
+ jw.setHostname("justwifi");
+
+ // Callbacks
+ jw.subscribe(infoCallback);
+
+ // -------------------------------------------------------------------------
+
+ Serial.println("[WIFI] JustWifi WPS example");
+ Serial.println("[WIFI] Click on your router WPS button...");
+
+ // Start WPS join
+ jw.startWPS();
+
+}
+
+void loop() {
+
+ // This call takes care of it all
+ jw.loop();
+
+ // Small delay to give some breath
+ delay(10);
+
+}
diff --git a/keywords.txt b/keywords.txt
new file mode 100644
index 0000000..ba92023
--- /dev/null
+++ b/keywords.txt
@@ -0,0 +1,61 @@
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+network_t KEYWORD1
+justwifi_messages_t KEYWORD1
+justwifi_states_t KEYWORD1
+TMessageFunction KEYWORD1
+
+#######################################
+# Classes (KEYWORD1)
+#######################################
+
+JustWifi KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+addCurrentNetwork KEYWORD2
+addNetwork KEYWORD2
+setSoftAP KEYWORD2
+setHostname KEYWORD2
+setConnectTimeout KEYWORD2
+setReconnectTimeout KEYWORD2
+resetReconnectTimeout KEYWORD2
+subscribe KEYWORD2
+getAPSSID KEYWORD2
+connectable KEYWORD2
+turnOff KEYWORD2
+turnOn KEYWORD2
+disconnect KEYWORD2
+enableScan KEYWORD2
+enableSTA KEYWORD2
+enableAP KEYWORD2
+enableAPFallback KEYWORD2
+startWPS KEYWORD2
+startSmartConfig KEYWORD2
+init KEYWORD2
+loop KEYWORD2
+_events KEYWORD2
+
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
+RESPONSE_START LITERAL1
+RESPONSE_OK LITERAL1
+RESPONSE_WAIT LITERAL1
+RESPONSE_FAIL LITERAL1
+
+JUSTWIFI_ENABLE_WPS LITERAL1
+JUSTWIFI_ENABLE_SMARTCONFIG LITERAL1
+
+DEFAULT_CONNECT_TIMEOUT LITERAL1
+DEFAULT_RECONNECT_INTERVAL LITERAL1
+JUSTWIFI_SMARTCONFIG_TIMEOUT LITERAL1
diff --git a/library.json b/library.json
new file mode 100644
index 0000000..fa84883
--- /dev/null
+++ b/library.json
@@ -0,0 +1,25 @@
+{
+ "name": "JustWifi",
+ "keywords": "wifi,manager,scan,wps,smartconfig",
+ "description": "Wifi Manager for ESP8266, supports multiple wifi networks, scan for strongest signal, WPS and SmartConfig",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/xoseperez/justwifi.git"
+ },
+ "version": "2.0.0",
+ "license": "LGPL-3.0",
+ "exclude": "tests",
+ "frameworks": "arduino",
+ "platforms": "espressif8266",
+ "dependencies": [
+ ],
+ "authors": {
+ "name": "Xose Perez",
+ "email": "xose.perez@gmail.com",
+ "url": "http://tinkerman.cat",
+ "maintainer": true
+ },
+ "examples": [
+ "examples/*/*.ino"
+ ]
+}
diff --git a/library.properties b/library.properties
new file mode 100644
index 0000000..bc6fdac
--- /dev/null
+++ b/library.properties
@@ -0,0 +1,10 @@
+name=JustWifi
+version=2.0.0
+author=Xose Pérez
+maintainer=Xose Pérez
+sentence=Wifi Manager for ESP8266
+paragraph=Supports multiple wifi networks, scan for strongest signal, WPS and SmartConfig
+category=Communication
+url=https://github.com/xoseperez/justwifi.git
+architectures=esp8266
+includes=JustWifi.h
diff --git a/pre-commit b/pre-commit
new file mode 100755
index 0000000..f814c9b
--- /dev/null
+++ b/pre-commit
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+"""
+
+Referencing current branch in github README.md [1]
+This pre-commit hook [2] updates the README.md file's
+Travis badge with the current branch. Based on [4].
+
+[1] http://stackoverflow.com/questions/18673694/referencing-current-branch-in-github-readme-md
+[2] http://www.git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
+[3] https://docs.travis-ci.com/user/status-images/
+[4] https://gist.github.com/dandye/dfe0870a6a1151c89ed9
+
+Copy this file to .git/hooks/
+
+"""
+
+import os
+import sys
+import re
+
+from subprocess import call, check_output
+try:
+ from urllib.parse import urlparse
+except ImportError:
+ from urlparse import urlparse
+
+from fileinput import FileInput
+# https://github.com/python/cpython/commit/6cb7b659#diff-78790b53ff259619377058acd4f74672
+if sys.version_info[0] < 3:
+ class FileInputCtx(FileInput):
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+
+ FileInput = FileInputCtx
+
+
+def run(cmd, cwd=None):
+ out = check_output(cmd, cwd=cwd)
+ out = out.decode("latin1").strip()
+
+ return out
+
+
+def git_parse_remote(cwd=None, remote="origin"):
+ remote_url = run([
+ "git", "config", "--local",
+ "--get", "remote.{}.url".format(remote)], cwd)
+
+ if remote_url.startswith("git"):
+ _, _, repo = remote_url.partition(":")
+ elif remote_url.startswith("https"):
+ parsed = urlparse(remote_url)
+ repo = parsed.path[1:]
+
+ path = repo.replace(".git", "")
+ return path.split("/")
+
+
+def git_branch(cwd=None):
+ return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd)
+
+
+def get_version(base, version_h="library.properties"):
+ version = "unknown"
+
+ path = os.path.join(base, version_h)
+ with open(path, "r") as version_f:
+ for line in version_f:
+ if line.startswith("version="):
+ version = line.replace("version=", "").strip()
+ break
+
+ return version
+
+TEMPLATES = {
+ "![travis]": "[![travis](https://travis-ci.org/{USER}/{REPO}.svg?branch={BRANCH})]" \
+ "(https://travis-ci.org/{USER}/{REPO})\n",
+ "![version]": "[![version](https://img.shields.io/badge/version-{VERSION}-brightgreen.svg)](CHANGELOG.md)\n",
+ "![branch]": "[![branch](https://img.shields.io/badge/branch-{BRANCH}-orange.svg)]" \
+ "(https://github.org/{USER}/{REPO}/tree/{BRANCH}/)\n",
+ "![codacy]": "[![codacy](https://img.shields.io/codacy/grade/{CODACY}/{BRANCH}.svg)]" \
+ "(https://www.codacy.com/app/{USER}/{REPO}/dashboard)\n"
+}
+
+README = "README.md"
+
+if __name__ == "__main__":
+ base = os.getcwd()
+
+ user, repo = git_parse_remote()
+ fmt = {
+ "USER": user,
+ "REPO": repo,
+ "BRANCH": git_branch(),
+ "VERSION": get_version(base),
+ "CODACY": "4ccbea0317c4415eb2d1c562feced407"
+ }
+ templates = [
+ (k, tmpl.format(**fmt))
+ for k, tmpl in TEMPLATES.items()
+ ]
+
+ def fmt_line(line):
+ for match, tmpl in templates:
+ if match in line:
+ return tmpl
+
+ return line
+
+ path = os.path.join(base, README)
+
+ with FileInput(path, inplace=True) as readme:
+ for line in readme:
+ sys.stdout.write(fmt_line(line))
+
+ sys.exit(call(["git", "add", README]))
diff --git a/src/JustWifi.cpp b/src/JustWifi.cpp
new file mode 100644
index 0000000..fe1448a
--- /dev/null
+++ b/src/JustWifi.cpp
@@ -0,0 +1,953 @@
+/*
+
+JustWifi 2.0.0
+
+Wifi Manager for ESP8266
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#include "JustWifi.h"
+#include
+
+#if defined(ARDUINO_ARCH_ESP32)
+extern "C" {
+ #include
+}
+#endif
+
+//------------------------------------------------------------------------------
+// CONSTRUCTOR
+//------------------------------------------------------------------------------
+
+JustWifi::JustWifi() {
+ _softap.ssid = NULL;
+ _timeout = 0;
+ uint32_t chip_id;
+ #if defined(ARDUINO_ARCH_ESP32)
+ chip_id = ESP.getEfuseMac() & 0xFFFFFFFF;
+ #else
+ chip_id = ESP.getChipId();
+ #endif
+ snprintf_P(_hostname, sizeof(_hostname), PSTR("ESP-%06X"), chip_id);
+}
+
+JustWifi::~JustWifi() {
+ cleanNetworks();
+}
+
+// -----------------------------------------------------------------------------
+// WPS
+// -----------------------------------------------------------------------------
+
+#if defined(JUSTWIFI_ENABLE_WPS)
+
+#if defined(ARDUINO_ARCH_ESP8266)
+
+#include "user_interface.h"
+
+wps_cb_status _jw_wps_status;
+
+void _jw_wps_status_cb(wps_cb_status status) {
+ _jw_wps_status = status;
+}
+
+
+#else
+
+#include "esp_wps.h"
+
+esp_wps_config_t _wifi_wps_config = WPS_CONFIG_INIT_DEFAULT(ESP_WPS_MODE);
+
+#endif
+
+void JustWifi::startWPS() {
+ _state = STATE_WPS_START;
+}
+
+#endif // defined(JUSTWIFI_ENABLE_WPS)
+
+//------------------------------------------------------------------------------
+// SMART CONFIG
+//------------------------------------------------------------------------------
+
+#if defined(JUSTWIFI_ENABLE_SMARTCONFIG)
+
+void JustWifi::startSmartConfig() {
+ _state = STATE_SMARTCONFIG_START;
+}
+
+#endif // defined(JUSTWIFI_ENABLE_SMARTCONFIG)
+
+//------------------------------------------------------------------------------
+// SCAN
+//------------------------------------------------------------------------------
+
+uint8_t JustWifi::_sortByRSSI() {
+
+ bool first = true;
+ uint8_t bestID = 0xFF;
+
+ for (uint8_t i = 0; i < _network_list.size(); i++) {
+
+ network_t * entry = &_network_list[i];
+
+ // if no data skip
+ if (entry->rssi == 0) continue;
+
+ // Empty list
+ if (first) {
+ first = false;
+ bestID = i;
+ entry->next = 0xFF;
+
+ // The best so far
+ } else if (entry->rssi > _network_list[bestID].rssi) {
+ entry->next = bestID;
+ bestID = i;
+
+ // Walk the list
+ } else {
+
+ network_t * current = &_network_list[bestID];
+ while (current->next != 0xFF) {
+ if (entry->rssi > _network_list[current->next].rssi) {
+ entry->next = current->next;
+ current->next = i;
+ break;
+ }
+ current = &_network_list[current->next];
+ }
+
+ // Place it the last
+ if (current->next == 0xFF) {
+ current->next = i;
+ entry->next = 0xFF;
+ }
+
+ }
+
+ }
+
+ return bestID;
+
+}
+
+String JustWifi::_encodingString(uint8_t security) {
+ #if defined(ARDUINO_ARCH_ESP32)
+ if (security == WIFI_AUTH_WEP) return String("WEP ");
+ if (security == WIFI_AUTH_WPA_PSK) return String("WPA ");
+ if (security == WIFI_AUTH_WPA2_PSK) return String("WPA2 ");
+ if (security == WIFI_AUTH_WPA_WPA2_PSK) return String("WPA* ");
+ if (security == WIFI_AUTH_WPA2_ENTERPRISE) return String("WPA2E");
+ if (security == WIFI_AUTH_MAX) return String("MAX ");
+ #else
+ if (security == ENC_TYPE_WEP) return String("WEP ");
+ if (security == ENC_TYPE_TKIP) return String("WPA ");
+ if (security == ENC_TYPE_CCMP) return String("WPA2 ");
+ if (security == ENC_TYPE_AUTO) return String("AUTO ");
+ #endif
+ return String("OPEN ");
+}
+
+uint8_t JustWifi::_populate(uint8_t networkCount) {
+
+ uint8_t count = 0;
+
+ // Reset RSSI to disable networks that have disappeared
+ for (uint8_t j = 0; j < _network_list.size(); j++) {
+ _network_list[j].rssi = 0;
+ _network_list[j].scanned = false;
+ }
+
+ String ssid_scan;
+ int32_t rssi_scan;
+ uint8_t sec_scan;
+ uint8_t* BSSID_scan;
+ int32_t chan_scan;
+
+ // Populate defined networks with scan data
+ for (int8_t i = 0; i < networkCount; ++i) {
+
+ #if defined(ARDUINO_ARCH_ESP32)
+ WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
+ #else
+ bool hidden_scan;
+ WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
+ #endif
+
+ bool known = false;
+
+ for (uint8_t j = 0; j < _network_list.size(); j++) {
+
+ network_t * entry = &_network_list[j];
+
+ if (ssid_scan.equals(entry->ssid)) {
+
+ // Check security
+ #if defined(ARDUINO_ARCH_ESP32)
+ if ((sec_scan != WIFI_AUTH_OPEN) && (entry->pass == NULL)) continue;
+ #else
+ if ((sec_scan != ENC_TYPE_NONE) && (entry->pass == NULL)) continue;
+ #endif
+
+ // In case of several networks with the same SSID
+ // we want to get the one with the best RSSI
+ // Thanks to Robert (robi772 @ bitbucket.org)
+ if (entry->rssi < rssi_scan || entry->rssi == 0) {
+ entry->rssi = rssi_scan;
+ entry->security = sec_scan;
+ entry->channel = chan_scan;
+ entry->scanned = true;
+ memcpy((void*) &entry->bssid, (void*) BSSID_scan, sizeof(entry->bssid));
+ }
+
+ count++;
+ known = true;
+ break;
+
+ }
+
+ }
+
+ if (_callbacks.size()) {
+
+ char buffer[128];
+ sprintf_P(buffer,
+ PSTR("%s BSSID: %02X:%02X:%02X:%02X:%02X:%02X CH: %2d RSSI: %3d SEC: %s SSID: %s"),
+ (known ? "-->" : " "),
+ BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5],
+ chan_scan,
+ rssi_scan,
+ _encodingString(sec_scan).c_str(),
+ ssid_scan.c_str()
+ );
+ _doCallback(MESSAGE_FOUND_NETWORK, buffer);
+
+ }
+
+ }
+
+ return count;
+
+}
+
+void JustWifi::_esp8266_153_reset() {
+
+ #if defined(ARDUINO_ARCH_ESP8266)
+
+ // See https://github.com/esp8266/Arduino/issues/2186
+ if (strncmp_P(ESP.getSdkVersion(), PSTR("1.5.3"), 5) == 0) {
+ if ((WiFi.getMode() & WIFI_AP) > 0) {
+ WiFi.mode(WIFI_OFF);
+ delay(10);
+ WiFi.enableAP(true);
+ } else {
+ WiFi.mode(WIFI_OFF);
+ }
+
+ }
+
+ #endif
+
+}
+
+uint8_t JustWifi::_doScan() {
+
+ static bool scanning = false;
+
+ // If not scanning, start scan
+ if (false == scanning) {
+ WiFi.disconnect();
+ WiFi.enableSTA(true);
+ WiFi.scanNetworks(true, true);
+ _doCallback(MESSAGE_SCANNING);
+ scanning = true;
+ return RESPONSE_WAIT;
+ }
+
+ // Check if scanning
+ int8_t scanResult = WiFi.scanComplete();
+ if (WIFI_SCAN_RUNNING == scanResult) {
+ return RESPONSE_WAIT;
+ }
+
+ // Scan finished
+ scanning = false;
+
+ // Sometimes the scan fails,
+ // this will force the scan to restart
+ if (WIFI_SCAN_FAILED == scanResult) {
+ _doCallback(MESSAGE_SCAN_FAILED);
+ return RESPONSE_WAIT;
+ }
+
+ // Check networks
+ if (0 == scanResult) {
+ WiFi.enableSTA(false);
+ _doCallback(MESSAGE_NO_NETWORKS);
+ return RESPONSE_FAIL;
+ }
+
+ // Populate network list
+ uint8_t count = _populate(scanResult);
+
+ // Free memory
+ WiFi.scanDelete();
+
+ if (0 == count) {
+ WiFi.enableSTA(false);
+ _doCallback(MESSAGE_NO_KNOWN_NETWORKS);
+ return RESPONSE_FAIL;
+ }
+
+ // Sort networks by RSSI
+ _currentID = _sortByRSSI();
+ return RESPONSE_OK;
+
+}
+
+// -----------------------------------------------------------------------------
+// STA
+// -----------------------------------------------------------------------------
+
+uint8_t JustWifi::_doSTA(uint8_t id) {
+
+ static uint8_t networkID;
+ static uint8_t state = RESPONSE_START;
+ static unsigned long timeout;
+
+ // Reset connection process
+ if (id != 0xFF) {
+ state = RESPONSE_START;
+ networkID = id;
+ }
+
+ // Get network
+ network_t entry = _network_list[networkID];
+
+ // No state or previous network failed
+ if (RESPONSE_START == state) {
+
+ // Init some values
+ WiFi.persistent(false);
+ _esp8266_153_reset();
+ WiFi.enableSTA(true);
+
+ // Configure static options
+ if (!entry.dhcp) {
+ WiFi.config(entry.ip, entry.gw, entry.netmask, entry.dns);
+ }
+
+ // Info callback
+ if (_callbacks.size()) {
+ char buffer[128];
+ if (entry.scanned) {
+ snprintf_P(buffer, sizeof(buffer),
+ PSTR("BSSID: %02X:%02X:%02X:%02X:%02X:%02X CH: %02d, RSSI: %3d, SEC: %s, SSID: %s"),
+ entry.bssid[0], entry.bssid[1], entry.bssid[2], entry.bssid[3], entry.bssid[4], entry.bssid[5],
+ entry.channel,
+ entry.rssi,
+ _encodingString(entry.security).c_str(),
+ entry.ssid
+ );
+ } else {
+ snprintf_P(buffer, sizeof(buffer), PSTR("SSID: %s"), entry.ssid);
+ }
+ _doCallback(MESSAGE_CONNECTING, buffer);
+ }
+
+ // Connecting
+ if (entry.channel == 0) {
+ WiFi.begin(entry.ssid, entry.pass);
+ } else {
+ WiFi.begin(entry.ssid, entry.pass, entry.channel, entry.bssid);
+ }
+
+ timeout = millis();
+ return (state = RESPONSE_WAIT);
+
+ }
+
+ // Connected?
+ if (WiFi.status() == WL_CONNECTED) {
+
+ // Hostname
+ #if defined(ARDUINO_ARCH_ESP32)
+ WiFi.setHostname(_hostname);
+ #else
+ WiFi.hostname(_hostname);
+ #endif
+
+ // Autoconnect only if DHCP, since it doesn't store static IP data
+ WiFi.setAutoConnect(entry.dhcp);
+
+ WiFi.setAutoReconnect(true);
+ _doCallback(MESSAGE_CONNECTED);
+ return (state = RESPONSE_OK);
+
+ }
+
+ // Check timeout
+ if (millis() - timeout > _connect_timeout) {
+ WiFi.enableSTA(false);
+ _doCallback(MESSAGE_CONNECT_FAILED, entry.ssid);
+ return (state = RESPONSE_FAIL);
+ }
+
+ // Still waiting
+ _doCallback(MESSAGE_CONNECT_WAITING);
+ return state;
+
+}
+
+// -----------------------------------------------------------------------------
+// AP
+// -----------------------------------------------------------------------------
+
+bool JustWifi::_doAP() {
+
+ // If already created recreate
+ if (_ap_connected) enableAP(false);
+
+ // Check if Soft AP configuration defined
+ if (!_softap.ssid) {
+ _softap.ssid = strdup(_hostname);
+ }
+
+ _doCallback(MESSAGE_ACCESSPOINT_CREATING);
+
+ WiFi.enableAP(true);
+
+ // Configure static options
+ if (_softap.dhcp) {
+ WiFi.softAPConfig(_softap.ip, _softap.gw, _softap.netmask);
+ }
+
+ if (_softap.pass) {
+ WiFi.softAP(_softap.ssid, _softap.pass);
+ } else {
+ WiFi.softAP(_softap.ssid);
+ }
+
+ _doCallback(MESSAGE_ACCESSPOINT_CREATED);
+
+ _ap_connected = true;
+ return true;
+
+}
+
+// -----------------------------------------------------------------------------
+// CALLBACKS
+// -----------------------------------------------------------------------------
+
+void JustWifi::_doCallback(justwifi_messages_t message, char * parameter) {
+ for (unsigned char i=0; i < _callbacks.size(); i++) {
+ (_callbacks[i])(message, parameter);
+ }
+}
+
+void JustWifi::subscribe(TMessageFunction fn) {
+ _callbacks.push_back(fn);
+}
+
+// -----------------------------------------------------------------------------
+// STATE MACHINE
+// -----------------------------------------------------------------------------
+
+void JustWifi::_machine() {
+
+ #if false
+ static unsigned char previous = 0xFF;
+ if (_state != previous) {
+ previous = _state;
+ Serial.printf("_state: %u, WiFi.getMode(): %u\n", _state, WiFi.getMode());
+ }
+ #endif
+
+ switch(_state) {
+
+ // ---------------------------------------------------------------------
+
+ case STATE_IDLE:
+
+ // Should we connect in STA mode?
+ if (WiFi.status() != WL_CONNECTED) {
+
+ if (_sta_enabled) {
+ if (_network_list.size() > 0) {
+ if ((0 == _timeout) || ((_reconnect_timeout > 0) && (millis() - _timeout > _reconnect_timeout))) {
+ _currentID = 0;
+ _state = _scan ? STATE_SCAN_START : STATE_STA_START;
+ return;
+ }
+ }
+ }
+
+ // Fallback
+ if (!_ap_connected & _ap_fallback_enabled) {
+ _state = STATE_FALLBACK;
+ }
+
+ }
+
+
+ break;
+
+ // ---------------------------------------------------------------------
+
+ case STATE_SCAN_START:
+ _doScan();
+ _state = STATE_SCAN_ONGOING;
+ break;
+
+ case STATE_SCAN_ONGOING:
+ {
+ uint8_t response = _doScan();
+ if (RESPONSE_OK == response) {
+ _state = STATE_STA_START;
+ } else if (RESPONSE_FAIL == response) {
+ _state = STATE_FALLBACK;
+ }
+ }
+ break;
+
+ // ---------------------------------------------------------------------
+
+ case STATE_STA_START:
+ _doSTA(_currentID);
+ _state = STATE_STA_ONGOING;
+ break;
+
+ case STATE_STA_ONGOING:
+ {
+ uint8_t response = _doSTA();
+ if (RESPONSE_OK == response) {
+ _state = STATE_STA_SUCCESS;
+ } else if (RESPONSE_FAIL == response) {
+ _state = STATE_STA_START;
+ if (_scan) {
+ _currentID = _network_list[_currentID].next;
+ if (_currentID == 0xFF) {
+ _state = STATE_STA_FAILED;
+ }
+ } else {
+ _currentID++;
+ if (_currentID == _network_list.size()) {
+ _state = STATE_STA_FAILED;
+ }
+ }
+ }
+ }
+ break;
+
+ case STATE_STA_FAILED:
+ _state = STATE_FALLBACK;
+ break;
+
+ case STATE_STA_SUCCESS:
+ _state = STATE_IDLE;
+ break;
+
+ // ---------------------------------------------------------------------
+
+ #if defined(JUSTWIFI_ENABLE_WPS)
+
+ case STATE_WPS_START:
+
+ _doCallback(MESSAGE_WPS_START);
+
+ #if defined(ARDUINO_ARCH_ESP8266)
+
+ _esp8266_153_reset();
+
+ if (!WiFi.enableSTA(true)) {
+ _state = STATE_WPS_FAILED;
+ return;
+ }
+
+ WiFi.disconnect();
+
+ if (!wifi_wps_disable()) {
+ _state = STATE_WPS_FAILED;
+ return;
+ }
+
+ // so far only WPS_TYPE_PBC is supported (SDK 1.2.0)
+ if (!wifi_wps_enable(WPS_TYPE_PBC)) {
+ _state = STATE_WPS_FAILED;
+ return;
+ }
+
+ _jw_wps_status = (wps_cb_status) 5;
+ if (!wifi_set_wps_cb((wps_st_cb_t) &_jw_wps_status_cb)) {
+ _state = STATE_WPS_FAILED;
+ return;
+ }
+
+ if (!wifi_wps_start()) {
+ _state = STATE_WPS_FAILED;
+ return;
+ }
+
+ #else
+
+ esp_wifi_wps_enable(&_wifi_wps_config);
+ esp_wifi_wps_start(0);
+
+ #endif
+
+ _state = STATE_WPS_ONGOING;
+ break;
+
+ case STATE_WPS_ONGOING:
+ if (5 == _jw_wps_status) {
+ // Still ongoing
+ } else if (WPS_CB_ST_SUCCESS == _jw_wps_status) {
+ _state = STATE_WPS_SUCCESS;
+ } else {
+ _state = STATE_WPS_FAILED;
+ }
+ break;
+
+ case STATE_WPS_FAILED:
+ _doCallback(MESSAGE_WPS_ERROR);
+ wifi_wps_disable();
+ _state = STATE_FALLBACK;
+ break;
+
+ case STATE_WPS_SUCCESS:
+ _doCallback(MESSAGE_WPS_SUCCESS);
+ wifi_wps_disable();
+ addCurrentNetwork(true);
+ _state = STATE_IDLE;
+ break;
+
+ #endif // defined(JUSTWIFI_ENABLE_WPS)
+
+ // ---------------------------------------------------------------------
+
+ #if defined(JUSTWIFI_ENABLE_SMARTCONFIG)
+
+ case STATE_SMARTCONFIG_START:
+
+ _doCallback(MESSAGE_SMARTCONFIG_START);
+
+ enableAP(false);
+
+ if (!WiFi.beginSmartConfig()) {
+ _state = STATE_SMARTCONFIG_FAILED;
+ return;
+ }
+
+ _state = STATE_SMARTCONFIG_ONGOING;
+ _start = millis();
+
+ break;
+
+ case STATE_SMARTCONFIG_ONGOING:
+ if (WiFi.smartConfigDone()) {
+ _state = STATE_SMARTCONFIG_SUCCESS;
+ } else if (millis() - _start > JUSTWIFI_SMARTCONFIG_TIMEOUT) {
+ _state = STATE_SMARTCONFIG_FAILED;
+ }
+ break;
+
+ case STATE_SMARTCONFIG_FAILED:
+ _doCallback(MESSAGE_SMARTCONFIG_ERROR);
+ WiFi.stopSmartConfig();
+ WiFi.enableSTA(false);
+ _state = STATE_FALLBACK;
+ break;
+
+ case STATE_SMARTCONFIG_SUCCESS:
+ _doCallback(MESSAGE_SMARTCONFIG_SUCCESS);
+ addCurrentNetwork(true);
+ _state = STATE_IDLE;
+ break;
+
+ #endif // defined(JUSTWIFI_ENABLE_SMARTCONFIG)
+
+ // ---------------------------------------------------------------------
+
+ case STATE_FALLBACK:
+ if (!_ap_connected & _ap_fallback_enabled) _doAP();
+ _timeout = millis();
+ _state = STATE_IDLE;
+ break;
+
+ default:
+ _state = STATE_IDLE;
+ break;
+
+ }
+
+}
+
+//------------------------------------------------------------------------------
+// PUBLIC API
+//------------------------------------------------------------------------------
+
+void JustWifi::cleanNetworks() {
+ for (uint8_t i = 0; i < _network_list.size(); i++) {
+ network_t entry = _network_list[i];
+ if (entry.ssid) free(entry.ssid);
+ if (entry.pass) free(entry.pass);
+ }
+ _network_list.clear();
+}
+
+bool JustWifi::addNetwork(
+ const char * ssid,
+ const char * pass,
+ const char * ip,
+ const char * gw,
+ const char * netmask,
+ const char * dns,
+ bool front
+) {
+
+ network_t new_network;
+
+ // Check SSID too long or missing
+ if (!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
+ return false;
+ }
+
+ // Check PASS too long
+ if (pass && strlen(pass) > 63) {
+ return false;
+ }
+
+ // Copy network SSID
+ new_network.ssid = strdup(ssid);
+ if (!new_network.ssid) {
+ return false;
+ }
+
+ // Copy network PASS
+ if (pass && *pass != 0x00) {
+ new_network.pass = strdup(pass);
+ if (!new_network.pass) {
+ free(new_network.ssid);
+ return false;
+ }
+ } else {
+ new_network.pass = NULL;
+ }
+
+ // Copy static config
+ new_network.dhcp = true;
+ if (ip && gw && netmask
+ && *ip != 0x00 && *gw != 0x00 && *netmask != 0x00) {
+ new_network.dhcp = false;
+ new_network.ip.fromString(ip);
+ new_network.gw.fromString(gw);
+ new_network.netmask.fromString(netmask);
+ }
+ if (dns && *dns != 0x00) {
+ new_network.dns.fromString(dns);
+ }
+
+ // Defaults
+ new_network.rssi = 0;
+ new_network.security = 0;
+ new_network.channel = 0;
+ new_network.next = 0xFF;
+ new_network.scanned = false;
+
+ // Store data
+ if (front) {
+ _network_list.insert(_network_list.begin(), new_network);
+ } else {
+ _network_list.push_back(new_network);
+ }
+ return true;
+
+}
+
+bool JustWifi::addCurrentNetwork(bool front) {
+ return addNetwork(
+ WiFi.SSID().c_str(),
+ WiFi.psk().c_str(),
+ NULL, NULL, NULL, NULL,
+ front
+ );
+}
+
+bool JustWifi::setSoftAP(
+ const char * ssid,
+ const char * pass,
+ const char * ip,
+ const char * gw,
+ const char * netmask
+) {
+
+ // Check SSID too long or missing
+ if (!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
+ return false;
+ }
+
+ // Check PASS too long
+ if (pass && strlen(pass) > 63) {
+ return false;
+ }
+
+ // Copy network SSID
+ _softap.ssid = strdup(ssid);
+ if (!_softap.ssid) {
+ return false;
+ }
+
+ // Copy network PASS
+ if (pass && *pass != 0x00) {
+ _softap.pass = strdup(pass);
+ if (!_softap.pass) {
+ _softap.ssid = NULL;
+ return false;
+ }
+ }
+
+ // Copy static config
+ _softap.dhcp = false;
+ if (ip && gw && netmask
+ && *ip != 0x00 && *gw != 0x00 && *netmask != 0x00) {
+ _softap.dhcp = true;
+ _softap.ip.fromString(ip);
+ _softap.gw.fromString(gw);
+ _softap.netmask.fromString(netmask);
+ }
+
+ if ((WiFi.getMode() & WIFI_AP) > 0) {
+
+ // https://github.com/xoseperez/justwifi/issues/4
+ if (_softap.pass) {
+ WiFi.softAP(_softap.ssid, _softap.pass);
+ } else {
+ WiFi.softAP(_softap.ssid);
+ }
+
+ }
+
+ return true;
+
+}
+
+void JustWifi::setConnectTimeout(unsigned long ms) {
+ _connect_timeout = ms;
+}
+
+void JustWifi::setReconnectTimeout(unsigned long ms) {
+ _reconnect_timeout = ms;
+}
+
+void JustWifi::resetReconnectTimeout() {
+ _timeout = millis();
+}
+
+void JustWifi::setHostname(const char * hostname) {
+ strncpy(_hostname, hostname, sizeof(_hostname));
+}
+
+String JustWifi::getAPSSID() {
+ return String(_softap.ssid);
+}
+
+bool JustWifi::connected() {
+ return (WiFi.status() == WL_CONNECTED);
+}
+
+bool JustWifi::connectable() {
+ return _ap_connected;
+}
+
+void JustWifi::disconnect() {
+ _timeout = 0;
+ WiFi.disconnect();
+ WiFi.enableSTA(false);
+ _doCallback(MESSAGE_DISCONNECTED);
+}
+
+void JustWifi::turnOff() {
+
+ WiFi.disconnect();
+ WiFi.enableAP(false);
+ WiFi.enableSTA(false);
+ #if defined(ARDUINO_ARCH_ESP8266)
+ WiFi.forceSleepBegin();
+ #endif
+ delay(1);
+
+ _sta_enabled = false;
+ _state = STATE_IDLE;
+ _doCallback(MESSAGE_TURNING_OFF);
+
+}
+
+void JustWifi::turnOn() {
+
+ #if defined(ARDUINO_ARCH_ESP8266)
+ WiFi.forceSleepWake();
+ #endif
+ delay(1);
+
+ setReconnectTimeout(0);
+ _sta_enabled = true;
+ _state = STATE_IDLE;
+ _doCallback(MESSAGE_TURNING_ON);
+
+}
+
+void JustWifi::enableSTA(bool enabled) {
+ _sta_enabled = enabled;
+}
+
+void JustWifi::enableAP(bool enabled) {
+ if (enabled) {
+ _doAP();
+ } else if (_ap_connected) {
+ WiFi.softAPdisconnect();
+ WiFi.enableAP(false);
+ _ap_connected = false;
+ _doCallback(MESSAGE_ACCESSPOINT_DESTROYED);
+ }
+}
+
+void JustWifi::enableAPFallback(bool enabled) {
+ _ap_fallback_enabled = enabled;
+}
+
+void JustWifi::enableScan(bool scan) {
+ _scan = scan;
+}
+
+void JustWifi::_events(WiFiEvent_t event) {
+ Serial.printf("[WIFI] Event %u\n", (uint8_t) event);
+ Serial.println(event);
+}
+
+void JustWifi::init() {
+ WiFi.enableAP(false);
+ WiFi.enableSTA(false);
+ //WiFi.onEvent(reinterpret_cast(&JustWifi::_events), WIFI_EVENT_ANY);
+}
+
+void JustWifi::loop() {
+ _machine();
+}
+
+JustWifi jw;
diff --git a/src/JustWifi.h b/src/JustWifi.h
new file mode 100644
index 0000000..09ca1f4
--- /dev/null
+++ b/src/JustWifi.h
@@ -0,0 +1,218 @@
+/*
+
+JustWifi 2.0.0
+
+Wifi Manager for ESP8266
+
+Copyright (C) 2016-2018 by Xose Pérez
+
+The JustWifi 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 3 of the License, or
+(at your option) any later version.
+
+The JustWifi 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 the JustWifi library. If not, see .
+
+*/
+
+#ifndef JustWifi_h
+#define JustWifi_h
+
+#include
+#include
+#if defined(ARDUINO_ARCH_ESP32)
+#include
+#elif defined(ARDUINO_ARCH_ESP8266)
+#include
+extern "C" {
+ #include "user_interface.h"
+}
+#else
+#error "Non supported architecture!"
+#endif
+
+
+#define DEFAULT_CONNECT_TIMEOUT 20000
+#define DEFAULT_RECONNECT_INTERVAL 60000
+#define JUSTWIFI_SMARTCONFIG_TIMEOUT 60000
+
+#ifdef DEBUG_ESP_WIFI
+#ifdef DEBUG_ESP_PORT
+#define DEBUG_WIFI_MULTI(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ )
+#endif
+#endif
+
+#ifndef DEBUG_WIFI_MULTI
+#define DEBUG_WIFI_MULTI(...)
+#endif
+
+typedef struct {
+ char * ssid;
+ char * pass;
+ bool dhcp;
+ bool scanned;
+ IPAddress ip;
+ IPAddress gw;
+ IPAddress netmask;
+ IPAddress dns;
+ int32_t rssi;
+ uint8_t security;
+ uint8_t channel;
+ uint8_t bssid[6];
+ uint8_t next;
+} network_t;
+
+typedef enum {
+ STATE_IDLE,
+ STATE_SCAN_START,
+ STATE_SCAN_ONGOING,
+ STATE_STA_START,
+ STATE_STA_ONGOING,
+ STATE_STA_FAILED,
+ STATE_STA_SUCCESS,
+ STATE_WPS_START,
+ STATE_WPS_ONGOING,
+ STATE_WPS_FAILED,
+ STATE_WPS_SUCCESS,
+ STATE_SMARTCONFIG_START,
+ STATE_SMARTCONFIG_ONGOING,
+ STATE_SMARTCONFIG_FAILED,
+ STATE_SMARTCONFIG_SUCCESS,
+ STATE_FALLBACK
+} justwifi_states_t;
+
+typedef enum {
+ MESSAGE_SCANNING,
+ MESSAGE_SCAN_FAILED,
+ MESSAGE_NO_NETWORKS,
+ MESSAGE_FOUND_NETWORK,
+ MESSAGE_NO_KNOWN_NETWORKS,
+ MESSAGE_CONNECTING,
+ MESSAGE_CONNECT_WAITING,
+ MESSAGE_CONNECT_FAILED,
+ MESSAGE_CONNECTED,
+ MESSAGE_ACCESSPOINT_CREATING,
+ MESSAGE_ACCESSPOINT_CREATED,
+ MESSAGE_ACCESSPOINT_FAILED,
+ MESSAGE_ACCESSPOINT_DESTROYED,
+ MESSAGE_DISCONNECTED,
+ MESSAGE_HOSTNAME_ERROR,
+ MESSAGE_TURNING_OFF,
+ MESSAGE_TURNING_ON,
+ MESSAGE_WPS_START,
+ MESSAGE_WPS_SUCCESS,
+ MESSAGE_WPS_ERROR,
+ MESSAGE_SMARTCONFIG_START,
+ MESSAGE_SMARTCONFIG_SUCCESS,
+ MESSAGE_SMARTCONFIG_ERROR
+} justwifi_messages_t;
+
+enum {
+ RESPONSE_START,
+ RESPONSE_OK,
+ RESPONSE_WAIT,
+ RESPONSE_FAIL
+};
+
+class JustWifi {
+
+ public:
+
+ typedef std::function TMessageFunction;
+
+ JustWifi();
+ ~JustWifi();
+
+ void cleanNetworks();
+ bool addCurrentNetwork(bool front = false);
+ bool addNetwork(
+ const char * ssid,
+ const char * pass = NULL,
+ const char * ip = NULL,
+ const char * gw = NULL,
+ const char * netmask = NULL,
+ const char * dns = NULL,
+ bool front = false
+ );
+ bool setSoftAP(
+ const char * ssid,
+ const char * pass = NULL,
+ const char * ip = NULL,
+ const char * gw = NULL,
+ const char * netmask = NULL
+ );
+
+ void setHostname(const char * hostname);
+ void setConnectTimeout(unsigned long ms);
+ void setReconnectTimeout(unsigned long ms = DEFAULT_RECONNECT_INTERVAL);
+ void resetReconnectTimeout();
+ void subscribe(TMessageFunction fn);
+
+ String getAPSSID();
+ bool connectable();
+
+ bool connected();
+
+ void turnOff();
+ void turnOn();
+ void disconnect();
+ void enableScan(bool scan);
+ void enableSTA(bool enabled);
+ void enableAP(bool enabled);
+ void enableAPFallback(bool enabled);
+
+ #if defined(JUSTWIFI_ENABLE_WPS)
+ void startWPS();
+ #endif
+
+ #if defined(JUSTWIFI_ENABLE_SMARTCONFIG)
+ void startSmartConfig();
+ #endif
+
+ void init();
+ void loop();
+
+ void _events(WiFiEvent_t event);
+
+ private:
+
+ std::vector _network_list;
+ std::vector _callbacks;
+
+ unsigned long _connect_timeout = DEFAULT_CONNECT_TIMEOUT;
+ unsigned long _reconnect_timeout = DEFAULT_RECONNECT_INTERVAL;
+ unsigned long _timeout = 0;
+ unsigned long _start = 0;
+ uint8_t _currentID;
+ bool _scan = false;
+ char _hostname[32];
+ network_t _softap { NULL, NULL };
+
+ justwifi_states_t _state = STATE_IDLE;
+ bool _sta_enabled = true;
+ bool _ap_connected = false;
+ bool _ap_fallback_enabled = true;
+
+ bool _doAP();
+ uint8_t _doScan();
+ uint8_t _doSTA(uint8_t id = 0xFF);
+
+ void _esp8266_153_reset();
+ void _machine();
+ uint8_t _populate(uint8_t networkCount);
+ uint8_t _sortByRSSI();
+ String _MAC2String(const unsigned char* mac);
+ String _encodingString(uint8_t security);
+ void _doCallback(justwifi_messages_t message, char * parameter = NULL);
+
+};
+
+extern JustWifi jw;
+
+#endif