You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AutoConnect/src/AutoConnectCredential.h

176 lines
5.6 KiB

7 years ago
/**
* Declaration of AutoConnectCredential class.
* @file AutoConnectCredential.h
* @author hieromon@gmail.com
* @version 1.0.2
* @date 2019-09-16
7 years ago
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTCREDENTIAL_H_
#define _AUTOCONNECTCREDENTIAL_H_
7 years ago
// The AUTOCONNECT_USE_PREFERENCES macro indicates which classes apply
// to the credentials storage structure either EEPROM or Preferences.
// It is a valid indicator only for ESP32.
// Undefine this macro, it maintains backward compatibility by applying
// EEPROM to the credentials storage class in the arduino-esp32 core
// v1.0.2 and earlier.
#define AUTOCONNECT_USE_PREFERENCES
#include <Arduino.h>
#include <memory>
6 years ago
#if defined(ARDUINO_ARCH_ESP8266)
#define AC_CREDENTIAL_PREFERENCES 0
7 years ago
extern "C" {
#include <user_interface.h>
}
6 years ago
#elif defined(ARDUINO_ARCH_ESP32)
#ifdef AUTOCONNECT_USE_PREFERENCES
#define AC_CREDENTIAL_PREFERENCES 1
#else
#define AC_CREDENTIAL_PREFERENCES 0
#endif
6 years ago
#include <esp_wifi.h>
struct station_config {
uint8_t ssid[32];
uint8_t password[64];
uint8_t bssid_set;
uint8_t bssid[6];
wifi_fast_scan_threshold_t threshold;
6 years ago
};
#endif
#include "AutoConnectDefs.h"
7 years ago
/**
* Credential storage area offset specifier in EEPROM.
* By defining AC_IDENTIFIER_OFFSET macro in the user sketch, the credential
* storage area can be shifted in EEPROM.
7 years ago
*/
#ifndef AC_IDENTIFIER_OFFSET
#define AC_IDENTIFIER_OFFSET 0
#endif
/**
* Storage identifier for AutoConnect credentials. It is global constant
* and reserved.
*/
#ifndef AC_IDENTIFIER
#define AC_IDENTIFIER "AC_CREDT"
#endif
class AutoConnectCredentialBase {
public:
explicit AutoConnectCredentialBase() : _entries(0), _containSize(0) {}
virtual ~AutoConnectCredentialBase() {}
virtual uint8_t entries(void) { return _entries; }
virtual bool del(const char* ssid) = 0;
virtual int8_t load(const char* ssid, struct station_config* config) = 0;
virtual bool load(int8_t entry, struct station_config* config) = 0;
virtual bool save(const struct station_config* config) = 0;
protected:
virtual void _allocateEntry(void) = 0; /**< Initialize storage for credentials. */
uint8_t _entries; /**< Count of the available entry */
uint16_t _containSize; /**< Container size */
};
#if AC_CREDENTIAL_PREFERENCES == 0
// #pragma message "AutoConnectCredential applies the EEPROM"
#define NO_GLOBAL_EEPROM
#include <EEPROM.h>
/** AutoConnectCredential class using EEPROM for ESP8266 */
class AutoConnectCredential : public AutoConnectCredentialBase {
7 years ago
public:
AutoConnectCredential();
6 years ago
explicit AutoConnectCredential(uint16_t offset);
7 years ago
~AutoConnectCredential();
bool del(const char* ssid) override;
int8_t load(const char* ssid, struct station_config* config) override;
bool load(int8_t entry, struct station_config* config) override;
bool save(const struct station_config* config) override;
protected:
void _allocateEntry(void) override; /**< Initialize storage for credentials. */
7 years ago
private:
void _retrieveEntry(char* ssid, char* password, uint8_t* bssid); /**< Read an available entry. */
7 years ago
int _dp; /**< The current address in EEPROM */
int _ep; /**< The current entry address in EEPROM */
uint16_t _offset; /**< The offset for the saved area of credentials in EEPROM. */
std::unique_ptr<EEPROMClass> _eeprom; /**< shared EEPROM class */
};
#else
// #pragma message "AutoConnectCredential applies the Preferences"
#include <type_traits>
#include <map>
#include <Preferences.h>
#include <nvs.h>
#define AC_CREDENTIAL_NVSNAME AC_IDENTIFIER
#define AC_CREDENTIAL_NVSKEY AC_CREDENTIAL_NVSNAME
namespace AutoConnectUtil {
AC_HAS_FUNC(getBytesLength);
template<typename T>
typename std::enable_if<AutoConnectUtil::has_func_getBytesLength<T>::value, size_t>::type getPrefBytesLength(T* pref, const char* key) {
return pref->getBytesLength(key);
}
template<typename T>
typename std::enable_if<!AutoConnectUtil::has_func_getBytesLength<T>::value, size_t>::type getPrefBytesLength(T* pref, const char* key) {
AC_UNUSED(pref);
uint32_t handle;
size_t len;
esp_err_t err = nvs_open(AC_CREDENTIAL_NVSNAME, NVS_READONLY, &handle);
if (err)
len = 0;
else {
(void)nvs_get_blob(handle, key, NULL, &len);
nvs_close(handle);
}
return len;
}
}
/** AutoConnectCredential class using Preferences for ESP32 */
class AutoConnectCredential : public AutoConnectCredentialBase {
public:
AutoConnectCredential();
explicit AutoConnectCredential(uint16_t offset);
~AutoConnectCredential();
bool del(const char* ssid) override;
int8_t load(const char* ssid, struct station_config* config) override;
bool load(int8_t entry, struct station_config* config) override;
bool save(const struct station_config* config) override;
protected:
void _allocateEntry(void) override; /**< Initialize storage for credentials. */
private:
typedef struct {
String password;
uint8_t bssid[6];
} AC_CREDTBODY_t; /**< Credential entry */
typedef std::map<String, AC_CREDTBODY_t> AC_CREDT_t;
typedef station_config station_config_t;
bool _add(const station_config_t* config); /**< Add an entry */
size_t _commit(void); /**< Write back to the nvs */
bool _del(const char* ssid, const bool commit); /**< Deletes an entry */
uint8_t _import(void); /**< Import from the nvs */
void _obtain(AC_CREDT_t::iterator const& it, station_config_t* config); /**< Obtain an entry from iterator */
AC_CREDT_t _credit; /**< Dictionary to maintain the credentials */
std::unique_ptr<Preferences> _pref; /**< Preferences class instance to access the nvs */
7 years ago
};
#endif
#endif // _AUTOCONNECTCREDENTIAL_H_