|
|
@ -6,14 +6,17 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "nvs.hpp" |
|
|
|
#include "nvs.hpp" |
|
|
|
#include <stdint.h> |
|
|
|
#include <stdint.h> |
|
|
|
|
|
|
|
#include <sys/_stdint.h> |
|
|
|
|
|
|
|
|
|
|
|
#include <cstdint> |
|
|
|
#include <cstdint> |
|
|
|
#include <memory> |
|
|
|
#include <memory> |
|
|
|
|
|
|
|
|
|
|
|
#include "bluetooth.hpp" |
|
|
|
#include "bluetooth.hpp" |
|
|
|
|
|
|
|
#include "bluetooth_types.hpp" |
|
|
|
#include "esp_log.h" |
|
|
|
#include "esp_log.h" |
|
|
|
#include "nvs.h" |
|
|
|
#include "nvs.h" |
|
|
|
#include "nvs_flash.h" |
|
|
|
#include "nvs_flash.h" |
|
|
|
|
|
|
|
#include "tasks.hpp" |
|
|
|
|
|
|
|
|
|
|
|
namespace drivers { |
|
|
|
namespace drivers { |
|
|
|
|
|
|
|
|
|
|
@ -23,8 +26,9 @@ static constexpr uint8_t kSchemaVersion = 1; |
|
|
|
static constexpr char kKeyVersion[] = "ver"; |
|
|
|
static constexpr char kKeyVersion[] = "ver"; |
|
|
|
static constexpr char kKeyBluetooth[] = "bt"; |
|
|
|
static constexpr char kKeyBluetooth[] = "bt"; |
|
|
|
static constexpr char kKeyOutput[] = "out"; |
|
|
|
static constexpr char kKeyOutput[] = "out"; |
|
|
|
|
|
|
|
static constexpr char kKeyBrightness[] = "bright"; |
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::Open() -> NvsStorage* { |
|
|
|
auto NvsStorage::OpenSync() -> NvsStorage* { |
|
|
|
esp_err_t err = nvs_flash_init(); |
|
|
|
esp_err_t err = nvs_flash_init(); |
|
|
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES) { |
|
|
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES) { |
|
|
|
ESP_LOGW(kTag, "partition needs initialisation"); |
|
|
|
ESP_LOGW(kTag, "partition needs initialisation"); |
|
|
@ -42,59 +46,80 @@ auto NvsStorage::Open() -> NvsStorage* { |
|
|
|
return nullptr; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<NvsStorage> instance = std::make_unique<NvsStorage>(handle); |
|
|
|
std::unique_ptr<NvsStorage> instance = std::make_unique<NvsStorage>( |
|
|
|
if (instance->SchemaVersion() < kSchemaVersion) { |
|
|
|
std::unique_ptr<tasks::Worker>( |
|
|
|
ESP_LOGW(kTag, "namespace needs downgrading"); |
|
|
|
tasks::Worker::Start<tasks::Type::kNvsWriter>()), |
|
|
|
nvs_erase_all(handle); |
|
|
|
handle); |
|
|
|
nvs_set_u8(handle, kKeyVersion, kSchemaVersion); |
|
|
|
if (instance->SchemaVersionSync() < kSchemaVersion && |
|
|
|
err = nvs_commit(handle); |
|
|
|
!instance->DowngradeSchemaSync()) { |
|
|
|
if (err != ESP_OK) { |
|
|
|
|
|
|
|
ESP_LOGW(kTag, "failed to init namespace"); |
|
|
|
ESP_LOGW(kTag, "failed to init namespace"); |
|
|
|
return nullptr; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(kTag, "nvm storage initialised okay"); |
|
|
|
ESP_LOGI(kTag, "nvm storage initialised okay"); |
|
|
|
return instance.release(); |
|
|
|
return instance.release(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
NvsStorage::NvsStorage(nvs_handle_t handle) : handle_(handle) {} |
|
|
|
NvsStorage::NvsStorage(std::unique_ptr<tasks::Worker> worker, |
|
|
|
|
|
|
|
nvs_handle_t handle) |
|
|
|
|
|
|
|
: writer_(std::move(worker)), handle_(handle) {} |
|
|
|
|
|
|
|
|
|
|
|
NvsStorage::~NvsStorage() { |
|
|
|
NvsStorage::~NvsStorage() { |
|
|
|
nvs_close(handle_); |
|
|
|
nvs_close(handle_); |
|
|
|
nvs_flash_deinit(); |
|
|
|
nvs_flash_deinit(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::SchemaVersion() -> uint8_t { |
|
|
|
auto NvsStorage::DowngradeSchemaSync() -> bool { |
|
|
|
|
|
|
|
ESP_LOGW(kTag, "namespace needs downgrading"); |
|
|
|
|
|
|
|
return writer_ |
|
|
|
|
|
|
|
->Dispatch<bool>([&]() -> bool { |
|
|
|
|
|
|
|
nvs_erase_all(handle_); |
|
|
|
|
|
|
|
nvs_set_u8(handle_, kKeyVersion, kSchemaVersion); |
|
|
|
|
|
|
|
return nvs_commit(handle_); |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.get() == ESP_OK; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::SchemaVersionSync() -> uint8_t { |
|
|
|
|
|
|
|
return writer_ |
|
|
|
|
|
|
|
->Dispatch<uint8_t>([&]() -> uint8_t { |
|
|
|
uint8_t ret; |
|
|
|
uint8_t ret; |
|
|
|
if (nvs_get_u8(handle_, kKeyVersion, &ret) != ESP_OK) { |
|
|
|
if (nvs_get_u8(handle_, kKeyVersion, &ret) != ESP_OK) { |
|
|
|
return UINT8_MAX; |
|
|
|
return UINT8_MAX; |
|
|
|
} |
|
|
|
} |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.get(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::PreferredBluetoothDevice() |
|
|
|
auto NvsStorage::PreferredBluetoothDevice() |
|
|
|
-> std::optional<bluetooth::mac_addr_t> { |
|
|
|
-> std::future<std::optional<bluetooth::mac_addr_t>> { |
|
|
|
|
|
|
|
return writer_->Dispatch<std::optional<bluetooth::mac_addr_t>>( |
|
|
|
|
|
|
|
[&]() -> std::optional<bluetooth::mac_addr_t> { |
|
|
|
bluetooth::mac_addr_t out{0}; |
|
|
|
bluetooth::mac_addr_t out{0}; |
|
|
|
size_t size = out.size(); |
|
|
|
size_t size = out.size(); |
|
|
|
if (nvs_get_blob(handle_, kKeyBluetooth, out.data(), &size) != ESP_OK) { |
|
|
|
if (nvs_get_blob(handle_, kKeyBluetooth, out.data(), &size) != ESP_OK) { |
|
|
|
return {}; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
} |
|
|
|
return out; |
|
|
|
return out; |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::PreferredBluetoothDevice( |
|
|
|
auto NvsStorage::PreferredBluetoothDevice( |
|
|
|
std::optional<bluetooth::mac_addr_t> addr) -> void { |
|
|
|
std::optional<bluetooth::mac_addr_t> addr) -> std::future<bool> { |
|
|
|
|
|
|
|
return writer_->Dispatch<bool>([&]() { |
|
|
|
if (!addr) { |
|
|
|
if (!addr) { |
|
|
|
nvs_erase_key(handle_, kKeyBluetooth); |
|
|
|
nvs_erase_key(handle_, kKeyBluetooth); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
nvs_set_blob(handle_, kKeyBluetooth, addr.value().data(), |
|
|
|
nvs_set_blob(handle_, kKeyBluetooth, addr.value().data(), |
|
|
|
addr.value().size()); |
|
|
|
addr.value().size()); |
|
|
|
} |
|
|
|
} |
|
|
|
nvs_commit(handle_); |
|
|
|
return nvs_commit(handle_) == ESP_OK; |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::OutputMode() -> Output { |
|
|
|
auto NvsStorage::OutputMode() -> std::future<Output> { |
|
|
|
|
|
|
|
return writer_->Dispatch<Output>([&]() -> Output { |
|
|
|
uint8_t out = 0; |
|
|
|
uint8_t out = 0; |
|
|
|
nvs_get_u8(handle_, kKeyOutput, &out); |
|
|
|
nvs_get_u8(handle_, kKeyOutput, &out); |
|
|
|
switch (out) { |
|
|
|
switch (out) { |
|
|
@ -104,11 +129,29 @@ auto NvsStorage::OutputMode() -> Output { |
|
|
|
default: |
|
|
|
default: |
|
|
|
return Output::kHeadphones; |
|
|
|
return Output::kHeadphones; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::OutputMode(Output out) -> void { |
|
|
|
auto NvsStorage::OutputMode(Output out) -> std::future<bool> { |
|
|
|
|
|
|
|
return writer_->Dispatch<bool>([&]() { |
|
|
|
nvs_set_u8(handle_, kKeyOutput, static_cast<uint8_t>(out)); |
|
|
|
nvs_set_u8(handle_, kKeyOutput, static_cast<uint8_t>(out)); |
|
|
|
nvs_commit(handle_); |
|
|
|
return nvs_commit(handle_) == ESP_OK; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::ScreenBrightness() -> std::future<uint_fast8_t> { |
|
|
|
|
|
|
|
return writer_->Dispatch<uint_fast8_t>([&]() -> uint_fast8_t { |
|
|
|
|
|
|
|
uint8_t out = 50; |
|
|
|
|
|
|
|
nvs_get_u8(handle_, kKeyBrightness, &out); |
|
|
|
|
|
|
|
return out; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto NvsStorage::ScreenBrightness(uint_fast8_t val) -> std::future<bool> { |
|
|
|
|
|
|
|
return writer_->Dispatch<bool>([&]() { |
|
|
|
|
|
|
|
nvs_set_u8(handle_, kKeyBrightness, val); |
|
|
|
|
|
|
|
return nvs_commit(handle_) == ESP_OK; |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} // namespace drivers
|
|
|
|
} // namespace drivers
|
|
|
|