mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-19 03:13:14 +00:00
Refactor WifiApSettings
This commit is contained in:
parent
5013c1da25
commit
57164ad6c8
@ -1,17 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "./WifiGlobals.h"
|
||||
#include "./WifiSettings.h"
|
||||
|
||||
#include <Tactility/PubSub.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "WifiApSettings.h"
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "esp_wifi.h"
|
||||
#include "WifiSettings.h"
|
||||
#else
|
||||
#include <cstdint>
|
||||
// From esp_wifi_types.h in ESP-IDF 5.2
|
||||
@ -124,7 +121,7 @@ std::string getIp();
|
||||
* @param[in] ap
|
||||
* @param[in] remember whether to save the ap data to the settings upon successful connection
|
||||
*/
|
||||
void connect(const settings::WifiApSettings* ap, bool remember);
|
||||
void connect(const settings::WifiApSettings& ap, bool remember);
|
||||
|
||||
/** @brief Disconnect from the access point. Doesn't have any effect when not connected. */
|
||||
void disconnect();
|
||||
|
||||
37
Tactility/Include/Tactility/service/wifi/WifiApSettings.h
Normal file
37
Tactility/Include/Tactility/service/wifi/WifiApSettings.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tt::service::wifi::settings {
|
||||
|
||||
/**
|
||||
* This struct is stored as-is into NVS flash.
|
||||
*
|
||||
* The SSID and secret are increased by 1 byte to facilitate string null termination.
|
||||
* This makes it easier to use the char array as a string in various places.
|
||||
*/
|
||||
struct WifiApSettings {
|
||||
std::string ssid;
|
||||
std::string password;
|
||||
bool autoConnect;
|
||||
int32_t channel;
|
||||
|
||||
WifiApSettings(
|
||||
std::string ssid,
|
||||
std::string password,
|
||||
bool autoConnect = true,
|
||||
int32_t channel = 0
|
||||
) : ssid(ssid), password(password), autoConnect(autoConnect), channel(channel) {}
|
||||
|
||||
WifiApSettings() : ssid(""), password(""), autoConnect(true), channel(0) {}
|
||||
};
|
||||
|
||||
bool contains(const std::string& ssid);
|
||||
|
||||
bool load(const std::string& ssid, WifiApSettings& settings);
|
||||
|
||||
bool save(const WifiApSettings& settings);
|
||||
|
||||
bool remove(const std::string& ssid);
|
||||
|
||||
} // namespace
|
||||
@ -1,31 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "WifiGlobals.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace tt::service::wifi::settings {
|
||||
|
||||
/**
|
||||
* This struct is stored as-is into NVS flash.
|
||||
*
|
||||
* The SSID and secret are increased by 1 byte to facilitate string null termination.
|
||||
* This makes it easier to use the char array as a string in various places.
|
||||
*/
|
||||
struct WifiApSettings {
|
||||
char ssid[TT_WIFI_SSID_LIMIT + 1] = { 0 };
|
||||
char password[TT_WIFI_CREDENTIALS_PASSWORD_LIMIT + 1] = { 0 };
|
||||
int32_t channel = 0;
|
||||
bool auto_connect = true;
|
||||
};
|
||||
|
||||
bool contains(const char* ssid);
|
||||
|
||||
bool load(const char* ssid, WifiApSettings* settings);
|
||||
|
||||
bool save(const WifiApSettings* settings);
|
||||
|
||||
bool remove(const char* ssid);
|
||||
|
||||
void setEnableOnBoot(bool enable);
|
||||
|
||||
bool shouldEnableOnBoot();
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
#include <Tactility/service/wifi/WifiApSettings.h>
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
typedef void (*OnConnectSsid)(const service::wifi::settings::WifiApSettings* settings, bool store, void* context);
|
||||
typedef void (*OnConnectSsid)(const service::wifi::settings::WifiApSettings& settings, bool store, void* context);
|
||||
|
||||
typedef struct {
|
||||
OnConnectSsid onConnectSsid;
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
#include <Tactility/service/wifi/WifiSettings.h>
|
||||
#include <Tactility/service/wifi/WifiApSettings.h>
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
class State {
|
||||
Mutex lock;
|
||||
service::wifi::settings::WifiApSettings apSettings = {
|
||||
.ssid = { 0 },
|
||||
.password = { 0 },
|
||||
.auto_connect = false
|
||||
};
|
||||
service::wifi::settings::WifiApSettings apSettings;
|
||||
bool connectionError = false;
|
||||
bool connecting = false;
|
||||
public:
|
||||
@ -20,7 +15,7 @@ public:
|
||||
void setConnectionError(bool error);
|
||||
bool hasConnectionError() const;
|
||||
|
||||
void setApSettings(const service::wifi::settings::WifiApSettings* newSettings);
|
||||
void setApSettings(const service::wifi::settings::WifiApSettings& newSettings);
|
||||
|
||||
void setConnecting(bool isConnecting);
|
||||
bool isConnecting() const;
|
||||
|
||||
@ -13,8 +13,6 @@ class WifiConnect;
|
||||
|
||||
class View {
|
||||
|
||||
private:
|
||||
|
||||
Bindings* bindings;
|
||||
State* state;
|
||||
|
||||
|
||||
@ -12,8 +12,6 @@ namespace tt::app::wificonnect {
|
||||
|
||||
class WifiConnect : public App {
|
||||
|
||||
private:
|
||||
|
||||
Mutex mutex;
|
||||
State state;
|
||||
Bindings bindings = {
|
||||
|
||||
@ -44,10 +44,10 @@ static void onToggleAutoConnect(lv_event_t* event) {
|
||||
bool is_on = lv_obj_has_state(enable_switch, LV_STATE_CHECKED);
|
||||
std::string ssid = parameters->getString("ssid");
|
||||
|
||||
service::wifi::settings::WifiApSettings settings {};
|
||||
if (service::wifi::settings::load(ssid.c_str(), &settings)) {
|
||||
settings.auto_connect = is_on;
|
||||
if (!service::wifi::settings::save(&settings)) {
|
||||
service::wifi::settings::WifiApSettings settings;
|
||||
if (service::wifi::settings::load(ssid.c_str(), settings)) {
|
||||
settings.autoConnect = is_on;
|
||||
if (!service::wifi::settings::save(settings)) {
|
||||
TT_LOG_E(TAG, "Failed to save settings");
|
||||
}
|
||||
} else {
|
||||
@ -98,9 +98,9 @@ class WifiApSettings : public App {
|
||||
lv_obj_align(forget_button_label, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_label_set_text(forget_button_label, "Forget");
|
||||
|
||||
service::wifi::settings::WifiApSettings settings {};
|
||||
if (service::wifi::settings::load(ssid.c_str(), &settings)) {
|
||||
if (settings.auto_connect) {
|
||||
service::wifi::settings::WifiApSettings settings;
|
||||
if (service::wifi::settings::load(ssid.c_str(), settings)) {
|
||||
if (settings.autoConnect) {
|
||||
lv_obj_add_state(auto_connect_switch, LV_STATE_CHECKED);
|
||||
} else {
|
||||
lv_obj_remove_state(auto_connect_switch, LV_STATE_CHECKED);
|
||||
|
||||
@ -17,9 +17,9 @@ bool State::hasConnectionError() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
void State::setApSettings(const service::wifi::settings::WifiApSettings* newSettings) {
|
||||
void State::setApSettings(const service::wifi::settings::WifiApSettings& newSettings) {
|
||||
lock.lock();
|
||||
memcpy(&this->apSettings, newSettings, sizeof(service::wifi::settings::WifiApSettings));
|
||||
this->apSettings = newSettings;
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@ -5,10 +5,11 @@
|
||||
#include "Tactility/lvgl/Spinner.h"
|
||||
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/service/wifi/WifiSettings.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <cstring>
|
||||
#include <Tactility/service/wifi/WifiApSettings.h>
|
||||
#include <Tactility/service/wifi/WifiGlobals.h>
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
@ -50,14 +51,14 @@ static void onConnect(TT_UNUSED lv_event_t* event) {
|
||||
view.setLoading(true);
|
||||
|
||||
service::wifi::settings::WifiApSettings settings;
|
||||
strcpy((char*)settings.password, password);
|
||||
strcpy((char*)settings.ssid, ssid);
|
||||
settings.password = password;
|
||||
settings.ssid = ssid;
|
||||
settings.channel = 0;
|
||||
settings.auto_connect = TT_WIFI_AUTO_CONNECT; // No UI yet, so use global setting:w
|
||||
settings.autoConnect = TT_WIFI_AUTO_CONNECT; // No UI yet, so use global setting:w
|
||||
|
||||
auto* bindings = &wifi->getBindings();
|
||||
bindings->onConnectSsid(
|
||||
&settings,
|
||||
settings,
|
||||
store,
|
||||
bindings->onConnectSsidContext
|
||||
);
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
#define TAG "wifi_connect"
|
||||
#define WIFI_CONNECT_PARAM_SSID "ssid" // String
|
||||
#define WIFI_CONNECT_PARAM_PASSWORD "password" // String
|
||||
@ -37,7 +36,7 @@ static void eventCallback(const void* message, void* context) {
|
||||
wifi->requestViewUpdate();
|
||||
}
|
||||
|
||||
static void onConnect(const service::wifi::settings::WifiApSettings* ap_settings, bool remember, TT_UNUSED void* parameter) {
|
||||
static void onConnect(const service::wifi::settings::WifiApSettings& ap_settings, bool remember, TT_UNUSED void* parameter) {
|
||||
auto* wifi = static_cast<WifiConnect*>(parameter);
|
||||
wifi->getState().setApSettings(ap_settings);
|
||||
wifi->getState().setConnecting(true);
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <format>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <Tactility/service/wifi/WifiSettings.h>
|
||||
|
||||
namespace tt::app::wifimanage {
|
||||
|
||||
|
||||
@ -16,9 +16,9 @@ extern const AppManifest manifest;
|
||||
|
||||
static void onConnect(const char* ssid) {
|
||||
service::wifi::settings::WifiApSettings settings;
|
||||
if (service::wifi::settings::load(ssid, &settings)) {
|
||||
if (service::wifi::settings::load(ssid, settings)) {
|
||||
TT_LOG_I(TAG, "Connecting with known credentials");
|
||||
service::wifi::connect(&settings, false);
|
||||
service::wifi::connect(settings, false);
|
||||
} else {
|
||||
TT_LOG_I(TAG, "Starting connection dialog");
|
||||
wificonnect::start(ssid);
|
||||
|
||||
186
Tactility/Source/service/wifi/WifiApSettings.cpp
Normal file
186
Tactility/Source/service/wifi/WifiApSettings.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
#include "Tactility/service/wifi/WifiApSettings.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <ranges>
|
||||
#include <Tactility/crypt/Crypt.h>
|
||||
#include <Tactility/file/File.h>
|
||||
#include <Tactility/file/PropertiesFile.h>
|
||||
|
||||
namespace tt::service::wifi::settings {
|
||||
|
||||
constexpr auto* TAG = "WifiApSettings";
|
||||
|
||||
constexpr auto* AP_SETTINGS_FORMAT = "/data/service/Wifi/{}.ap.properties";
|
||||
|
||||
constexpr auto* AP_PROPERTIES_KEY_SSID = "ssid";
|
||||
constexpr auto* AP_PROPERTIES_KEY_PASSWORD = "password";
|
||||
constexpr auto* AP_PROPERTIES_KEY_AUTO_CONNECT = "autoConnect";
|
||||
constexpr auto* AP_PROPERTIES_KEY_CHANNEL = "channel";
|
||||
|
||||
|
||||
std::string toHexString(const uint8_t *data, int length) {
|
||||
std::stringstream stream;
|
||||
stream << std::hex;
|
||||
for( int i(0) ; i < length; ++i )
|
||||
stream << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool readHex(const std::string& input, uint8_t* buffer, int length) {
|
||||
if (input.size() / 2 != length) {
|
||||
TT_LOG_E(TAG, "readHex() length mismatch");
|
||||
return false;
|
||||
}
|
||||
|
||||
char hex[3] = { 0 };
|
||||
for (int i = 0; i < length; i++) {
|
||||
hex[0] = input[i * 2];
|
||||
hex[1] = input[i * 2 + 1];
|
||||
char* endptr;
|
||||
buffer[i] = static_cast<uint8_t>(strtoul(hex, &endptr, 16));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string getApPropertiesFilePath(const std::string& ssid) {
|
||||
return std::format(AP_SETTINGS_FORMAT, ssid);
|
||||
}
|
||||
|
||||
static bool encrypt(const std::string& ssidInput, std::string& ssidOutput) {
|
||||
uint8_t iv[16];
|
||||
const auto length = ssidInput.size();
|
||||
constexpr size_t chunk_size = 16;
|
||||
const auto encrypted_length = ((length / chunk_size) + (length % chunk_size ? 1 : 0)) * chunk_size;
|
||||
|
||||
auto* buffer = static_cast<uint8_t*>(malloc(encrypted_length));
|
||||
|
||||
crypt::getIv(ssidInput.c_str(), ssidInput.size(), iv);
|
||||
if (crypt::encrypt(iv, reinterpret_cast<const uint8_t*>(ssidInput.c_str()), buffer, encrypted_length) != 0) {
|
||||
TT_LOG_E(TAG, "Failed to encrypt");
|
||||
free(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
ssidOutput = toHexString(buffer, encrypted_length);
|
||||
free(buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool decrypt(const std::string& ssidInput, std::string& ssidOutput) {
|
||||
assert(!ssidInput.empty());
|
||||
assert(ssidInput.size() % 2 == 0);
|
||||
auto* data = static_cast<uint8_t*>(malloc(ssidInput.size() / 2));
|
||||
if (!readHex(ssidInput, data, ssidInput.size() / 2)) {
|
||||
TT_LOG_E(TAG, "Failed to read hex");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t iv[16];
|
||||
crypt::getIv(ssidInput.c_str(), ssidInput.size(), iv);
|
||||
|
||||
auto result_length = ssidInput.size() / 2;
|
||||
// Allocate correct length plus space for string null terminator
|
||||
auto* result = static_cast<uint8_t*>(malloc(result_length + 1));
|
||||
result[result_length] = 0;
|
||||
|
||||
int decrypt_result = crypt::decrypt(
|
||||
iv,
|
||||
data,
|
||||
result,
|
||||
ssidInput.size() / 2
|
||||
);
|
||||
|
||||
free(data);
|
||||
|
||||
if (decrypt_result != 0) {
|
||||
TT_LOG_E(TAG, "Failed to decrypt credentials for \"%s\": %d", ssidInput.c_str(), decrypt_result);
|
||||
free(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
ssidOutput = reinterpret_cast<char*>(result);
|
||||
free(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool contains(const std::string& ssid) {
|
||||
const auto file_path = getApPropertiesFilePath(ssid);
|
||||
return file::exists(file_path);
|
||||
}
|
||||
|
||||
bool load(const std::string& ssid, WifiApSettings& apSettings) {
|
||||
const auto file_path = getApPropertiesFilePath(ssid);
|
||||
std::map<std::string, std::string> map;
|
||||
if (!file::loadPropertiesFile(file_path, map)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// SSID is required
|
||||
if (!map.contains(AP_PROPERTIES_KEY_SSID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
apSettings.ssid = map[AP_PROPERTIES_KEY_SSID];
|
||||
assert(ssid == apSettings.ssid);
|
||||
|
||||
if (map.contains(AP_PROPERTIES_KEY_PASSWORD)) {
|
||||
std::string password_decrypted;
|
||||
if (decrypt(map[AP_PROPERTIES_KEY_PASSWORD], password_decrypted)) {
|
||||
apSettings.password = password_decrypted;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
apSettings.password = "";
|
||||
}
|
||||
|
||||
if (map.contains(AP_PROPERTIES_KEY_AUTO_CONNECT)) {
|
||||
apSettings.autoConnect = (map[AP_PROPERTIES_KEY_AUTO_CONNECT] == "true");
|
||||
} else {
|
||||
apSettings.autoConnect = true;
|
||||
}
|
||||
|
||||
if (map.contains(AP_PROPERTIES_KEY_CHANNEL)) {
|
||||
apSettings.channel = std::stoi(map[AP_PROPERTIES_KEY_CHANNEL].c_str());
|
||||
} else {
|
||||
apSettings.channel = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool save(const WifiApSettings& apSettings) {
|
||||
if (apSettings.ssid.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto file_path = getApPropertiesFilePath(apSettings.ssid);
|
||||
|
||||
std::map<std::string, std::string> map;
|
||||
|
||||
std::string password_encrypted;
|
||||
if (!encrypt(apSettings.password, password_encrypted)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
map[AP_PROPERTIES_KEY_PASSWORD] = password_encrypted;
|
||||
map[AP_PROPERTIES_KEY_SSID] = apSettings.ssid;
|
||||
map[AP_PROPERTIES_KEY_AUTO_CONNECT] = apSettings.autoConnect ? "true" : "false";
|
||||
map[AP_PROPERTIES_KEY_CHANNEL] = std::to_string(apSettings.channel);
|
||||
|
||||
return file::savePropertiesFile(file_path, map);
|
||||
}
|
||||
|
||||
bool remove(const std::string& ssid) {
|
||||
const auto path = getApPropertiesFilePath(ssid);
|
||||
if (!file::exists(path)) {
|
||||
return false;
|
||||
}
|
||||
return ::remove(path.c_str()) == 0;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,19 +1,19 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <lwip/esp_netif_net_stack.h>
|
||||
#include "Tactility/service/wifi/Wifi.h"
|
||||
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/service/ServiceContext.h"
|
||||
#include "Tactility/service/wifi/WifiGlobals.h"
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
#include <Tactility/Timer.h>
|
||||
|
||||
#include <lwip/esp_netif_net_stack.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
namespace tt::service::wifi {
|
||||
@ -36,8 +36,6 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi);
|
||||
|
||||
class Wifi {
|
||||
|
||||
private:
|
||||
|
||||
std::atomic<RadioState> radio_state = RadioState::Off;
|
||||
bool scan_active = false;
|
||||
bool secure_connection = false;
|
||||
@ -66,11 +64,7 @@ public:
|
||||
esp_event_handler_instance_t event_handler_any_id = nullptr;
|
||||
esp_event_handler_instance_t event_handler_got_ip = nullptr;
|
||||
EventFlag connection_wait_flags;
|
||||
settings::WifiApSettings connection_target = {
|
||||
.ssid = { 0 },
|
||||
.password = { 0 },
|
||||
.auto_connect = false
|
||||
};
|
||||
settings::WifiApSettings connection_target;
|
||||
bool pause_auto_connect = false; // Pause when manually disconnecting until manually connecting again
|
||||
bool connection_target_remember = false; // Whether to store the connection_target on successful connection or not
|
||||
esp_netif_ip_info_t ip_info;
|
||||
@ -187,8 +181,8 @@ bool isScanning() {
|
||||
}
|
||||
}
|
||||
|
||||
void connect(const settings::WifiApSettings* ap, bool remember) {
|
||||
TT_LOG_I(TAG, "connect(%s, %d)", ap->ssid, remember);
|
||||
void connect(const settings::WifiApSettings& ap, bool remember) {
|
||||
TT_LOG_I(TAG, "connect(%s, %d)", ap.ssid.c_str(), remember);
|
||||
auto wifi = wifi_singleton;
|
||||
if (wifi == nullptr) {
|
||||
return;
|
||||
@ -201,14 +195,14 @@ void connect(const settings::WifiApSettings* ap, bool remember) {
|
||||
|
||||
// Manual connect (e.g. via app) should stop auto-connecting until the connection is established
|
||||
wifi->pause_auto_connect = true;
|
||||
memcpy(&wifi->connection_target, ap, sizeof(settings::WifiApSettings));
|
||||
wifi->connection_target = ap;
|
||||
wifi->connection_target_remember = remember;
|
||||
|
||||
if (wifi->getRadioState() == RadioState::Off) {
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchEnable(wifi); });
|
||||
getMainDispatcher().dispatch([wifi] { dispatchEnable(wifi); });
|
||||
}
|
||||
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchConnect(wifi); });
|
||||
getMainDispatcher().dispatch([wifi] { dispatchConnect(wifi); });
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
@ -223,11 +217,7 @@ void disconnect() {
|
||||
return;
|
||||
}
|
||||
|
||||
wifi->connection_target = (settings::WifiApSettings) {
|
||||
.ssid = { 0 },
|
||||
.password = { 0 },
|
||||
.auto_connect = false
|
||||
};
|
||||
wifi->connection_target = settings::WifiApSettings("", "");
|
||||
// Manual disconnect (e.g. via app) should stop auto-connecting until a new connection is established
|
||||
wifi->pause_auto_connect = true;
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchDisconnectButKeepActive(wifi); });
|
||||
@ -307,9 +297,9 @@ void setEnabled(bool enabled) {
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchEnable(wifi); });
|
||||
getMainDispatcher().dispatch([wifi] { dispatchEnable(wifi); });
|
||||
} else {
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchDisable(wifi); });
|
||||
getMainDispatcher().dispatch([wifi] { dispatchDisable(wifi); });
|
||||
}
|
||||
|
||||
wifi->pause_auto_connect = false;
|
||||
@ -431,8 +421,8 @@ static bool find_auto_connect_ap(std::shared_ptr<Wifi> wifi, settings::WifiApSet
|
||||
auto ssid = reinterpret_cast<const char*>(wifi->scan_list[i].ssid);
|
||||
if (settings::contains(ssid)) {
|
||||
static_assert(sizeof(wifi->scan_list[i].ssid) == (TT_WIFI_SSID_LIMIT + 1), "SSID size mismatch");
|
||||
if (settings::load(ssid, &settings)) {
|
||||
if (settings.auto_connect) {
|
||||
if (settings::load(ssid, settings)) {
|
||||
if (settings.autoConnect) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
@ -451,8 +441,8 @@ static void dispatchAutoConnect(std::shared_ptr<Wifi> wifi) {
|
||||
|
||||
settings::WifiApSettings settings;
|
||||
if (find_auto_connect_ap(wifi, settings)) {
|
||||
TT_LOG_I(TAG, "Auto-connecting to %s", settings.ssid);
|
||||
connect(&settings, false);
|
||||
TT_LOG_I(TAG, "Auto-connecting to %s", settings.ssid.c_str());
|
||||
connect(settings, false);
|
||||
// TODO: We currently have to manually reset it because connect() sets it.
|
||||
// connect() assumes it's only being called by the user and not internally, so it disables auto-connect
|
||||
wifi->pause_auto_connect = false;
|
||||
@ -726,7 +716,7 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
return;
|
||||
}
|
||||
|
||||
TT_LOG_I(TAG, "Connecting to %s", wifi->connection_target.ssid);
|
||||
TT_LOG_I(TAG, "Connecting to %s", wifi->connection_target.ssid.c_str());
|
||||
|
||||
// Stop radio first, if needed
|
||||
RadioState radio_state = wifi->getRadioState();
|
||||
@ -758,11 +748,10 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
config.sta.threshold.rssi = -127;
|
||||
config.sta.pmf_cfg.capable = true;
|
||||
|
||||
static_assert(sizeof(config.sta.ssid) == (sizeof(wifi_singleton->connection_target.ssid)-1), "SSID size mismatch");
|
||||
memcpy(config.sta.ssid, wifi_singleton->connection_target.ssid, sizeof(config.sta.ssid));
|
||||
memcpy(config.sta.ssid, wifi_singleton->connection_target.ssid.c_str(), wifi_singleton->connection_target.ssid.size());
|
||||
|
||||
if (wifi_singleton->connection_target.password[0] != 0x00) {
|
||||
memcpy(config.sta.password, wifi_singleton->connection_target.password, sizeof(config.sta.password));
|
||||
memcpy(config.sta.password, wifi_singleton->connection_target.password.c_str(), wifi_singleton->connection_target.password.size());
|
||||
config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
|
||||
}
|
||||
|
||||
@ -794,9 +783,9 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
wifi->setSecureConnection(config.sta.password[0] != 0x00U);
|
||||
wifi->setRadioState(RadioState::ConnectionActive);
|
||||
publish_event_simple(wifi, EventType::ConnectionSuccess);
|
||||
TT_LOG_I(TAG, "Connected to %s", wifi->connection_target.ssid);
|
||||
TT_LOG_I(TAG, "Connected to %s", wifi->connection_target.ssid.c_str());
|
||||
if (wifi->connection_target_remember) {
|
||||
if (!settings::save(&wifi->connection_target)) {
|
||||
if (!settings::save(wifi->connection_target)) {
|
||||
TT_LOG_E(TAG, "Failed to store credentials");
|
||||
} else {
|
||||
TT_LOG_I(TAG, "Stored credentials");
|
||||
@ -805,7 +794,7 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
} else if (bits & WIFI_FAIL_BIT) {
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::ConnectionFailed);
|
||||
TT_LOG_I(TAG, "Failed to connect to %s", wifi->connection_target.ssid);
|
||||
TT_LOG_I(TAG, "Failed to connect to %s", wifi->connection_target.ssid.c_str());
|
||||
} else {
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::ConnectionFailed);
|
||||
|
||||
@ -1,43 +1,54 @@
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
#include "Tactility/Preferences.h"
|
||||
|
||||
#define WIFI_PREFERENCES_NAMESPACE "wifi"
|
||||
#define WIFI_PREFERENCES_KEY_ENABLE_ON_BOOT "enable_on_boot"
|
||||
#include <Tactility/LogEsp.h>
|
||||
#include <Tactility/file/File.h>
|
||||
#include <Tactility/file/PropertiesFile.h>
|
||||
|
||||
namespace tt::service::wifi::settings {
|
||||
|
||||
// region General settings
|
||||
constexpr auto* TAG = "WifiSettings";
|
||||
constexpr auto* SETTINGS_FILE = "/data/service/Wifi/wifi.properties";
|
||||
constexpr auto* SETTINGS_KEY_ENABLE_ON_BOOT = "enableOnBoot";
|
||||
|
||||
struct WifiProperties {
|
||||
bool enableOnBoot;
|
||||
};
|
||||
|
||||
static bool load(WifiProperties& properties) {
|
||||
std::map<std::string, std::string> map;
|
||||
if (!file::loadPropertiesFile(SETTINGS_FILE, map)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!map.contains(SETTINGS_KEY_ENABLE_ON_BOOT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto enable_on_boot_string = map[SETTINGS_KEY_ENABLE_ON_BOOT];
|
||||
properties.enableOnBoot = (enable_on_boot_string == "true");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool save(const WifiProperties& properties) {
|
||||
std::map<std::string, std::string> map;
|
||||
map[SETTINGS_KEY_ENABLE_ON_BOOT] = properties.enableOnBoot ? "true" : "false";
|
||||
return file::savePropertiesFile(SETTINGS_FILE, map);
|
||||
}
|
||||
|
||||
void setEnableOnBoot(bool enable) {
|
||||
Preferences(WIFI_PREFERENCES_NAMESPACE).putBool(WIFI_PREFERENCES_KEY_ENABLE_ON_BOOT, enable);
|
||||
WifiProperties properties { .enableOnBoot = enable };
|
||||
if (!save(properties)) {
|
||||
TT_LOG_E(TAG, "Failed to save %s", SETTINGS_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldEnableOnBoot() {
|
||||
bool enable = false;
|
||||
Preferences(WIFI_PREFERENCES_NAMESPACE).optBool(WIFI_PREFERENCES_KEY_ENABLE_ON_BOOT, enable);
|
||||
return enable;
|
||||
WifiProperties properties;
|
||||
if (!load(properties)) {
|
||||
return false;
|
||||
}
|
||||
return properties.enableOnBoot;
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region AP
|
||||
|
||||
bool contains(const char* ssid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool load(const char* ssid, WifiApSettings* settings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool save(const WifiApSettings* settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remove(const char* ssid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#ifndef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
@ -34,10 +34,11 @@ void tt_wifi_set_enabled(bool enabled) {
|
||||
|
||||
void tt_wifi_connect(const char* ssid, const char* password, int32_t channel, bool autoConnect, bool remember) {
|
||||
wifi::settings::WifiApSettings settings;
|
||||
strcpy(settings.ssid, ssid);
|
||||
strcpy(settings.password, password);
|
||||
settings.ssid = ssid;
|
||||
settings.password = password;
|
||||
settings.channel = channel;
|
||||
settings.auto_connect = autoConnect;
|
||||
settings.autoConnect = autoConnect;
|
||||
wifi::connect(settings, remember);
|
||||
}
|
||||
|
||||
void tt_wifi_disconnect() {
|
||||
|
||||
@ -44,7 +44,7 @@ void getIv(const void* data, size_t dataLength, uint8_t iv[16]);
|
||||
* @param[in] dataLength data length, a multiple of 16 (for both inData and outData)
|
||||
* @return the result of esp_aes_crypt_cbc() (MBEDTLS_ERR_*)
|
||||
*/
|
||||
int encrypt(const uint8_t iv[16], uint8_t* inData, uint8_t* outData, size_t dataLength);
|
||||
int encrypt(const uint8_t iv[16], const uint8_t* inData, uint8_t* outData, size_t dataLength);
|
||||
|
||||
/**
|
||||
* @brief Decrypt data.
|
||||
@ -58,6 +58,7 @@ int encrypt(const uint8_t iv[16], uint8_t* inData, uint8_t* outData, size_t data
|
||||
* @param[in] dataLength data length, a multiple of 16 (for both inData and outData)
|
||||
* @return the result of esp_aes_crypt_cbc() (MBEDTLS_ERR_*)
|
||||
*/
|
||||
int decrypt(const uint8_t iv[16], uint8_t* inData, uint8_t* outData, size_t dataLength);
|
||||
int decrypt(const uint8_t iv[16], const uint8_t* inData, uint8_t* outData, size_t dataLength);
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -92,6 +92,8 @@ bool direntSortAlphaAndType(const dirent& left, const dirent& right);
|
||||
/** A filter for filtering out "." and ".." */
|
||||
int direntFilterDotEntries(const dirent* entry);
|
||||
|
||||
bool exists(const std::string& path);
|
||||
|
||||
/**
|
||||
* A scandir()-like implementation that works on ESP32.
|
||||
* It does not return "." and ".." items but otherwise functions the same.
|
||||
|
||||
@ -127,7 +127,7 @@ static void getKey(uint8_t key[32]) {
|
||||
}
|
||||
|
||||
void getIv(const void* data, size_t dataLength, uint8_t iv[16]) {
|
||||
memset((void*)iv, 0, 16);
|
||||
memset(iv, 0, 16);
|
||||
auto* data_bytes = (uint8_t*)data;
|
||||
for (int i = 0; i < dataLength; ++i) {
|
||||
size_t safe_index = i % 16;
|
||||
@ -161,7 +161,7 @@ static int aes256CryptCbc(
|
||||
return result;
|
||||
}
|
||||
|
||||
int encrypt(const uint8_t iv[16], uint8_t* inData, uint8_t* outData, size_t dataLength) {
|
||||
int encrypt(const uint8_t iv[16], const uint8_t* inData, uint8_t* outData, size_t dataLength) {
|
||||
tt_check(dataLength % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256");
|
||||
uint8_t key[32];
|
||||
getKey(key);
|
||||
@ -173,7 +173,7 @@ int encrypt(const uint8_t iv[16], uint8_t* inData, uint8_t* outData, size_t data
|
||||
return aes256CryptCbc(key, MBEDTLS_AES_ENCRYPT, dataLength, iv_copy, inData, outData);
|
||||
}
|
||||
|
||||
int decrypt(const uint8_t iv[16], uint8_t* inData, uint8_t* outData, size_t dataLength) {
|
||||
int decrypt(const uint8_t iv[16], const uint8_t* inData, uint8_t* outData, size_t dataLength) {
|
||||
tt_check(dataLength % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256");
|
||||
uint8_t key[32];
|
||||
getKey(key);
|
||||
|
||||
@ -208,4 +208,8 @@ bool findOrCreateDirectory(std::string path, mode_t mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exists(const std::string& path) {
|
||||
return access(path.c_str(), F_OK) == 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user