WiFiConfig/src/WiFiConfig.h

170 lines
6.4 KiB
C++

/**
* @file WiFiConfig.h
* @author Pavel Brychta, http://www.xpablo.cz
*
* Copyright (c) 2015-21 Pavel Brychta. All rights reserved.
*
* 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
*
*/
/* Nastaveni ESP modulu, ktere pracuje takto:
* 1. Pokud je forceConfigure ==0, tak se aktivuje WiFi v rezimu AP a cele ESP je mozne nastavit webovym rozhranim (pocitam s prenosem hodnoty nouzoveho tlacitka pri startu).
* 2. Neni-li tlacitko stisknute, tak se vezme rezim prace a AP se nastavi dle nej (WIFI_STA a WIFI_AP)
* 3. Pokud byl rezim prace WIFI_STA a ESP se nepripoji k zadne siti do casu WIFI_STA_CONNECT_TIMEOUT, tak se pokracuje jako kdyby bylo stisknute rekonfiguracni tlacitko
* Podrobnejsi informace o upravach chovani v jednotlivych verzich jsou v zahlavi .cpp souboru.
*/
#ifndef __WiFiConfig_h__
#define __WiFiConfig_h__
#if defined(ESP8266)
# include <ESP8266WiFi.h>
#else
# include <WiFi.h>
#endif
#include <memory>
#include <ESPAsyncWebServer.h>
#include <DNSServer.h>
#define WC_DONT_RUN_CONFIGAP -1 // priznak, ze si neprejeme spoustet konfiguracni AP (uziva se misto parametru timeout). Urceno pro bateriove napajene pristroje
#if not defined(WIFICFG_FILE)
# define WIFICFG_FILE "/wifi.json"
#endif
// Parametr, predany uzivatelske callback funkci, urceny pro aplikacni vizualizaci stavu konfigurace a pripojeni
typedef enum {
WCS_CONNECTSTART = 0, // zacatek pokusu o pripojeni k ulozene konfiguraci
WCS_CONNECTING = 1, // probiha pokus o pripojeni
WCS_CONNECTED = 2, // pripojeni bylo uspesne/byl spusteny AP
WCS_CONFIGSTART = 3, // zacatek startu konfiguracniho AP
WCS_CONFIGWAIT = 4, // cekame na nastaveni konfigurace pres web
WCS_CONFIGTIMEOUT = 5, // doslo k vyprseni timeoutu konfigurace, budeme se vracet s False jako vysledek z .begin(...)
} wificonfigstate_t;
// Navratovy parametr z volani begin() - udava, jak se podarilo WiFiConfig modulu pripojit k AP
typedef enum {
WCR_OK = 0, // wifi pripojena/AP nastartovane (dle parametru v EEPROM)
WCR_TIMEOUT = 1, // wifi neni pripojena a vyprsel zadany timeout
WCR_CONFIGAP_NOT_STARTED = 2, // wifi neni pripojena a spusteni konfiguracniho AP bylo zakazane parametrem timeout (WC_DONT_RUN_CONFIGAP)
} wificonfigresult_t;
// Interni reprezentace konfigurace WiFi
enum {
WIFIMODE_AP = WIFI_AP, // rezim prace jako pristupovy bod (AP)
WIFIMODE_STA = WIFI_STA, // rezim prace jako klient
WIFIMODE_AP_STA = WIFI_AP_STA // rezim prace jako klient i pristupovy bod
};
// Interni reprezentace konfigurace ip
enum {
IPCONFIG_DHCP = 0x55, // DHCP konfigurace ip adres (default)
IPCONFIG_STATIC = 0xaa // staticka konfigurace ip adres
};
typedef void (*wificonfig_cb)(wificonfigstate_t state); // definice callbacku
typedef void (*storeparam_cb)(const char *newvalue); // callback pro ulozeni uzivatelskeho parametru
#ifndef WIFI_STA_CONNECT_TIMEOUT
# define WIFI_STA_CONNECT_TIMEOUT 20000UL // delka cekani na pripojeni k AP [ms]
#endif
#ifndef SETUP_SSID
# define SETUP_SSID "ESPPBSetup_?"
#endif
#ifndef SETUP_CHANNEL
# define SETUP_CHANNEL 3
#endif
/**
* \brief Ziskani nasi ip adresy
*
* \return Nase ip adresa, ziskana dle rezimu prace modulu
*/
IPAddress getOurIP(void);
/**
* \brief Ziskani nasi MAC adresy
*
* \param [in] mac kam ma byt MAC adresa ulozena
* \return Ukazatel na ulozenou MAC adresu (vraci parametr mac)
*
* \details Details
*/
uint8_t * getOurMAC(uint8_t *mac);
class WiFiConfigUsrParameter
{
public:
WiFiConfigUsrParameter(const char *id, const char *label, const char *defaultValue, unsigned int length, storeparam_cb cb);
const char *getID();
const char *getValue();
const char *getLabel();
int getValueLength();
void setNext(WiFiConfigUsrParameter *n);
WiFiConfigUsrParameter *getNext();
void setNewValue(const char *newval);
private:
const char *_id;
const char *_label;
char *_value;
int _length;
storeparam_cb _cb;
WiFiConfigUsrParameter *_next;
friend class WiFiConfig;
};
class WiFiConfig
{
public:
WiFiConfig(): _params(nullptr), _timeout(0) {}
wificonfigresult_t begin(int forceConfigure, wificonfig_cb cb);
wificonfigresult_t begin(int forceConfigure, int timeout, wificonfig_cb cb);
void addParameter(WiFiConfigUsrParameter *p);
void initConfig(const String &ssid, const String &pass, const int mode = WIFIMODE_STA, const int ipcfg = IPCONFIG_DHCP, const IPAddress &ip = (uint32_t)0, const IPAddress &mask = (uint32_t)0, const IPAddress &gw = (uint32_t)0, const IPAddress &dns = (uint32_t)0);
private:
AsyncWebServer *server;
std::unique_ptr<DNSServer> dnsServer;
void _prepareWifi(void);
wificonfigresult_t _setupAP(wificonfig_cb cb);
void _handleDisplayAP(AsyncWebServerRequest *request);
void _handleSetAP(AsyncWebServerRequest *request);
void _handleInfo(AsyncWebServerRequest *request);
void _handleReset(AsyncWebServerRequest *request);
void _handleNotFound(AsyncWebServerRequest *request); // CaptivePortal redirector
void _handleRoot(AsyncWebServerRequest *request); // jen jednoducha stranka kvuli CaptivePortalu umoznuje prejit na spravnou stranku (ale nedela to...)
void _handleScan(AsyncWebServerRequest *request);
bool _testWifi(wificonfig_cb cb);
WiFiConfigUsrParameter *_searchUsrParameter(const char *name);
IPAddress _getIP(const String &from);
String rootProcessor(const String &var);
String apProcessor(const String &var);
String infoProcessor(const String & var);
WiFiConfigUsrParameter *_params; // ukazatel na posledni zadany uzivatelsky parametr
int _timeout; // timeout pri cekani na konfiguraci
uint32_t _time; // hodnota, po ktere bude ESP restartovano (pokud je _timeout != 0)
uint8_t _status; // stav pripojeni - je pouzity pro signalizaci duvodu, proc se nepripoji k AP
};
#endif