Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
co2ampel
ampel-firmware
Commits
80a71660
Commit
80a71660
authored
May 14, 2021
by
Eric Duminil
Browse files
Trying to add autoconnect libraries
parent
a5807d86
Changes
38
Expand all
Hide whitespace changes
Inline
Side-by-side
ampel-firmware/src/lib/AutoConnect/AutoConnect.cpp
0 → 100644
View file @
80a71660
This diff is collapsed.
Click to expand it.
ampel-firmware/src/lib/AutoConnect/AutoConnect.h
0 → 100644
View file @
80a71660
/**
* Declaration of AutoConnect class and accompanying AutoConnectConfig class.
* @file AutoConnect.h
* @author hieromon@gmail.com
* @version 1.2.0
* @date 2020-11-15
* @copyright MIT license.
*/
#ifndef _AUTOCONNECT_H_
#define _AUTOCONNECT_H_
#include <vector>
#include <memory>
#include <functional>
#include <DNSServer.h>
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
extern
"C"
{
#include <user_interface.h>
}
using
WebServerClass
=
ESP8266WebServer
;
#elif defined(ARDUINO_ARCH_ESP32)
#include <WiFi.h>
#include <WebServer.h>
using
WebServerClass
=
WebServer
;
#endif
#include <EEPROM.h>
#include <PageBuilder.h>
#include "AutoConnectDefs.h"
#include "AutoConnectPage.h"
#include "AutoConnectCredential.h"
#include "AutoConnectTicker.h"
#include "AutoConnectAux.h"
#include "AutoConnectTypes.h"
// The realization of AutoConnectOTA is effective only by the explicit
#include "AutoConnectOTA.h"
class
AutoConnectOTA
;
// Reference to avoid circular
// The realization of AutoConnectUpdate is effective only by the explicit
// definition of AUTOCONNECT_USE_UPDATE
#include "AutoConnectUpdate.h"
class
AutoConnectUpdate
;
// Reference to avoid circular
class
AutoConnectConfig
{
public:
/**
* AutoConnectConfig default constructor.
* SSID for the captive portal access point assumes AUTOCONNECT_APID which
* assigned from macro. Password is same as above too.
*/
AutoConnectConfig
()
:
apip
(
AUTOCONNECT_AP_IP
),
gateway
(
AUTOCONNECT_AP_GW
),
netmask
(
AUTOCONNECT_AP_NM
),
apid
(
String
(
F
(
AUTOCONNECT_APID
))),
psk
(
String
(
F
(
AUTOCONNECT_PSK
))),
channel
(
AUTOCONNECT_AP_CH
),
hidden
(
0
),
minRSSI
(
AUTOCONNECT_MIN_RSSI
),
autoSave
(
AC_SAVECREDENTIAL_AUTO
),
bootUri
(
AC_ONBOOTURI_ROOT
),
principle
(
AC_PRINCIPLE_RECENT
),
boundaryOffset
(
AC_IDENTIFIER_OFFSET
),
uptime
(
AUTOCONNECT_STARTUPTIME
),
autoRise
(
true
),
autoReset
(
true
),
autoReconnect
(
false
),
immediateStart
(
false
),
retainPortal
(
false
),
preserveAPMode
(
false
),
beginTimeout
(
AUTOCONNECT_TIMEOUT
),
portalTimeout
(
AUTOCONNECT_CAPTIVEPORTAL_TIMEOUT
),
menuItems
(
AC_MENUITEM_CONFIGNEW
|
AC_MENUITEM_OPENSSIDS
|
AC_MENUITEM_DISCONNECT
|
AC_MENUITEM_RESET
|
AC_MENUITEM_UPDATE
|
AC_MENUITEM_HOME
),
reconnectInterval
(
0
),
ticker
(
false
),
tickerPort
(
AUTOCONNECT_TICKER_PORT
),
tickerOn
(
LOW
),
ota
(
AC_OTA_EXTRA
),
auth
(
AC_AUTH_NONE
),
authScope
(
AC_AUTHSCOPE_AUX
),
username
(
String
(
""
)),
password
(
String
(
""
)),
hostName
(
String
(
""
)),
homeUri
(
AUTOCONNECT_HOMEURI
),
title
(
AUTOCONNECT_MENU_TITLE
),
staip
(
0U
),
staGateway
(
0U
),
staNetmask
(
0U
),
dns1
(
0U
),
dns2
(
0U
)
{}
/**
* Configure by SSID for the captive portal access point and password.
*/
AutoConnectConfig
(
const
char
*
ap
,
const
char
*
password
,
const
unsigned
long
portalTimeout
=
0
,
const
uint8_t
channel
=
AUTOCONNECT_AP_CH
)
:
apip
(
AUTOCONNECT_AP_IP
),
gateway
(
AUTOCONNECT_AP_GW
),
netmask
(
AUTOCONNECT_AP_NM
),
apid
(
String
(
ap
)),
psk
(
String
(
password
)),
channel
(
channel
),
hidden
(
0
),
minRSSI
(
AUTOCONNECT_MIN_RSSI
),
autoSave
(
AC_SAVECREDENTIAL_AUTO
),
bootUri
(
AC_ONBOOTURI_ROOT
),
principle
(
AC_PRINCIPLE_RECENT
),
boundaryOffset
(
AC_IDENTIFIER_OFFSET
),
uptime
(
AUTOCONNECT_STARTUPTIME
),
autoRise
(
true
),
autoReset
(
true
),
autoReconnect
(
false
),
immediateStart
(
false
),
retainPortal
(
false
),
preserveAPMode
(
false
),
beginTimeout
(
AUTOCONNECT_TIMEOUT
),
portalTimeout
(
portalTimeout
),
menuItems
(
AC_MENUITEM_CONFIGNEW
|
AC_MENUITEM_OPENSSIDS
|
AC_MENUITEM_DISCONNECT
|
AC_MENUITEM_RESET
|
AC_MENUITEM_UPDATE
|
AC_MENUITEM_HOME
),
reconnectInterval
(
0
),
ticker
(
false
),
tickerPort
(
AUTOCONNECT_TICKER_PORT
),
tickerOn
(
LOW
),
ota
(
AC_OTA_EXTRA
),
auth
(
AC_AUTH_NONE
),
authScope
(
AC_AUTHSCOPE_AUX
),
username
(
String
(
""
)),
password
(
String
(
""
)),
hostName
(
String
(
""
)),
homeUri
(
AUTOCONNECT_HOMEURI
),
title
(
AUTOCONNECT_MENU_TITLE
),
staip
(
0U
),
staGateway
(
0U
),
staNetmask
(
0U
),
dns1
(
0U
),
dns2
(
0U
)
{}
~
AutoConnectConfig
()
{}
AutoConnectConfig
&
operator
=
(
const
AutoConnectConfig
&
o
)
{
apip
=
o
.
apip
;
gateway
=
o
.
gateway
;
netmask
=
o
.
netmask
;
apid
=
o
.
apid
;
psk
=
o
.
psk
;
channel
=
o
.
channel
;
hidden
=
o
.
hidden
;
minRSSI
=
o
.
minRSSI
;
autoSave
=
o
.
autoSave
;
bootUri
=
o
.
bootUri
;
principle
=
o
.
principle
;
boundaryOffset
=
o
.
boundaryOffset
;
uptime
=
o
.
uptime
;
autoRise
=
o
.
autoRise
;
autoReset
=
o
.
autoReset
;
autoReconnect
=
o
.
autoReconnect
;
immediateStart
=
o
.
immediateStart
;
retainPortal
=
o
.
retainPortal
;
preserveAPMode
=
o
.
preserveAPMode
;
beginTimeout
=
o
.
beginTimeout
;
portalTimeout
=
o
.
portalTimeout
;
menuItems
=
o
.
menuItems
;
reconnectInterval
=
o
.
reconnectInterval
;
ticker
=
o
.
ticker
;
tickerPort
=
o
.
tickerPort
;
tickerOn
=
o
.
tickerOn
;
ota
=
o
.
ota
;
auth
=
o
.
auth
;
authScope
=
o
.
authScope
;
username
=
o
.
username
;
password
=
o
.
password
;
hostName
=
o
.
hostName
;
homeUri
=
o
.
homeUri
;
title
=
o
.
title
;
staip
=
o
.
staip
;
staGateway
=
o
.
staGateway
;
staNetmask
=
o
.
staNetmask
;
dns1
=
o
.
dns1
;
dns2
=
o
.
dns2
;
return
*
this
;
}
IPAddress
apip
;
/**< SoftAP IP address */
IPAddress
gateway
;
/**< SoftAP gateway address */
IPAddress
netmask
;
/**< SoftAP subnet mask */
String
apid
;
/**< SoftAP SSID */
String
psk
;
/**< SoftAP password */
uint8_t
channel
;
/**< SoftAP used wifi channel */
uint8_t
hidden
;
/**< SoftAP SSID hidden */
int16_t
minRSSI
;
/**< Lowest WiFi signal strength (RSSI) that can be connected. */
AC_SAVECREDENTIAL_t
autoSave
;
/**< Auto save credential */
AC_ONBOOTURI_t
bootUri
;
/**< An uri invoking after reset */
AC_PRINCIPLE_t
principle
;
/**< WiFi connection principle */
uint16_t
boundaryOffset
;
/**< The save storage offset of EEPROM */
int
uptime
;
/**< Length of start up time */
bool
autoRise
;
/**< Automatic starting the captive portal */
bool
autoReset
;
/**< Reset ESP8266 module automatically when WLAN disconnected. */
bool
autoReconnect
;
/**< Automatic reconnect with past SSID */
bool
immediateStart
;
/**< Skips WiFi.begin(), start portal immediately */
bool
retainPortal
;
/**< Even if the captive portal times out, it maintains the portal state. */
bool
preserveAPMode
;
/**< Keep existing AP WiFi mode if captive portal won't be started. */
unsigned
long
beginTimeout
;
/**< Timeout value for WiFi.begin */
unsigned
long
portalTimeout
;
/**< Timeout value for stay in the captive portal */
uint16_t
menuItems
;
/**< A compound value of the menu items to be attached */
uint8_t
reconnectInterval
;
/**< Auto-reconnect attempt interval uint */
bool
ticker
;
/**< Drives LED flicker according to WiFi connection status. */
uint8_t
tickerPort
;
/**< GPIO for flicker */
uint8_t
tickerOn
;
/**< A signal for flicker turn on */
AC_OTA_t
ota
;
/**< Attach built-in OTA */
AC_AUTH_t
auth
;
/**< Enable authentication */
uint16_t
authScope
;
/**< Authetication scope */
String
username
;
/**< User name for authentication */
String
password
;
/**< Authentication password */
String
hostName
;
/**< host name */
String
homeUri
;
/**< A URI of user site */
String
title
;
/**< Menu title */
IPAddress
staip
;
/**< Station static IP address */
IPAddress
staGateway
;
/**< Station gateway address */
IPAddress
staNetmask
;
/**< Station subnet mask */
IPAddress
dns1
;
/**< Primary DNS server */
IPAddress
dns2
;
/**< Secondary DNS server */
};
typedef
std
::
vector
<
std
::
reference_wrapper
<
AutoConnectAux
>>
AutoConnectAuxVT
;
class
AutoConnect
{
public:
AutoConnect
();
AutoConnect
(
WebServerClass
&
webServer
);
virtual
~
AutoConnect
();
bool
begin
(
void
);
bool
begin
(
const
char
*
ssid
,
const
char
*
passphrase
=
nullptr
,
unsigned
long
timeout
=
0
);
bool
config
(
AutoConnectConfig
&
Config
);
bool
config
(
const
char
*
ap
,
const
char
*
password
=
nullptr
);
void
end
(
void
);
uint16_t
getEEPROMUsedSize
(
void
);
void
handleClient
(
void
);
void
handleRequest
(
void
);
void
home
(
const
String
&
uri
);
WebServerClass
&
host
(
void
);
String
where
(
void
)
const
{
return
_auxUri
;
}
AutoConnectAux
*
aux
(
const
String
&
uri
)
const
;
AutoConnectAux
*
append
(
const
String
&
uri
,
const
String
&
title
);
AutoConnectAux
*
append
(
const
String
&
uri
,
const
String
&
title
,
WebServerClass
::
THandlerFunction
handler
);
bool
detach
(
const
String
&
uri
);
inline
void
disableMenu
(
const
uint16_t
items
)
{
_apConfig
.
menuItems
&=
(
0xffff
^
items
);
}
inline
void
enableMenu
(
const
uint16_t
items
)
{
_apConfig
.
menuItems
|=
items
;
}
void
join
(
AutoConnectAux
&
aux
);
void
join
(
AutoConnectAuxVT
auxVector
);
bool
on
(
const
String
&
uri
,
const
AuxHandlerFunctionT
handler
,
AutoConnectExitOrder_t
order
=
AC_EXIT_AHEAD
);
/** For AutoConnectAux described in JSON */
#ifdef AUTOCONNECT_USE_JSON
bool
load
(
PGM_P
aux
);
bool
load
(
const
__FlashStringHelper
*
aux
);
bool
load
(
const
String
&
aux
);
bool
load
(
Stream
&
aux
);
#endif // !AUTOCONNECT_USE_JSON
typedef
std
::
function
<
bool
(
IPAddress
&
)
>
DetectExit_ft
;
typedef
std
::
function
<
void
(
IPAddress
&
)
>
ConnectExit_ft
;
typedef
std
::
function
<
bool
(
void
)
>
WhileCaptivePortalExit_ft
;
void
onDetect
(
DetectExit_ft
fn
);
void
onConnect
(
ConnectExit_ft
fn
);
void
onNotFound
(
WebServerClass
::
THandlerFunction
fn
);
void
whileCaptivePortal
(
WhileCaptivePortalExit_ft
fn
);
protected:
typedef
enum
{
AC_RECONNECT_SET
,
AC_RECONNECT_RESET
}
AC_STARECONNECT_t
;
typedef
enum
{
AC_SEEKMODE_ANY
,
AC_SEEKMODE_NEWONE
,
AC_SEEKMODE_CURRENT
}
AC_SEEKMODE_t
;
void
_authentication
(
bool
allow
);
void
_authentication
(
bool
allow
,
const
HTTPAuthMethod
method
);
bool
_configAP
(
void
);
bool
_configSTA
(
const
IPAddress
&
ip
,
const
IPAddress
&
gateway
,
const
IPAddress
&
netmask
,
const
IPAddress
&
dns1
,
const
IPAddress
&
dns2
);
String
_getBootUri
(
void
);
bool
_getConfigSTA
(
station_config_t
*
config
);
bool
_loadAvailCredential
(
const
char
*
ssid
,
const
AC_PRINCIPLE_t
principle
=
AC_PRINCIPLE_RECENT
,
const
bool
excludeCurrent
=
false
);
bool
_loadCurrentCredential
(
char
*
ssid
,
char
*
password
,
const
AC_PRINCIPLE_t
principle
,
const
bool
excludeCurrent
);
bool
_seekCredential
(
const
AC_PRINCIPLE_t
principle
,
const
AC_SEEKMODE_t
mode
);
void
_startWebServer
(
void
);
void
_startDNSServer
(
void
);
void
_stopDNSServer
(
void
);
void
_stopPortal
(
void
);
bool
_classifyHandle
(
HTTPMethod
mothod
,
String
uri
);
void
_handleUpload
(
const
String
&
requestUri
,
const
HTTPUpload
&
upload
);
void
_handleNotFound
(
void
);
void
_purgePages
(
void
);
virtual
PageElement
*
_setupPage
(
String
&
uri
);
#ifdef AUTOCONNECT_USE_JSON
template
<
typename
T
>
bool
_parseJson
(
T
in
);
bool
_load
(
JsonVariant
&
aux
);
#endif // !AUTOCONNECT_USE_JSON
/** Request handlers implemented by Page Builder */
String
_induceConnect
(
PageArgument
&
args
);
String
_induceDisconnect
(
PageArgument
&
args
);
String
_induceReset
(
PageArgument
&
args
);
String
_invokeResult
(
PageArgument
&
args
);
/** For portal control */
bool
_captivePortal
(
void
);
bool
_hasTimeout
(
unsigned
long
timeout
);
bool
_isIP
(
String
ipStr
);
void
_softAP
(
void
);
wl_status_t
_waitForConnect
(
unsigned
long
timeout
);
void
_waitForEndTransmission
(
void
);
void
_disconnectWiFi
(
bool
wifiOff
);
void
_setReconnect
(
const
AC_STARECONNECT_t
order
);
/** Utilities */
String
_attachMenuItem
(
const
AC_MENUITEM_t
item
);
static
uint32_t
_getChipId
(
void
);
static
uint32_t
_getFlashChipRealSize
(
void
);
static
String
_toMACAddressString
(
const
uint8_t
mac
[]);
static
unsigned
int
_toWiFiQuality
(
int32_t
rssi
);
ConnectExit_ft
_onConnectExit
;
DetectExit_ft
_onDetectExit
;
WhileCaptivePortalExit_ft
_whileCaptivePortal
;
WebServerClass
::
THandlerFunction
_notFoundHandler
;
size_t
_freeHeapSize
;
/** Servers which works in concert. */
typedef
std
::
unique_ptr
<
WebServerClass
,
std
::
function
<
void
(
WebServerClass
*
)
>
>
WebserverUP
;
WebserverUP
_webServer
=
WebserverUP
(
nullptr
,
std
::
default_delete
<
WebServerClass
>
());
std
::
unique_ptr
<
DNSServer
>
_dnsServer
;
/**
* Dynamically hold one page of AutoConnect menu.
* Every time a GET/POST HTTP request occurs, an AutoConnect
* menu page corresponding to the URI is generated.
*/
std
::
unique_ptr
<
PageBuilder
>
_responsePage
;
std
::
unique_ptr
<
PageElement
>
_currentPageElement
;
/** Extended pages made up with AutoConnectAux */
AutoConnectAux
*
_aux
=
nullptr
;
/**< A top of registered AutoConnectAux */
String
_auxUri
;
/**< Last accessed AutoConnectAux */
String
_prevUri
;
/**< Previous generated page uri */
/** Available updater, only reset by AutoConnectUpdate::attach is valid */
std
::
unique_ptr
<
AutoConnectUpdate
>
_update
;
/** OTA updater */
std
::
unique_ptr
<
AutoConnectOTA
>
_ota
;
/** Saved configurations */
AutoConnectConfig
_apConfig
;
station_config_t
_credential
;
uint8_t
_hiddenSSIDCount
;
int16_t
_scanCount
;
uint8_t
_connectCh
;
unsigned
long
_portalAccessPeriod
;
unsigned
long
_attemptPeriod
;
/** The control indicators */
bool
_rfAdHocBegin
=
false
;
/**< Specified with AutoConnect::begin */
bool
_rfConnect
=
false
;
/**< URI /connect requested */
bool
_rfDisconnect
=
false
;
/**< URI /disc requested */
bool
_rfReset
=
false
;
/**< URI /reset requested */
wl_status_t
_rsConnect
;
/**< connection result */
#ifdef ARDUINO_ARCH_ESP32
WiFiEventId_t
_disconnectEventId
=
-
1
;
/**< STA disconnection event handler registered id */
#endif
/** Only available with ticker enabled */
std
::
unique_ptr
<
AutoConnectTicker
>
_ticker
;
/** HTTP header information of the currently requested page. */
IPAddress
_currentHostIP
;
/**< host IP address */
String
_uri
;
/**< Requested URI */
String
_redirectURI
;
/**< Redirect destination */
String
_menuTitle
;
/**< Title string of the page */
/** PageElements of AutoConnect site. */
static
const
char
_CSS_BASE
[]
PROGMEM
;
static
const
char
_CSS_LUXBAR
[]
PROGMEM
;
static
const
char
_CSS_UL
[]
PROGMEM
;
static
const
char
_CSS_ICON_LOCK
[]
PROGMEM
;
static
const
char
_CSS_INPUT_BUTTON
[]
PROGMEM
;
static
const
char
_CSS_INPUT_TEXT
[]
PROGMEM
;
static
const
char
_CSS_TABLE
[]
PROGMEM
;
static
const
char
_CSS_SPINNER
[]
PROGMEM
;
static
const
char
_ELM_HTML_HEAD
[]
PROGMEM
;
static
const
char
_ELM_MENU_PRE
[]
PROGMEM
;
static
const
char
_ELM_MENU_AUX
[]
PROGMEM
;
static
const
char
_ELM_MENU_POST
[]
PROGMEM
;
static
const
char
_PAGE_STAT
[]
PROGMEM
;
static
const
char
_PAGE_CONFIGNEW
[]
PROGMEM
;
static
const
char
_PAGE_CONNECTING
[]
PROGMEM
;
static
const
char
_PAGE_OPENCREDT
[]
PROGMEM
;
static
const
char
_PAGE_SUCCESS
[]
PROGMEM
;
static
const
char
_PAGE_RESETTING
[]
PROGMEM
;
static
const
char
_PAGE_DISCONN
[]
PROGMEM
;
static
const
char
_PAGE_FAIL
[]
PROGMEM
;
static
const
char
_PAGE_404
[]
PROGMEM
;
static
const
struct
PageTranserModeST
{
const
char
*
uri
;
const
TransferEncoding_t
transMode
;
const
size_t
rSize
;
}
_pageBuildMode
[];
/** Token handlers for PageBuilder */
String
_token_CSS_BASE
(
PageArgument
&
args
);
String
_token_CSS_ICON_LOCK
(
PageArgument
&
args
);
String
_token_CSS_INPUT_BUTTON
(
PageArgument
&
args
);
String
_token_CSS_INPUT_TEXT
(
PageArgument
&
args
);
String
_token_CSS_LUXBAR
(
PageArgument
&
args
);
String
_token_CSS_SPINNER
(
PageArgument
&
args
);
String
_token_CSS_TABLE
(
PageArgument
&
args
);
String
_token_CSS_UL
(
PageArgument
&
args
);
String
_token_MENU_AUX
(
PageArgument
&
args
);
String
_token_MENU_POST
(
PageArgument
&
args
);
String
_token_MENU_PRE
(
PageArgument
&
args
);
String
_token_AP_MAC
(
PageArgument
&
args
);
String
_token_BOOTURI
(
PageArgument
&
args
);
String
_token_CHANNEL
(
PageArgument
&
args
);
String
_token_CHIP_ID
(
PageArgument
&
args
);
String
_token_CONFIG_STAIP
(
PageArgument
&
args
);
String
_token_CPU_FREQ
(
PageArgument
&
args
);
String
_token_CURRENT_SSID
(
PageArgument
&
args
);
String
_token_DBM
(
PageArgument
&
args
);
String
_token_ESTAB_SSID
(
PageArgument
&
args
);
String
_token_FLASH_SIZE
(
PageArgument
&
args
);
String
_token_FREE_HEAP
(
PageArgument
&
args
);
String
_token_GATEWAY
(
PageArgument
&
args
);
String
_token_HEAD
(
PageArgument
&
args
);
String
_token_HIDDEN_COUNT
(
PageArgument
&
args
);
String
_token_LIST_SSID
(
PageArgument
&
args
);
String
_token_LOCAL_IP
(
PageArgument
&
args
);
String
_token_NETMASK
(
PageArgument
&
args
);
String
_token_OPEN_SSID
(
PageArgument
&
args
);
String
_token_SOFTAP_IP
(
PageArgument
&
args
);
String
_token_SSID_COUNT
(
PageArgument
&
args
);
String
_token_STA_MAC
(
PageArgument
&
args
);
String
_token_STATION_STATUS
(
PageArgument
&
args
);
String
_token_UPTIME
(
PageArgument
&
args
);
String
_token_WIFI_MODE
(
PageArgument
&
args
);
String
_token_WIFI_STATUS
(
PageArgument
&
args
);
private:
// The access point collation key is determined at compile time
// according to the AUTOCONNECT_APKEY_SSID definition, which is
inline
bool
_isValidAP
(
const
station_config_t
&
config
,
const
uint8_t
item
)
const
{
#if defined(AUTOCONNECT_APKEY_SSID)
return
!
strcmp
(
reinterpret_cast
<
const
char
*>
(
config
.
ssid
),
WiFi
.
SSID
(
item
).
c_str
());
#else
return
!
memcmp
(
config
.
bssid
,
WiFi
.
BSSID
(
item
),
sizeof
(
station_config_t
::
bssid
));
#endif
}
static
const
String
_emptyString
;
/**< An empty string allocation **/
#if defined(ARDUINO_ARCH_ESP8266)
friend
ESP8266WebServer
;
#elif defined(ARDUINO_ARCH_ESP32)
friend
class
WebServer
;
#endif
friend
class
AutoConnectAux
;
friend
class
AutoConnectUpdate
;
};
#endif // _AUTOCONNECT_H_
ampel-firmware/src/lib/AutoConnect/AutoConnectAux.cpp
0 → 100644
View file @
80a71660
This diff is collapsed.
Click to expand it.
ampel-firmware/src/lib/AutoConnect/AutoConnectAux.h
0 → 100644
View file @
80a71660
/**
* Declaration of AutoConnectAux basic class.
* @file AutoConnectAux.h
* @author hieromon@gmail.com
* @version 1.2.0
* @date 2029-04-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTAUX_H_
#define _AUTOCONNECTAUX_H_
#include "AutoConnectDefs.h"
#include <vector>
#include <memory>
#include <functional>
#include <type_traits>
#ifdef AUTOCONNECT_USE_JSON
#include <Stream.h>
#endif // !AUTOCONNECT_USE_JSON
#include <PageBuilder.h>
#include "AutoConnectElement.h"
#include "AutoConnectTypes.h"
class
AutoConnect
;
// Reference to avoid circular
class
AutoConnectAux
;
// Reference to avoid circular
// Manage placed AutoConnectElement with a vector
typedef
std
::
vector
<
std
::
reference_wrapper
<
AutoConnectElement
>>
AutoConnectElementVT
;
// A type of callback function when AutoConnectAux page requested.
typedef
std
::
function
<
String
(
AutoConnectAux
&
,
PageArgument
&
)
>
AuxHandlerFunctionT
;
// A type for the order in which callback functions are called.
typedef
enum
{
AC_EXIT_AHEAD
=
1
,
/**< Callback before building HTML */
AC_EXIT_LATER
=
2
,
/**< Callback after building HTML */
AC_EXIT_BOTH
=
3
/**< Callback twice before and after building HTML */
}
AutoConnectExitOrder_t
;
/**
* A class that handles an auxiliary page with AutoConnectElement
* that placed on it by binding it to the AutoConnect menu.
* @param uri An uri string of this page.
* @param title A title string of this page.
* @param addons A set of AutoConnectElement vector.
* @param menu A switch for item displaying in AutoConnect menu.
*/
class
AutoConnectAux
:
public
PageBuilder
{
public:
explicit
AutoConnectAux
(
const
String
&
uri
=
String
(
""
),
const
String
&
title
=
String
(
""
),
const
bool
menu
=
true
,
const
AutoConnectElementVT
addons
=
AutoConnectElementVT
())
:
chunk
(
PB_Chunk
),
_title
(
title
),
_menu
(
menu
),
_uriStr
(
String
(
uri
)),
_addonElm
(
addons
),
_handler
(
nullptr
),
_order
(
AC_EXIT_AHEAD
),
_uploadHandler
(
nullptr
)
{
_uri
=
_uriStr
.
c_str
();
}
~
AutoConnectAux
();
AutoConnectElement
&
operator
[](
const
String
&
name
)
{
return
*
getElement
(
name
);
}
void
add
(
AutoConnectElement
&
addon
);
/**< Add an element to the auxiliary page */
void
add
(
AutoConnectElementVT
addons
);
/**< Add the element set to the auxiliary page */
void
authentication
(
const
AC_AUTH_t
auth
)
{
_httpAuth
=
auth
;
}
/**< Set certain page authentication */
void
fetchElement
(
void
);
/**< Fetch AutoConnectElements values from http query parameters */
template
<
typename
T
>
T
&
getElement
(
const
String
&
name
);
AutoConnectElement
*
getElement
(
const
String
&
name
);
/**< Get registered AutoConnectElement as specified name */
AutoConnectElementVT
&
getElements
(
void
)
{
return
_addonElm
;
}
/**< Get vector of all elements */
void
menu
(
const
bool
post
)
{
_menu
=
post
;
}
/**< Set or reset the display as menu item for this aux */
bool
isMenu
(
void
)
{
return
_menu
;
}
/**< Return whether embedded in the menu or not */
bool
isValid
(
void
)
const
;
/**< Validate all AutoConnectInput value */
bool
release
(
const
String
&
name
);
/**< Release an AutoConnectElement */
bool
setElementValue
(
const
String
&
name
,
const
String
value
);
/**< Set value to specified element */
bool
setElementValue
(
const
String
&
name
,
std
::
vector
<
String
>
const
&
values
);
/**< Set values collection to specified element */
void
setTitle
(
const
String
&
title
)
{
_title
=
title
;
}
/**< Set a title of the auxiliary page */
void
on
(
const
AuxHandlerFunctionT
handler
,
const
AutoConnectExitOrder_t
order
=
AC_EXIT_AHEAD
)
{
_handler
=
handler
;
_order
=
order
;
}
/**< Set user handler */
void
onUpload
(
PageBuilder
::
UploadFuncT
uploadFunc
)
override
{
_uploadHandler
=
uploadFunc
;
}
template
<
typename
T
>
void
onUpload
(
T
&
uploadClass
)
{
static_assert
(
std
::
is_base_of
<
AutoConnectUploadHandler
,
T
>::
value
,
"onUpload type must be inherited AutoConnectUploadHandler"
);
_uploadHandler
=
std
::
bind
(
&
T
::
upload
,
&
uploadClass
,
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
);
}
#ifdef AUTOCONNECT_USE_JSON
bool
load
(
PGM_P
in
);
/**< Load whole elements to AutoConnectAux Page */
bool
load
(
const
__FlashStringHelper
*
in
);
/**< Load whole elements to AutoConnectAux Page */
bool
load
(
const
String
&
in
);
/**< Load whole elements to AutoConnectAux Page */
bool
load
(
Stream
&
in
);
/**< Load whole elements to AutoConnectAux Page */
bool
loadElement
(
PGM_P
in
,
const
String
&
name
=
String
(
""
));
/**< Load specified element */
bool
loadElement
(
PGM_P
in
,
std
::
vector
<
String
>
const
&
names
);
/**< Load any specified elements */
bool
loadElement
(
const
__FlashStringHelper
*
in
,
const
String
&
name
=
String
(
""
));
/**< Load specified element */
bool
loadElement
(
const
__FlashStringHelper
*
in
,
std
::
vector
<
String
>
const
&
names
);
/**< Load any specified elements */
bool
loadElement
(
const
String
&
in
,
const
String
&
name
=
String
(
""
));
/**< Load specified element */
bool
loadElement
(
const
String
&
in
,
std
::
vector
<
String
>
const
&
names
);
/**< Load any specified elements */
bool
loadElement
(
Stream
&
in
,
const
String
&
name
=
String
(
""
));
/**< Load specified element */
bool
loadElement
(
Stream
&
in
,
std
::
vector
<
String
>
const
&
names
);
/**< Load any specified elements */
size_t
saveElement
(
Stream
&
out
,
std
::
vector
<
String
>
const
&
names
=
{});
/**< Write elements of AutoConnectAux to the stream */
#endif // !AUTOCONNECT_USE_JSON
TransferEncoding_t
chunk
;
/**< Chunked transfer specified */
protected:
void
upload
(
const
String
&
requestUri
,
const
HTTPUpload
&
upload
);
/**< Uploader wrapper */
void
_concat
(
AutoConnectAux
&
aux
);
/**< Make up chain of AutoConnectAux */
void
_join
(
AutoConnect
&
ac
);
/**< Make a link to AutoConnect */
PageElement
*
_setupPage
(
const
String
&
uri
);
/**< AutoConnectAux page builder */