esp-vfd-clock/firmware/main/wifi_provisioner.hpp
2024-01-18 15:22:40 +02:00

100 lines
2.4 KiB
C++

//
// Created by erki on 07/01/24.
//
#pragma once
#include "nvs_handle.hpp"
#include <esp_http_server.h>
#include <etl/vector.h>
#include <etl/string.h>
#include <etl/delegate.h>
#include <expected>
#include <variant>
#include <memory>
#include <cJSON.h>
struct CJsonStringDeleter
{
void operator()(char* json_str) const
{
if (json_str)
cJSON_free(json_str);
}
};
using CJsonStrPtr = std::unique_ptr<char, CJsonStringDeleter>;
struct CJsonDeleter
{
void operator()(cJSON* element) const
{
if (element)
cJSON_Delete(element);
}
};
using CJsonPtr = std::unique_ptr<cJSON, CJsonDeleter>;
class WifiProvisioner
{
public:
struct Parameter
{
etl::string<100> name;
etl::string<15> nvs_name;
enum class Type
{
INT,
FLOAT,
STRING
};
Type type;
using Value = std::variant<std::int32_t, float, etl::string<100>>;
Value data;
Parameter() = default;
Parameter(const char* name, const char* nvs_name, const Parameter::Type type)
: name(name)
, nvs_name(nvs_name)
, type(type)
{ }
std::expected<Value, esp_err_t> getValue(nvs::NVSHandle* file_handle) const;
std::expected<Value, const char*> tryValidateAndAssign(cJSON* object);
};
explicit WifiProvisioner(const char* settings_namespace, etl::delegate<void (const etl::vector<Parameter, 10>&)> success_cb);
~WifiProvisioner();
WifiProvisioner() = delete;
WifiProvisioner(const WifiProvisioner&) = delete;
WifiProvisioner(WifiProvisioner&&) = delete;
WifiProvisioner& operator=(const WifiProvisioner&) = delete;
WifiProvisioner& operator=(WifiProvisioner&&) = delete;
bool parametersAreConfigured();
std::expected<void, esp_err_t> startProvisioning();
std::expected<void, std::error_code> addParameter(const char* name, const char* nvs_name, const Parameter::Type type);
CJsonPtr getParameterObjects() const;
std::expected<void, const char*> tryConfigureParameters(CJsonPtr json_root);
private:
std::unique_ptr<nvs::NVSHandle> file_handle_;
bool settings_initialized_ = false;
httpd_handle_t http_server_ = nullptr;
etl::vector<Parameter, 10> params_;
etl::delegate<void (const etl::vector<Parameter, 10>& params)> success_cb_;
esp_err_t initializeNvsNamespace_();
std::expected<void, esp_err_t> initializeWifiAp_();
std::expected<httpd_handle_t, esp_err_t> initializeCaptivePortal_();
std::expected<void, esp_err_t> writeAndCommitParameters_();
};