#include "qrimport.h" // esp-idf includes #include #include // 3rd party includes #include #include #include #include // local includes #include "newsettings.h" namespace qrimport { namespace { constexpr const char * const TAG = "QRIMPORT"; cpputils::DelayedConstruction http_request; } // namespace // nvs bool has_qr_code(std::string_view key) { const auto handle = configs.nvs_handle_user; size_t length; if (const esp_err_t result = nvs_get_str(handle, key.data(), nullptr, &length); result != ESP_OK) { if (result != ESP_ERR_NVS_NOT_FOUND) ESP_LOGW(TAG, "nvs_get_str() size-only for key %.*s failed with %s", key.size(), key.data(), esp_err_to_name(result)); return false; } return length; } tl::expected get_qr_code(std::string_view key) { const auto handle = configs.nvs_handle_user; size_t length; if (const esp_err_t result = nvs_get_str(handle, key.data(), nullptr, &length); result != ESP_OK) { if (result != ESP_ERR_NVS_NOT_FOUND) ESP_LOGW(TAG, "nvs_get_str() size-only for key %.*s failed with %s", key.size(), key.data(), esp_err_to_name(result)); return tl::make_unexpected(result); } // empty string optimization if (!length) return {}; std::string buf; buf.resize(length); if (const esp_err_t result = nvs_get_str(handle, key.data(), buf.data(), &length); result != ESP_OK) { ESP_LOGW(TAG, "nvs_get_str() for key %.*s failed with %s", key.size(), key.data(), esp_err_to_name(result)); return tl::make_unexpected(result); } if (buf.back() == '\n') buf.resize(buf.size() - 1); return buf; // no std::move needed as return is optimized } tl::expected set_qr_code(std::string_view key, std::string_view qrcode) { const auto handle = configs.nvs_handle_user; if (const esp_err_t result = nvs_set_str(handle, key.data(), qrcode.data()); result != ESP_OK) { ESP_LOGW(TAG, "nvs_set_str() for key %.*s failed with %s", key.size(), key.data(), esp_err_to_name(result)); return tl::make_unexpected(result); } return {}; } tl::expected delete_qr_code(std::string_view key) { const auto handle = configs.nvs_handle_user; if (const esp_err_t result = nvs_erase_key(handle, key.data()); result != ESP_OK) { ESP_LOGW(TAG, "nvs_erase_key() for key %.*s failed with %s", key.size(), key.data(), esp_err_to_name(result)); return tl::make_unexpected(result); } return {}; } // web request void setup_request() { if (!http_request.constructed()) { http_request.construct("qr_request", espcpputils::CoreAffinity::Core0); } } tl::expected start_qr_request() { if (!http_request.constructed()) { return tl::make_unexpected("request im oarsch"); } if (auto res = http_request->start(fmt::format("http://qr.bobbycar.cloud/qr/{}.qr", configs.otaUsername.value())); !res) { return res; } return{}; } tl::expected check_request() { if (!http_request.constructed()) { return tl::make_unexpected("request im oarsch"); } if (!http_request->finished()) { return tl::make_unexpected("request has not finished"); } const auto helper = cpputils::makeCleanupHelper([](){ http_request->clearFinished(); }); if (const auto result = http_request->result(); !result) { return tl::make_unexpected(result.error()); } else if (http_request->statusCode() != 200) { DynamicJsonDocument doc(256); deserializeJson(doc, http_request->takeBuffer()); return tl::make_unexpected(fmt::format("{} {}", http_request->statusCode(), doc["error"].as())); } else { ESP_LOGI(TAG, "%.*s", http_request->buffer().size(), http_request->buffer().data()); return http_request->takeBuffer(); } } bool get_request_running() { if (!http_request.constructed()) { ESP_LOGW(TAG, "not constructed"); return false; } return !http_request->finished(); } } // namespace