mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 04:27:12 +03:00
121 lines
3.8 KiB
C++
121 lines
3.8 KiB
C++
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
|
#include "Batch.h"
|
|
#include "esp_event.h"
|
|
#include "esp_http_client.h"
|
|
#include "esp_log.h"
|
|
#include "esp_netif.h"
|
|
#include "esp_ota_ops.h"
|
|
#include "esp_tls.h"
|
|
|
|
#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
|
|
#include "esp_crt_bundle.h"
|
|
#endif
|
|
#include "esp_system.h"
|
|
#include "http_handlers.h"
|
|
#include "tools.h"
|
|
#include <algorithm>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <sys/param.h>
|
|
#if CONFIG_WITH_METRICS
|
|
static const char* const TAG = "MetricsBatch";
|
|
static const char* const feature_evt_name = "$feature_flag_called";
|
|
static const char* const feature_flag_name = "$feature_flag";
|
|
static const char* const feature_flag_response_name = "$feature_flag_response";
|
|
|
|
namespace Metrics {
|
|
|
|
Event& Batch::add_feature_event() { return add_event(feature_evt_name); }
|
|
void Batch::add_remove_feature_event(const char* name, bool active) {
|
|
if (!active) {
|
|
remove_feature_event(name);
|
|
} else {
|
|
add_event(feature_evt_name).add_property(feature_flag_name, name);
|
|
}
|
|
}
|
|
Event& Batch::add_feature_variant_event(const char* const name, const char* const value) {
|
|
return add_event(feature_evt_name)
|
|
.add_property(feature_flag_name, name)
|
|
.add_property(feature_flag_response_name, value);
|
|
}
|
|
void Batch::remove_feature_event(const char* name) {
|
|
for (Metrics::Event& e : _events) {
|
|
if (strcmp(e.get_name(), feature_evt_name) == 0) {
|
|
e.remove_property(feature_flag_name, name);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
cJSON* Batch::to_json() {
|
|
cJSON* batch_json = cJSON_CreateArray();
|
|
for (Metrics::Event& e : _events) {
|
|
cJSON_AddItemToArray(batch_json, e.to_json(_metrics_uid.c_str()));
|
|
}
|
|
cJSON* message = cJSON_CreateObject();
|
|
cJSON_AddItemToObject(message, "batch", batch_json);
|
|
cJSON_AddStringToObject(message, "api_key", _api_key);
|
|
return batch_json;
|
|
}
|
|
char* Batch::to_json_str() {
|
|
cJSON* json = to_json();
|
|
char* json_str = cJSON_PrintUnformatted(json);
|
|
cJSON_Delete(json);
|
|
return json_str;
|
|
}
|
|
|
|
void Batch::push() {
|
|
int status_code = 0;
|
|
if (_metrics_uid.empty() && !_warned) {
|
|
ESP_LOGW(TAG, "Metrics disabled; no CID found");
|
|
_warned = true;
|
|
return;
|
|
}
|
|
|
|
char* json_str = to_json_str();
|
|
ESP_LOGV(TAG, "Metrics payload: %s", json_str);
|
|
uint32_t start_time = gettime_ms();
|
|
|
|
status_code = metrics_http_post_request(json_str, _url);
|
|
|
|
if (status_code == 200 || status_code == 204) {
|
|
_events.clear();
|
|
}
|
|
FREE_AND_NULL(json_str)
|
|
ESP_LOGD(TAG, "Total duration for metrics call: %u. ", gettime_ms() - start_time);
|
|
}
|
|
|
|
void Batch::build_guid() {
|
|
uint8_t raw[16];
|
|
std::ostringstream oss;
|
|
esp_fill_random(raw, 16);
|
|
std::for_each(std::begin(raw), std::end(raw), [&oss](const uint8_t& byte) {
|
|
oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
|
|
});
|
|
_metrics_uid = oss.str();
|
|
}
|
|
void Batch::assign_id() {
|
|
size_t size = 0;
|
|
esp_err_t esp_err = ESP_OK;
|
|
_metrics_uid = std::string((char*)get_nvs_value_alloc_for_partition(
|
|
NVS_DEFAULT_PART_NAME, TAG, NVS_TYPE_BLOB, "cid", &size));
|
|
if (_metrics_uid[0] == 'G') {
|
|
ESP_LOGW(TAG, "Invalid ID. %s", _metrics_uid.c_str());
|
|
_metrics_uid.clear();
|
|
}
|
|
if (_metrics_uid.empty()) {
|
|
build_guid();
|
|
if (_metrics_uid.empty()) {
|
|
ESP_LOGE(TAG, "ID Failed");
|
|
return;
|
|
}
|
|
ESP_LOGW(TAG, "Metrics ID: %s", _metrics_uid.c_str());
|
|
esp_err = store_nvs_value_len_for_partition(NVS_DEFAULT_PART_NAME, TAG, NVS_TYPE_BLOB,
|
|
"cid", _metrics_uid.c_str(), _metrics_uid.length() + 1);
|
|
if (esp_err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Store ID failed: %s", esp_err_to_name(esp_err));
|
|
}
|
|
}
|
|
}
|
|
} // namespace Metrics
|
|
#endif |