mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 11:36:59 +03:00
Trim app and recovery binaries
This commit is contained in:
124
components/metrics/Batch.cpp
Normal file
124
components/metrics/Batch.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#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"
|
||||
#include "nvs_flash.h"
|
||||
#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
|
||||
#include "esp_crt_bundle.h"
|
||||
#endif
|
||||
#include "esp_system.h"
|
||||
#include "http_handlers.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs_utilities.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);
|
||||
time_t start_time = millis();
|
||||
|
||||
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: %lu. ", millis() - 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
|
||||
46
components/metrics/Batch.h
Normal file
46
components/metrics/Batch.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include "Events.h"
|
||||
#include <string>
|
||||
#ifdef __cplusplus
|
||||
namespace Metrics {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
class Batch {
|
||||
private:
|
||||
std::list<Event> _events;
|
||||
bool _warned = false;
|
||||
std::string _metrics_uid = nullptr;
|
||||
const char* _api_key = nullptr;
|
||||
const char* _url = nullptr;
|
||||
void build_guid();
|
||||
void assign_id();
|
||||
|
||||
public:
|
||||
Batch() = default;
|
||||
void configure(const char* api_key, const char* url) {
|
||||
_api_key = api_key;
|
||||
_url = url;
|
||||
assign_id();
|
||||
}
|
||||
Event& add_feature_event();
|
||||
void add_remove_feature_event(const char* name, bool active);
|
||||
Event& add_feature_variant_event(const char* const name, const char* const value);
|
||||
Event& add_event(const char* name) {
|
||||
_events.emplace_back(name);
|
||||
return _events.back();
|
||||
}
|
||||
|
||||
bool has_events() const { return !_events.empty(); }
|
||||
void remove_feature_event(const char* name);
|
||||
cJSON* to_json();
|
||||
char* to_json_str();
|
||||
void push();
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
5
components/metrics/CMakeLists.txt
Normal file
5
components/metrics/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRC_DIRS .
|
||||
INCLUDE_DIRS .
|
||||
REQUIRES json tools platform_config wifi-manager esp-tls platform_config
|
||||
PRIV_REQUIRES esp32 freertos
|
||||
)
|
||||
98
components/metrics/Events.cpp
Normal file
98
components/metrics/Events.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "Events.h"
|
||||
#include <algorithm>
|
||||
#include "esp_app_format.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#if CONFIG_WITH_METRICS
|
||||
static const char* const TAG = "MetricsEvent";
|
||||
namespace Metrics {
|
||||
Event& Event::add_property(const char* name, const char* value) {
|
||||
ESP_LOGV(TAG, "Adding property %s:%s to event %s",name,value,_name);
|
||||
char* mutable_name = strdup_psram(name); // Cast away const-ness, be careful with this
|
||||
auto elem = properties.find(mutable_name);
|
||||
FREE_AND_NULL(mutable_name)
|
||||
if (elem == properties.end()) {
|
||||
ESP_LOGV(TAG, "Adding property %s:%s to event %s",name,value,_name);
|
||||
properties.insert({strdup_psram(name), strdup_psram(value)});
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Replacing value for property %s. Old: %s New: %s, Event: %s",name,elem->second,value,name);
|
||||
FREE_AND_NULL(elem->second)
|
||||
elem->second = strdup_psram(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Event::has_property_value(const char* name, const char* value) const {
|
||||
ESP_LOGV(TAG, "Checking if event %s property %s has value %s",_name, name,value);
|
||||
return std::any_of(properties.begin(), properties.end(),
|
||||
[name, value](const std::pair<const char* const, char*>& kv) {
|
||||
ESP_LOGV(TAG, "Found property %s=%s", name,value);
|
||||
return strcmp(kv.first, name) == 0 && strcmp(kv.second, value) == 0;
|
||||
});
|
||||
}
|
||||
|
||||
void Event::remove_property(const char* name, const char* value) {
|
||||
auto it = properties.begin();
|
||||
ESP_LOGV(TAG, "Removing event %s property %s=%s",_name, name,value);
|
||||
while (it != properties.end()) {
|
||||
if (strcmp(it->first, name) == 0 && strcmp(it->second, value)) {
|
||||
properties.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ESP_LOGV(TAG, "Property %s=%s not found.", name,value);
|
||||
}
|
||||
cJSON* Event::properties_to_json() {
|
||||
ESP_LOGV(TAG, "Event %s properties to json.",_name);
|
||||
const esp_app_desc_t* desc = esp_ota_get_app_description();
|
||||
#ifdef CONFIG_FW_PLATFORM_NAME
|
||||
const char* platform = CONFIG_FW_PLATFORM_NAME;
|
||||
#else
|
||||
const char* platform = desc->project_name;
|
||||
#endif
|
||||
cJSON* prop_json = cJSON_CreateObject();
|
||||
auto it = properties.begin();
|
||||
|
||||
while (it != properties.end()) {
|
||||
cJSON_AddStringToObject(prop_json, it->first, it->second);
|
||||
++it;
|
||||
}
|
||||
cJSON_AddStringToObject(prop_json, "platform", platform);
|
||||
cJSON_AddStringToObject(prop_json, "build", desc->version);
|
||||
dump_json_content("User properties for event:", prop_json, ESP_LOG_VERBOSE);
|
||||
return prop_json;
|
||||
}
|
||||
cJSON* Event::to_json(const char* distinct_id) {
|
||||
// The target structure looks like this
|
||||
// {
|
||||
// "event": "batched_event_name_1",
|
||||
// "properties": {
|
||||
// "distinct_id": "user distinct id",
|
||||
// "account_type": "pro"
|
||||
// },
|
||||
// "timestamp": "[optional timestamp in ISO 8601 format]"
|
||||
// }
|
||||
ESP_LOGV(TAG,"Event %s to json",_name);
|
||||
|
||||
free_json();
|
||||
_json = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(_json, "name", _name);
|
||||
cJSON_AddItemToObject(_json, "properties", properties_to_json());
|
||||
|
||||
char buf[26] = {};
|
||||
strftime(buf, sizeof(buf), "%FT%TZ", gmtime(&_time));
|
||||
// this will work too, if your compiler doesn't support %F or %T:
|
||||
// strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
|
||||
cJSON_AddStringToObject(_json, "timestamp", buf);
|
||||
cJSON* prop_json = properties_to_json();
|
||||
cJSON_AddStringToObject(prop_json, "distinct_id", distinct_id);
|
||||
dump_json_content("Full Event:", _json, ESP_LOG_VERBOSE);
|
||||
return _json;
|
||||
}
|
||||
void Event::free_json() { cJSON_Delete(_json); }
|
||||
void Event::update_time() {
|
||||
if (_time == 0) {
|
||||
_time = time(nullptr);
|
||||
}
|
||||
}
|
||||
} // namespace Metrics
|
||||
#endif
|
||||
53
components/metrics/Events.h
Normal file
53
components/metrics/Events.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "esp_log.h"
|
||||
#include "tools.h"
|
||||
#include <cJSON.h>
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
namespace Metrics {
|
||||
struct StrCompare {
|
||||
bool operator()(const char* a, const char* b) const { return strcmp(a, b) < 0; }
|
||||
};
|
||||
|
||||
class Event {
|
||||
|
||||
public:
|
||||
std::map<char*, char*, StrCompare> properties;
|
||||
Event& add_property(const char* name, const char* value);
|
||||
bool has_property_value(const char* name, const char* value) const;
|
||||
void remove_property(const char* name, const char* value);
|
||||
cJSON* properties_to_json();
|
||||
cJSON* to_json(const char* distinct_id);
|
||||
void free_json();
|
||||
void update_time();
|
||||
explicit Event(const char* name) {
|
||||
_name = strdup_psram(name);
|
||||
memset(&_time, 0x00, sizeof(_time));
|
||||
}
|
||||
const char* get_name() const { return _name; }
|
||||
~Event() {
|
||||
FREE_AND_NULL(_name);
|
||||
|
||||
// Iterate through the map and free the elements
|
||||
for (auto& kv : properties) {
|
||||
free((void*)kv.first);
|
||||
free(kv.second);
|
||||
}
|
||||
properties.clear(); // Clear the map after freeing memory
|
||||
FREE_AND_NULL(_json);
|
||||
}
|
||||
private:
|
||||
char* _name = nullptr;
|
||||
time_t _time;
|
||||
cJSON* _json = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Metrics
|
||||
#endif
|
||||
148
components/metrics/Metrics.cpp
Normal file
148
components/metrics/Metrics.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#include "Metrics.h"
|
||||
#include "Batch.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_tls.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "tools.h"
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "cJSON.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "network_manager.h"
|
||||
#include "platform_config.h"
|
||||
|
||||
static const char* TAG = "metrics";
|
||||
|
||||
#if CONFIG_WITH_METRICS
|
||||
extern bool is_network_connected();
|
||||
#define METRICS_CLIENT_ID_LEN 50
|
||||
#define MAX_HTTP_RECV_BUFFER 512
|
||||
|
||||
static bool metrics_usage_gen = false;
|
||||
static time_t metrics_usage_gen_time = 0;
|
||||
#ifndef METRICS_API_KEY
|
||||
#pragma message "Metrics API key needs to be passed from the environment"
|
||||
#define METRICS_API_KEY "ZZZ"
|
||||
#endif
|
||||
static const char* metrics_api_key =
|
||||
static const char* parms_str = "params";
|
||||
static const char* properties_str = "properties";
|
||||
static const char* user_properties_str = "user_properties";
|
||||
static const char* items_str = "items";
|
||||
static const char* quantity_str = "quantity";
|
||||
static const char* metrics_url = "https://app.posthog.com";
|
||||
static TimerHandle_t timer;
|
||||
extern cJSON* get_cmd_list();
|
||||
Metrics::Batch batch;
|
||||
|
||||
static void metrics_timer_cb(void* timer_id) {
|
||||
if (batch.has_events()) {
|
||||
if (!is_network_connected()) {
|
||||
ESP_LOGV(TAG, "Network not connected. can't flush");
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Pushing events");
|
||||
batch.push();
|
||||
}
|
||||
}
|
||||
if (millis() > metrics_usage_gen_time && !metrics_usage_gen) {
|
||||
metrics_usage_gen = true;
|
||||
ESP_LOGV(TAG, "Generate command list to pull features");
|
||||
cJSON* cmdlist = get_cmd_list();
|
||||
dump_json_content("generated cmd list", cmdlist, ESP_LOG_VERBOSE);
|
||||
cJSON_Delete(cmdlist);
|
||||
}
|
||||
}
|
||||
void metrics_init() {
|
||||
ESP_LOGV(TAG, "Initializing metrics");
|
||||
batch.configure(metrics_api_key, metrics_url);
|
||||
if (!timer) {
|
||||
ESP_LOGE(TAG, "Metrics Timer failure");
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Starting timer");
|
||||
xTimerStart(timer, portMAX_DELAY);
|
||||
}
|
||||
// set a 20 seconds delay before generating the
|
||||
// features so the system has time to boot
|
||||
metrics_usage_gen_time = millis() + 20000;
|
||||
}
|
||||
|
||||
void metrics_event_playback(const char* source) {
|
||||
ESP_LOGV(TAG, "Playback event: %s", source);
|
||||
auto event = batch.add_event("play").add_property("source", source);
|
||||
}
|
||||
void metrics_event_boot(const char* partition) {
|
||||
ESP_LOGV(TAG, "Boot event %s", partition);
|
||||
auto event = batch.add_event("start");
|
||||
event.add_property("partition", partition);
|
||||
}
|
||||
void metrics_add_feature_variant(const char* name, const char* format, ...) {
|
||||
va_list args;
|
||||
ESP_LOGV(TAG, "Feature %s", name);
|
||||
va_start(args, format);
|
||||
|
||||
// Determine the required buffer size
|
||||
int size = vsnprintf(nullptr, 0, format, args);
|
||||
va_end(args); // Reset the va_list
|
||||
|
||||
// Allocate buffer and format the string
|
||||
std::vector<char> buffer(size + 1); // +1 for the null-terminator
|
||||
va_start(args, format);
|
||||
vsnprintf(buffer.data(), buffer.size(), format, args);
|
||||
va_end(args);
|
||||
|
||||
// Now buffer.data() contains the formatted string
|
||||
batch.add_feature_variant_event(name, buffer.data());
|
||||
}
|
||||
void metrics_add_feature(const char* name, bool active) {
|
||||
ESP_LOGV(TAG, "Adding feature %s: %s", name, active ? "ACTIVE" : "INACTIVE");
|
||||
batch.add_remove_feature_event(name, active);
|
||||
}
|
||||
void metrics_event(const char* name) {
|
||||
ESP_LOGV(TAG, "Adding Event %s", name);
|
||||
batch.add_event(name);
|
||||
}
|
||||
#else
|
||||
static const char * not_enabled = " - (metrics not enabled, this is just marking where the call happens)";
|
||||
void metrics_init(){
|
||||
#pragma message("Metrics disabled")
|
||||
ESP_LOGD(TAG,"Metrics init%s",not_enabled);
|
||||
}
|
||||
void metrics_event_boot(const char* partition){
|
||||
ESP_LOGD(TAG,"Metrics Event Boot from partition %s%s",partition,not_enabled);
|
||||
}
|
||||
void metrics_event(const char* name){
|
||||
ESP_LOGD(TAG,"Metrics Event %s%s",name,not_enabled);
|
||||
}
|
||||
void metrics_add_feature(const char* name, bool active) {
|
||||
ESP_LOGD(TAG,"Metrics add feature %s%s%s",name,active?"ACTIVE":"INACTIVE",not_enabled);
|
||||
}
|
||||
void metrics_add_feature_variant(const char* name, const char* format, ...){
|
||||
va_list args;
|
||||
ESP_LOGV(TAG, "Feature %s", name);
|
||||
va_start(args, format);
|
||||
|
||||
// Determine the required buffer size
|
||||
int size = vsnprintf(nullptr, 0, format, args);
|
||||
va_end(args); // Reset the va_list
|
||||
|
||||
// Allocate buffer and format the string
|
||||
std::vector<char> buffer(size + 1); // +1 for the null-terminator
|
||||
va_start(args, format);
|
||||
vsnprintf(buffer.data(), buffer.size(), format, args);
|
||||
va_end(args);
|
||||
|
||||
ESP_LOGD(TAG,"Metrics add feature %s variant %s%s",name,buffer.data(),not_enabled);
|
||||
}
|
||||
#endif
|
||||
18
components/metrics/Metrics.h
Normal file
18
components/metrics/Metrics.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void metrics_event_playback(const char* source);
|
||||
void metrics_event_boot(const char* partition);
|
||||
void metrics_event(const char* name);
|
||||
void metrics_add_feature(const char* name, bool active);
|
||||
void metrics_add_feature_variant(const char* name, const char* format, ...);
|
||||
void metrics_init();
|
||||
void metrics_flush();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
163
components/metrics/http_handlers.c
Normal file
163
components/metrics/http_handlers.c
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "http_handlers.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_tls.h"
|
||||
#include "tools.h"
|
||||
#include <sys/param.h>
|
||||
#if CONFIG_WITH_METRICS
|
||||
static const char* TAG = "metrics_http";
|
||||
static char* output_buffer; // Buffer to store response of http request from
|
||||
// event handler
|
||||
static int output_len = 0; // Stores number of bytes read
|
||||
#define MAX_HTTP_OUTPUT_BUFFER 2048
|
||||
// Common function signature for event handlers
|
||||
typedef void (*HttpEventHandler)(esp_http_client_event_t* evt);
|
||||
|
||||
static void handle_http_error(esp_http_client_event_t* evt) { ESP_LOGV(TAG, "ERROR"); }
|
||||
|
||||
static void handle_http_connected(esp_http_client_event_t* evt) {
|
||||
ESP_LOGV(TAG, "ON_CONNECTED");
|
||||
}
|
||||
|
||||
static void handle_http_header_sent(esp_http_client_event_t* evt) {
|
||||
ESP_LOGV(TAG, "HEADER_SENT");
|
||||
}
|
||||
|
||||
static void handle_http_on_header(esp_http_client_event_t* evt) {
|
||||
ESP_LOGV(TAG, "ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
|
||||
}
|
||||
|
||||
static void handle_http_on_data(esp_http_client_event_t* evt) {
|
||||
ESP_LOGV(TAG, "ON_DATA, len=%d", evt->data_len);
|
||||
ESP_LOGV(TAG, "ON_DATA, len=%d", evt->data_len);
|
||||
// Clean the buffer in case of a new request
|
||||
if (output_len == 0 && evt->user_data) {
|
||||
// we are just starting to copy the output data into the use
|
||||
ESP_LOGV(TAG, "Resetting buffer");
|
||||
memset(evt->user_data, 0, MAX_HTTP_OUTPUT_BUFFER);
|
||||
}
|
||||
/*
|
||||
* Check for chunked encoding is added as the URL for chunked encoding used in this example
|
||||
* returns binary data. However, event handler can also be used in case chunked encoding is
|
||||
* used.
|
||||
*/
|
||||
|
||||
// If user_data buffer is configured, copy the response into the buffer
|
||||
int copy_len = 0;
|
||||
if (evt->user_data) {
|
||||
ESP_LOGV(TAG, "Not Chunked response, with user data");
|
||||
// The last byte in evt->user_data is kept for the NULL character in
|
||||
// case of out-of-bound access.
|
||||
copy_len = MIN(evt->data_len, (MAX_HTTP_OUTPUT_BUFFER - output_len));
|
||||
if (copy_len) {
|
||||
memcpy(evt->user_data + output_len, evt->data, copy_len);
|
||||
}
|
||||
} else {
|
||||
int content_len = esp_http_client_get_content_length(evt->client);
|
||||
if (esp_http_client_is_chunked_response(evt->client)) {
|
||||
esp_http_client_get_chunk_length(evt->client, &content_len);
|
||||
}
|
||||
|
||||
if (output_buffer == NULL) {
|
||||
// We initialize output_buffer with 0 because it is used by
|
||||
// strlen() and similar functions therefore should be null
|
||||
// terminated.
|
||||
size_t len=(content_len + 1) * sizeof(char);
|
||||
ESP_LOGV(TAG, "Init buffer %d",len);
|
||||
output_buffer = (char*)malloc_init_external(len);
|
||||
output_len = 0;
|
||||
if (output_buffer == NULL) {
|
||||
ESP_LOGE(TAG, "Buffer alloc failed.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
copy_len = MIN(evt->data_len, (content_len - output_len));
|
||||
if (copy_len) {
|
||||
memcpy(output_buffer + output_len, evt->data, copy_len);
|
||||
}
|
||||
}
|
||||
output_len += copy_len;
|
||||
}
|
||||
|
||||
static void handle_http_on_finish(esp_http_client_event_t* evt) {
|
||||
ESP_LOGD(TAG, "ON_FINISH");
|
||||
if (output_buffer != NULL) {
|
||||
ESP_LOGV(TAG, "Response: %s", output_buffer);
|
||||
free(output_buffer);
|
||||
output_buffer = NULL;
|
||||
}
|
||||
output_len = 0;
|
||||
}
|
||||
static void handle_http_disconnected(esp_http_client_event_t* evt) {
|
||||
ESP_LOGI(TAG, "DISCONNECTED");
|
||||
int mbedtls_err = 0;
|
||||
esp_err_t err =
|
||||
esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
|
||||
if (err != 0) {
|
||||
ESP_LOGI(TAG, "Last error : %s", esp_err_to_name(err));
|
||||
ESP_LOGI(TAG, "Last mbedtls err 0x%x", mbedtls_err);
|
||||
}
|
||||
if (output_buffer != NULL) {
|
||||
free(output_buffer);
|
||||
output_buffer = NULL;
|
||||
}
|
||||
output_len = 0;
|
||||
}
|
||||
static const HttpEventHandler eventHandlers[] = {
|
||||
handle_http_error, // HTTP_EVENT_ERROR
|
||||
handle_http_connected, // HTTP_EVENT_ON_CONNECTED
|
||||
handle_http_header_sent, // HTTP_EVENT_HEADERS_SENT
|
||||
handle_http_header_sent, // HTTP_EVENT_HEADER_SENT (alias for HTTP_EVENT_HEADERS_SENT)
|
||||
handle_http_on_header, // HTTP_EVENT_ON_HEADER
|
||||
handle_http_on_data, // HTTP_EVENT_ON_DATA
|
||||
handle_http_on_finish, // HTTP_EVENT_ON_FINISH
|
||||
handle_http_disconnected // HTTP_EVENT_DISCONNECTED
|
||||
};
|
||||
esp_err_t metrics_http_event_handler(esp_http_client_event_t* evt) {
|
||||
|
||||
if (evt->event_id < 0 || evt->event_id >= sizeof(eventHandlers) / sizeof(eventHandlers[0])) {
|
||||
ESP_LOGE(TAG, "Invalid event ID: %d", evt->event_id);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
eventHandlers[evt->event_id](evt);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
int metrics_http_post_request(const char* payload, const char* url) {
|
||||
int status_code = 0;
|
||||
esp_http_client_config_t config = {.url = url,
|
||||
.disable_auto_redirect = false,
|
||||
.event_handler = metrics_http_event_handler,
|
||||
.transport_type = HTTP_TRANSPORT_OVER_SSL,
|
||||
.user_data = NULL, // local_response_buffer, // Pass address of
|
||||
// local buffer to get response
|
||||
.skip_cert_common_name_check = true
|
||||
|
||||
};
|
||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||
esp_err_t err = esp_http_client_set_method(client, HTTP_METHOD_POST);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
err = esp_http_client_set_header(client, "Content-Type", "application/json");
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGV(TAG, "Setting payload: %s", payload);
|
||||
err = esp_http_client_set_post_field(client, payload, strlen(payload));
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = esp_http_client_perform(client);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
status_code = esp_http_client_get_status_code(client);
|
||||
ESP_LOGD(TAG, "metrics call Status = %d, content_length = %d",
|
||||
esp_http_client_get_status_code(client), esp_http_client_get_content_length(client));
|
||||
|
||||
} else {
|
||||
status_code = 500;
|
||||
ESP_LOGW(TAG, "metrics call Status failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
esp_http_client_cleanup(client);
|
||||
return status_code;
|
||||
}
|
||||
#endif
|
||||
11
components/metrics/http_handlers.h
Normal file
11
components/metrics/http_handlers.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int metrics_http_post_request(const char* payload, const char* url);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -13,14 +13,14 @@ esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data, siz
|
||||
esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data);
|
||||
esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size);
|
||||
void * get_nvs_value_alloc(nvs_type_t type, const char *key);
|
||||
void * get_nvs_value_alloc_for_partition(const char * partition,const char * ns,nvs_type_t type, const char *key, size_t * size);
|
||||
esp_err_t erase_nvs_for_partition(const char * partition, const char * ns,const char *key);
|
||||
esp_err_t store_nvs_value_len_for_partition(const char * partition,const char * ns,nvs_type_t type, const char *key, const void * data,size_t data_len);
|
||||
void * get_nvs_value_alloc_for_partition(const char * partition,const char * name_space,nvs_type_t type, const char *key, size_t * size);
|
||||
esp_err_t erase_nvs_for_partition(const char * partition, const char * name_space,const char *key);
|
||||
esp_err_t store_nvs_value_len_for_partition(const char * partition,const char * name_space,nvs_type_t type, const char *key, const void * data,size_t data_len);
|
||||
esp_err_t erase_nvs(const char *key);
|
||||
void print_blob(const char *blob, size_t len);
|
||||
const char *type_to_str(nvs_type_t type);
|
||||
nvs_type_t str_to_type(const char *type);
|
||||
esp_err_t erase_nvs_partition(const char * partition, const char * ns);
|
||||
esp_err_t erase_nvs_partition(const char * partition, const char * name_space);
|
||||
void erase_settings_partition();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -634,7 +634,7 @@ cJSON * config_alloc_get_cjson(const char *key){
|
||||
}
|
||||
return conf_json;
|
||||
}
|
||||
esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value){
|
||||
esp_err_t config_set_cjson(const char *key, cJSON *value, bool free_cjson){
|
||||
char * value_str = cJSON_PrintUnformatted(value);
|
||||
if(value_str==NULL){
|
||||
ESP_LOGE(TAG, "Unable to print cJSON for key [%s]", key);
|
||||
@@ -642,9 +642,14 @@ esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value){
|
||||
}
|
||||
esp_err_t err = config_set_value(NVS_TYPE_STR,key, value_str);
|
||||
free(value_str);
|
||||
if(free_cjson){
|
||||
cJSON_Delete(value);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value){
|
||||
return config_set_cjson(key, value, true);
|
||||
}
|
||||
void config_get_uint16t_from_str(const char *key, uint16_t *value, uint16_t default_value){
|
||||
char * str_value = config_alloc_get(NVS_TYPE_STR, key);
|
||||
if(str_value == NULL){
|
||||
@@ -786,6 +791,44 @@ cJSON* cjson_update_number(cJSON** root, const char* key, int value) {
|
||||
}
|
||||
return *root;
|
||||
}
|
||||
bool config_parse_param_int(const char * config,const char * param, char delimiter,int * value){
|
||||
const char *p;
|
||||
if(!value){
|
||||
return false;
|
||||
}
|
||||
if ((p = strcasestr(config, param)) && (p = strchr(p, delimiter))) {
|
||||
*value = atoi(p+1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool config_parse_param_float(const char * config,const char * param, char delimiter,double * value){
|
||||
const char *p;
|
||||
if(!value){
|
||||
return false;
|
||||
}
|
||||
if ((p = strcasestr(config, param)) && (p = strchr(p, delimiter))) {
|
||||
*value = atof(p+1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool config_parse_param_str(const char *source, const char *param, char delimiter, char *value, size_t value_size) {
|
||||
char *p;
|
||||
if ((p = strstr(source, param)) && (p = strchr(p, delimiter))) {
|
||||
while (*++p == ' '); // Skip spaces
|
||||
// Read the value into the buffer, making sure not to overflow
|
||||
snprintf(value, value_size, "%s", p);
|
||||
char *end = strchr(value, ',');
|
||||
if (end) {
|
||||
*end = '\0'; // Null-terminate at the comma, if found
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_SET_DEFAULT(uint8_t,NVS_TYPE_U8);
|
||||
IMPLEMENT_SET_DEFAULT(int8_t,NVS_TYPE_I8);
|
||||
IMPLEMENT_SET_DEFAULT(uint16_t,NVS_TYPE_U16);
|
||||
|
||||
@@ -8,7 +8,12 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PARSE_WITH_FUNC 1
|
||||
#ifdef PARSE_WITH_FUNC
|
||||
#define PARSE_PARAM(S,P,C,V) config_parse_param_int(S,P,C,(int*)&V)
|
||||
#define PARSE_PARAM_STR(S,P,C,V,I) config_parse_param_str(S,P,C,V,I)
|
||||
#define PARSE_PARAM_FLOAT(S,P,C,V) config_parse_param_float(S,P,C,&V)
|
||||
#else
|
||||
#define PARSE_PARAM(S,P,C,V) do { \
|
||||
char *__p; \
|
||||
if ((__p = strcasestr(S, P)) && (__p = strchr(__p, C))) V = atoi(__p+1); \
|
||||
@@ -26,7 +31,7 @@ extern "C" {
|
||||
sscanf(__p,"%" #I "[^,]", V); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#define DECLARE_SET_DEFAULT(t) void config_set_default_## t (const char *key, t value);
|
||||
#define DECLARE_GET_NUM(t) esp_err_t config_get_## t (const char *key, t * value);
|
||||
#ifndef FREE_RESET
|
||||
@@ -50,10 +55,14 @@ bool config_has_changes();
|
||||
void config_commit_to_nvs();
|
||||
void config_start_timer();
|
||||
void config_init();
|
||||
bool config_parse_param_int(const char * config,const char * param, char delimiter,int * value);
|
||||
bool config_parse_param_float(const char * config,const char * param, char delimiter,double * value);
|
||||
bool config_parse_param_str(const char *source, const char *param, char delimiter, char *value, size_t value_size);
|
||||
void * config_alloc_get_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
|
||||
void * config_alloc_get_str(const char *key, char *lead, char *fallback);
|
||||
cJSON * config_alloc_get_cjson(const char *key);
|
||||
esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value);
|
||||
esp_err_t config_set_cjson(const char *key, cJSON *value, bool free_cjson);
|
||||
void config_get_uint16t_from_str(const char *key, uint16_t *value, uint16_t default_value);
|
||||
void config_delete_key(const char *key);
|
||||
void config_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
|
||||
|
||||
@@ -8,7 +8,7 @@ idf_component_register( SRCS
|
||||
cmd_config.c
|
||||
INCLUDE_DIRS .
|
||||
REQUIRES nvs_flash
|
||||
PRIV_REQUIRES console app_update tools services spi_flash platform_config vfs pthread wifi-manager platform_config newlib telnet display squeezelite tools)
|
||||
PRIV_REQUIRES console app_update tools services spi_flash platform_config vfs pthread wifi-manager platform_config newlib telnet display squeezelite tools metrics)
|
||||
|
||||
set_source_files_properties(cmd_config.c
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
idf_component_register( SRC_DIRS .
|
||||
INCLUDE_DIRS .
|
||||
PRIV_REQUIRES bootloader_support
|
||||
PRIV_REQUIRES bootloader_support json
|
||||
)
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--undefined=esp_app_desc")
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
#include "application_name.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_app_format.h"
|
||||
|
||||
#include "cJSON.h"
|
||||
#include "stdbool.h"
|
||||
extern esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t length);
|
||||
|
||||
extern cJSON * gpio_list;
|
||||
const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
||||
.magic_word = ESP_APP_DESC_MAGIC_WORD,
|
||||
.version = PROJECT_VER,
|
||||
@@ -26,7 +27,12 @@ const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
||||
.date = "",
|
||||
#endif
|
||||
};
|
||||
|
||||
cJSON * get_gpio_list(bool refresh){
|
||||
if(!gpio_list){
|
||||
gpio_list = cJSON_CreateArray();
|
||||
}
|
||||
return gpio_list;
|
||||
}
|
||||
void register_optional_cmd(void) {
|
||||
}
|
||||
|
||||
|
||||
@@ -43,12 +43,25 @@ const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
||||
extern void register_audio_config(void);
|
||||
extern void register_rotary_config(void);
|
||||
extern void register_ledvu_config(void);
|
||||
|
||||
extern void register_nvs();
|
||||
extern cJSON * get_gpio_list_handler(bool refresh);
|
||||
void register_optional_cmd(void) {
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
register_rotary_config();
|
||||
register_ledvu_config();
|
||||
#endif
|
||||
register_audio_config();
|
||||
register_ledvu_config();
|
||||
register_nvs();
|
||||
|
||||
}
|
||||
cJSON * get_gpio_list(bool refresh){
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
return get_gpio_list_handler(refresh);
|
||||
#else
|
||||
return cJSON_CreateArray();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern int squeezelite_main(int argc, char **argv);
|
||||
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
#include "tools.h"
|
||||
#include "cJSON.h"
|
||||
#include "cmd_i2ctools.h"
|
||||
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
#include "metrics.h"
|
||||
#endif
|
||||
#include "cmd_system.h"
|
||||
const char * desc_squeezelite ="Squeezelite Options";
|
||||
const char * desc_dac= "DAC Options";
|
||||
const char * desc_cspotc= "Spotify (cSpot) Options";
|
||||
@@ -330,9 +333,8 @@ static int do_bt_source_cmd(int argc, char **argv){
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
// char value[100] ={0};
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
@@ -441,9 +443,8 @@ static int do_audio_cmd(int argc, char **argv){
|
||||
int nerrors = arg_parse(argc, argv,(void **)&audio_args);
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
@@ -529,9 +530,8 @@ static int do_spdif_cmd(int argc, char **argv){
|
||||
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
@@ -568,9 +568,8 @@ static int do_rotary_cmd(int argc, char **argv){
|
||||
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
@@ -640,9 +639,8 @@ static int do_cspot_config(int argc, char **argv){
|
||||
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -699,9 +697,8 @@ static int do_ledvu_cmd(int argc, char **argv){
|
||||
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
@@ -759,10 +756,8 @@ static int do_i2s_cmd(int argc, char **argv)
|
||||
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
ESP_LOGE(TAG, "do_i2s_cmd: Failed to open memstream");
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
@@ -873,7 +868,9 @@ cJSON * i2s_cb(){
|
||||
cJSON * values = cJSON_CreateObject();
|
||||
|
||||
const i2s_platform_config_t * i2s_conf= config_dac_get( );
|
||||
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("i2s",i2s_conf->pin.data_out_num>=0);
|
||||
#endif
|
||||
if(i2s_conf->pin.bck_io_num>0 ) {
|
||||
cJSON_AddNumberToObject(values,i2s_args.clock->hdr.longopts,i2s_conf->pin.bck_io_num);
|
||||
}
|
||||
@@ -910,6 +907,11 @@ cJSON * i2s_cb(){
|
||||
cJSON * spdif_cb(){
|
||||
cJSON * values = cJSON_CreateObject();
|
||||
const i2s_platform_config_t * spdif_conf= config_spdif_get( );
|
||||
if(spdif_conf->pin.data_out_num>=0) {
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("spdif","enabled");
|
||||
#endif
|
||||
}
|
||||
if(spdif_conf->pin.bck_io_num>0 ) {
|
||||
cJSON_AddNumberToObject(values,"clock",spdif_conf->pin.bck_io_num);
|
||||
}
|
||||
@@ -928,7 +930,9 @@ cJSON * rotary_cb(){
|
||||
bool raw_mode = p && (*p == '1' || *p == 'Y' || *p == 'y');
|
||||
free(p);
|
||||
const rotary_struct_t *rotary= config_rotary_get();
|
||||
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("rotary",GPIO_IS_VALID_GPIO(rotary->A ));
|
||||
#endif
|
||||
if(GPIO_IS_VALID_GPIO(rotary->A ) && rotary->A>=0 && GPIO_IS_VALID_GPIO(rotary->B) && rotary->B>=0){
|
||||
cJSON_AddNumberToObject(values,rotary_args.A->hdr.longopts,rotary->A);
|
||||
cJSON_AddNumberToObject(values,rotary_args.B->hdr.longopts,rotary->B);
|
||||
@@ -947,7 +951,11 @@ cJSON * rotary_cb(){
|
||||
cJSON * ledvu_cb(){
|
||||
cJSON * values = cJSON_CreateObject();
|
||||
const ledvu_struct_t *ledvu= config_ledvu_get();
|
||||
|
||||
if(GPIO_IS_VALID_GPIO(ledvu->gpio )){
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("led_vu","enabled");
|
||||
#endif
|
||||
}
|
||||
if(GPIO_IS_VALID_GPIO(ledvu->gpio) && ledvu->gpio>=0 && ledvu->length > 0){
|
||||
cJSON_AddNumberToObject(values,"gpio",ledvu->gpio);
|
||||
cJSON_AddNumberToObject(values,"length",ledvu->length);
|
||||
@@ -965,8 +973,14 @@ cJSON * audio_cb(){
|
||||
cJSON * values = cJSON_CreateObject();
|
||||
char * p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0);
|
||||
cJSON_AddStringToObject(values,"jack_behavior",(strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0)?"Headphones":"Subwoofer");
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("jack_mute",atoi(p)>=0);
|
||||
#endif
|
||||
FREE_AND_NULL(p);
|
||||
p = config_alloc_get_default(NVS_TYPE_STR, "loudness", "0", 0);
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("loudness",atoi(p)>=0);
|
||||
#endif
|
||||
cJSON_AddStringToObject(values,"loudness",p);
|
||||
FREE_AND_NULL(p);
|
||||
return values;
|
||||
@@ -976,6 +990,9 @@ cJSON * bt_source_cb(){
|
||||
char * p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_sink_name", NULL, 0);
|
||||
if(p){
|
||||
cJSON_AddStringToObject(values,"sink_name",p);
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("btsource",strlen(p)>0);
|
||||
#endif
|
||||
}
|
||||
FREE_AND_NULL(p);
|
||||
// p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_ctmt", NULL, 0);
|
||||
@@ -1026,9 +1043,8 @@ static int do_squeezelite_cmd(int argc, char **argv)
|
||||
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr ** )&squeezelite_args);
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
fprintf(f,"Not yet implemented!");
|
||||
@@ -1047,11 +1063,10 @@ cJSON * squeezelite_cb(){
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
int nerrors=1;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
log_send_messaging(MESSAGING_ERROR,"Unable to parse squeezelite parameters");
|
||||
return values;
|
||||
}
|
||||
else {
|
||||
|
||||
if(nvs_config && strlen(nvs_config)>0){
|
||||
ESP_LOGD(TAG,"Parsing command %s",nvs_config);
|
||||
@@ -1080,6 +1095,11 @@ cJSON * squeezelite_cb(){
|
||||
// get_str_parm_json(squeezelite_args.log_level_stream, values);
|
||||
get_str_parm_json(squeezelite_args.mac_addr, values);
|
||||
get_str_parm_json(squeezelite_args.output_device, values);
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
if(squeezelite_args.output_device->sval[0]!=NULL && strlen(squeezelite_args.output_device->sval[0])>0){
|
||||
metrics_add_feature_variant("output",squeezelite_args.output_device->sval[0]);
|
||||
}
|
||||
#endif
|
||||
get_str_parm_json(squeezelite_args.model_name, values);
|
||||
get_str_parm_json(squeezelite_args.name, values);
|
||||
get_int_parm_json(squeezelite_args.rate, values);
|
||||
@@ -1099,7 +1119,6 @@ cJSON * squeezelite_cb(){
|
||||
}
|
||||
fclose(f);
|
||||
FREE_AND_NULL(buf);
|
||||
}
|
||||
FREE_AND_NULL(nvs_config);
|
||||
FREE_AND_NULL(argv);
|
||||
return values;
|
||||
@@ -1212,9 +1231,8 @@ static int do_register_known_templates_config(int argc, char **argv){
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
cJSON * config_name =NULL;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
@@ -1396,7 +1414,7 @@ void register_ledvu_config(void){
|
||||
|
||||
void register_audio_config(void){
|
||||
audio_args.jack_behavior = arg_str0("j", "jack_behavior","Headphones|Subwoofer","On supported DAC, determines the audio jack behavior. Selecting headphones will cause the external amp to be muted on insert, while selecting Subwoofer will keep the amp active all the time.");
|
||||
audio_args.loudness = arg_int0("l", "loudness","0-10","Sets the loudness level, from 0 to 10. 0 will disable the loudness completely.");
|
||||
audio_args.loudness = arg_int0("l", "loudness","0-10","Sets a loudness level, from 0 to 10. 0 will disable the loudness completely. Note that LMS has priority over setting this value, so use it only when away from your server.");
|
||||
audio_args.end = arg_end(6);
|
||||
audio_args.end = arg_end(6);
|
||||
const esp_console_cmd_t cmd = {
|
||||
@@ -1468,22 +1486,36 @@ static void register_squeezelite_config(void){
|
||||
cmd_to_json_with_cb(&cmd,&squeezelite_cb);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
void dummy_register_cmd(){
|
||||
|
||||
}
|
||||
void register_config_cmd(void){
|
||||
if(!is_dac_config_locked()){
|
||||
register_known_templates_config();
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CSPOT_SINK
|
||||
register_cspot_config();
|
||||
#endif
|
||||
register_bt_source_config();
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
if(!is_dac_config_locked()){
|
||||
register_i2s_config();
|
||||
}
|
||||
else {
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("i2s",true);
|
||||
#endif
|
||||
}
|
||||
if(!is_spdif_config_locked()){
|
||||
register_spdif_config();
|
||||
}
|
||||
else {
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature("spdif",true);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
register_optional_cmd();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,22 +6,23 @@
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "cmd_i2ctools.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "platform_console.h"
|
||||
#include "esp_log.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "platform_config.h"
|
||||
#include "accessors.h"
|
||||
#include "trace.h"
|
||||
#include "messaging.h"
|
||||
#include "display.h"
|
||||
#include "config.h"
|
||||
#include "tools.h"
|
||||
#include "adac.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "config.h"
|
||||
#include "display.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_log.h"
|
||||
#include "messaging.h"
|
||||
#include "platform_config.h"
|
||||
#include "platform_console.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "tools.h"
|
||||
#include "trace.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
@@ -74,7 +75,7 @@ static struct {
|
||||
struct arg_lit* clear;
|
||||
struct arg_end* end;
|
||||
} i2cconfig_args;
|
||||
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
static struct {
|
||||
struct arg_int* data;
|
||||
struct arg_int* miso;
|
||||
@@ -84,7 +85,6 @@ static struct {
|
||||
struct arg_lit* clear;
|
||||
struct arg_end* end;
|
||||
} spiconfig_args;
|
||||
|
||||
static struct {
|
||||
struct arg_str* type;
|
||||
struct arg_str* driver;
|
||||
@@ -104,6 +104,7 @@ static struct {
|
||||
struct arg_int* mode;
|
||||
struct arg_end* end;
|
||||
} i2cdisp_args;
|
||||
#endif
|
||||
|
||||
bool is_i2c_started(i2c_port_t port) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
@@ -120,7 +121,8 @@ bool is_i2c_started(i2c_port_t port){
|
||||
ret = i2c_master_cmd_begin(port, cmd, 50 / portTICK_RATE_MS);
|
||||
}
|
||||
i2c_cmd_link_delete(cmd);
|
||||
ESP_LOGD(TAG,"i2c is %s. %s",ret!=ESP_ERR_INVALID_STATE?"started":"not started", esp_err_to_name(ret));
|
||||
ESP_LOGD(TAG, "i2c is %s. %s", ret != ESP_ERR_INVALID_STATE ? "started" : "not started",
|
||||
esp_err_to_name(ret));
|
||||
return (ret != ESP_ERR_INVALID_STATE);
|
||||
}
|
||||
|
||||
@@ -129,32 +131,26 @@ typedef struct {
|
||||
const char* description;
|
||||
} i2c_db_t;
|
||||
|
||||
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
// the list was taken from https://i2cdevices.org/addresses
|
||||
// on 2020-01-16
|
||||
|
||||
static const i2c_db_t i2c_db[] = {
|
||||
{ .address = 0x00, .description="Unknown"},
|
||||
{ .address = 0x01, .description="Unknown"},
|
||||
{ .address = 0x02, .description="Unknown"},
|
||||
{ .address = 0x03, .description="Unknown"},
|
||||
{ .address = 0x04, .description="Unknown"},
|
||||
{ .address = 0x05, .description="Unknown"},
|
||||
{ .address = 0x06, .description="Unknown"},
|
||||
{ .address = 0x07, .description="Unknown"},
|
||||
{ .address = 0x08, .description="Unknown"},
|
||||
{ .address = 0x0c, .description="AK8975"},
|
||||
{ .address = 0x0d, .description="AK8975"},
|
||||
static const i2c_db_t i2c_db[] = {{.address = 0x00, .description = "Unknown"},
|
||||
{.address = 0x01, .description = "Unknown"}, {.address = 0x02, .description = "Unknown"},
|
||||
{.address = 0x03, .description = "Unknown"}, {.address = 0x04, .description = "Unknown"},
|
||||
{.address = 0x05, .description = "Unknown"}, {.address = 0x06, .description = "Unknown"},
|
||||
{.address = 0x07, .description = "Unknown"}, {.address = 0x08, .description = "Unknown"},
|
||||
{.address = 0x0c, .description = "AK8975"}, {.address = 0x0d, .description = "AK8975"},
|
||||
{.address = 0x0e, .description = "MAG3110 AK8975 IST-8310"},
|
||||
{.address = 0x0f, .description = "AK8975"},
|
||||
{.address = 0x10, .description = "VEML7700 VML6075 VEML6075 ES8388"},
|
||||
{ .address = 0x11, .description="Si4713 SAA5246 SAA5243P/K SAA5243P/L SAA5243P/E SAA5243P/H ES8388"},
|
||||
{.address = 0x11,
|
||||
.description = "Si4713 SAA5246 SAA5243P/K SAA5243P/L SAA5243P/E SAA5243P/H ES8388"},
|
||||
{.address = 0x12, .description = "SEN-17374"},
|
||||
{.address = 0x13, .description = "VCNL40x0 SEN-17374"},
|
||||
{.address = 0x18, .description = "MCP9808 LIS3DH LSM303 COM-15093"},
|
||||
{.address = 0x19, .description = "MCP9808 LIS3DH LSM303 COM-15093"},
|
||||
{ .address = 0x1a, .description="AC101 MCP9808"},
|
||||
{ .address = 0x1b, .description="MCP9808"},
|
||||
{.address = 0x1a, .description = "AC101 MCP9808"}, {.address = 0x1b, .description = "MCP9808"},
|
||||
{.address = 0x1c, .description = "MCP9808 MMA845x FXOS8700"},
|
||||
{.address = 0x1d, .description = "MCP9808 MMA845x ADXL345 FXOS8700"},
|
||||
{.address = 0x1e, .description = "HMC5883 LSM303 MCP9808 LSM303 FXOS8700"},
|
||||
@@ -169,14 +165,12 @@ static const i2c_db_t i2c_db[] = {
|
||||
{.address = 0x27, .description = "MCP23008 MCP23017 HIH6130 TCA9554"},
|
||||
{.address = 0x28, .description = "BNO055 CAP1188"},
|
||||
{.address = 0x29, .description = "BNO055 VL53L0x VL6180X CAP1188 TCS34725 TSL2591"},
|
||||
{ .address = 0x2a, .description="CAP1188"},
|
||||
{ .address = 0x2b, .description="CAP1188"},
|
||||
{.address = 0x2a, .description = "CAP1188"}, {.address = 0x2b, .description = "CAP1188"},
|
||||
{.address = 0x2c, .description = "CAP1188 AD5248 AD5251 AD5252 CAT5171"},
|
||||
{.address = 0x2d, .description = "CAP1188 AD5248 AD5251 AD5252 CAT5171"},
|
||||
{.address = 0x2e, .description = "AD5248 AD5251 AD5252 LPS22HB"},
|
||||
{.address = 0x2f, .description = "AD5248 AD5243 AD5251 AD5252"},
|
||||
{ .address = 0x30, .description="SAA2502"},
|
||||
{ .address = 0x31, .description="SAA2502"},
|
||||
{.address = 0x30, .description = "SAA2502"}, {.address = 0x31, .description = "SAA2502"},
|
||||
{.address = 0x33, .description = "MLX90640"},
|
||||
{.address = 0x38, .description = "FT6x06 VEML6070 BMA150 SAA1064 SEN-15892 PCF8574AP"},
|
||||
{.address = 0x39, .description = "TSL2561 APDS-9960 VEML6070 SAA1064 PCF8574AP"},
|
||||
@@ -184,20 +178,30 @@ static const i2c_db_t i2c_db[] = {
|
||||
{.address = 0x3b, .description = "SAA1064 PCF8569 PCF8574AP"},
|
||||
{.address = 0x3c, .description = "SSD1305 SSD1306 PCF8578 PCF8569 SH1106 PCF8574AP"},
|
||||
{.address = 0x3d, .description = "SSD1305 SSD1306 PCF8578 SH1106 PCF8574AP"},
|
||||
{ .address = 0x3e, .description="PCF8574AP"},
|
||||
{ .address = 0x3f, .description="PCF8574AP"},
|
||||
{ .address = 0x40, .description="Si7021 HTU21D-F TMP007 TMP006 PCA9685 INA219 TEA6330 TEA6300 TDA9860 TEA6320 TDA8421 NE5751 INA260 PCF8574"},
|
||||
{ .address = 0x41, .description="TMP007 TDA8421 TDA8424 STMPE610 PCF8574 STMPE811 NE5751 INA260 TDA8425 TMP006 TDA9860 PCA9685 INA219 TDA8426"},
|
||||
{ .address = 0x42, .description="TMP007 TDA8417 HDC1008 PCF8574 INA260 TDA8415 TMP006 PCA9685 INA219"},
|
||||
{.address = 0x3e, .description = "PCF8574AP"}, {.address = 0x3f, .description = "PCF8574AP"},
|
||||
{.address = 0x40,
|
||||
.description = "Si7021 HTU21D-F TMP007 TMP006 PCA9685 INA219 TEA6330 TEA6300 TDA9860 "
|
||||
"TEA6320 TDA8421 NE5751 INA260 PCF8574"},
|
||||
{.address = 0x41,
|
||||
.description = "TMP007 TDA8421 TDA8424 STMPE610 PCF8574 STMPE811 NE5751 INA260 TDA8425 "
|
||||
"TMP006 TDA9860 PCA9685 INA219 TDA8426"},
|
||||
{.address = 0x42,
|
||||
.description = "TMP007 TDA8417 HDC1008 PCF8574 INA260 TDA8415 TMP006 PCA9685 INA219"},
|
||||
{.address = 0x43, .description = "TMP007 HDC1008 PCF8574 INA260 TMP006 PCA9685 INA219"},
|
||||
{ .address = 0x44, .description="TMP007 TMP006 PCA9685 INA219 STMPE610 SHT31 ISL29125 STMPE811 TDA4688 TDA4672 TDA4780 TDA4670 TDA8442 TDA4687 TDA4671 TDA4680 INA260 PCF8574"},
|
||||
{ .address = 0x45, .description="TMP007 TDA7433 PCF8574 TDA8376 INA260 TMP006 PCA9685 INA219 SHT31"},
|
||||
{.address = 0x44,
|
||||
.description = "TMP007 TMP006 PCA9685 INA219 STMPE610 SHT31 ISL29125 STMPE811 TDA4688 "
|
||||
"TDA4672 TDA4780 TDA4670 TDA8442 TDA4687 TDA4671 TDA4680 INA260 PCF8574"},
|
||||
{.address = 0x45,
|
||||
.description = "TMP007 TDA7433 PCF8574 TDA8376 INA260 TMP006 PCA9685 INA219 SHT31"},
|
||||
{.address = 0x46, .description = "TMP007 PCF8574 TDA8370 INA260 TMP006 PCA9685 INA219 TDA9150"},
|
||||
{.address = 0x47, .description = "TMP007 PCF8574 INA260 TMP006 PCA9685 INA219"},
|
||||
{.address = 0x48, .description = "PCA9685 INA219 PN532 TMP102 INA260 ADS1115 PCF8574 ADS7828"},
|
||||
{ .address = 0x49, .description="TSL2561 PCA9685 INA219 TMP102 INA260 ADS1115 AS7262 PCF8574 ADS7828"},
|
||||
{ .address = 0x4a, .description="ADS7828 PCF8574 ADS1115 INA260 PCA9685 MAX44009 INA219 TMP102"},
|
||||
{ .address = 0x4b, .description="ADS7828 PCF8574 ADS1115 INA260 PCA9685 MAX44009 INA219 TMP102"},
|
||||
{.address = 0x49,
|
||||
.description = "TSL2561 PCA9685 INA219 TMP102 INA260 ADS1115 AS7262 PCF8574 ADS7828"},
|
||||
{.address = 0x4a,
|
||||
.description = "ADS7828 PCF8574 ADS1115 INA260 PCA9685 MAX44009 INA219 TMP102"},
|
||||
{.address = 0x4b,
|
||||
.description = "ADS7828 PCF8574 ADS1115 INA260 PCA9685 MAX44009 INA219 TMP102"},
|
||||
{.address = 0x4c, .description = "PCA9685 INA219 INA260 PCF8574"},
|
||||
{.address = 0x4d, .description = "PCA9685 INA219 INA260 PCF8574"},
|
||||
{.address = 0x4e, .description = "PCA9685 INA219 INA260 PCF8574"},
|
||||
@@ -215,23 +219,28 @@ static const i2c_db_t i2c_db[] = {
|
||||
{.address = 0x5a, .description = "MPR121 MLX90614 CCS811 PCA9685 DRV2605"},
|
||||
{.address = 0x5b, .description = "PCA9685 CCS811 MPR121"},
|
||||
{.address = 0x5c, .description = "PCA9685 AM2315 MPR121"},
|
||||
{ .address = 0x5d, .description="PCA9685 MPR121"},
|
||||
{ .address = 0x5e, .description="PCA9685"},
|
||||
{.address = 0x5d, .description = "PCA9685 MPR121"}, {.address = 0x5e, .description = "PCA9685"},
|
||||
{.address = 0x5f, .description = "PCA9685 HTS221"},
|
||||
{ .address = 0x60, .description="SI1132 Si5351A ATECC608A TSA5511 ATECC508A SAB3035 MCP4725A0 SAB3037 PCA9685 MCP4725A1 TEA5767 MPL3115A2 MPL115A2 Si1145"},
|
||||
{ .address = 0x61, .description="Si5351A TSA5511 SAB3035 MCP4725A0 SAB3037 TEA6100 PCA9685 MCP4725A1"},
|
||||
{ .address = 0x62, .description="SCD40-D-R2 TSA5511 SAB3035 UMA1014T SAB3037 PCA9685 MCP4725A1"},
|
||||
{.address = 0x60,
|
||||
.description = "SI1132 Si5351A ATECC608A TSA5511 ATECC508A SAB3035 MCP4725A0 SAB3037 "
|
||||
"PCA9685 MCP4725A1 TEA5767 MPL3115A2 MPL115A2 Si1145"},
|
||||
{.address = 0x61,
|
||||
.description = "Si5351A TSA5511 SAB3035 MCP4725A0 SAB3037 TEA6100 PCA9685 MCP4725A1"},
|
||||
{.address = 0x62,
|
||||
.description = "SCD40-D-R2 TSA5511 SAB3035 UMA1014T SAB3037 PCA9685 MCP4725A1"},
|
||||
{.address = 0x63, .description = "Si4713 TSA5511 SAB3035 UMA1014T SAB3037 PCA9685 MCP4725A1"},
|
||||
{.address = 0x64, .description = "PCA9685 MCP4725A2 MCP4725A1"},
|
||||
{.address = 0x65, .description = "PCA9685 MCP4725A2 MCP4725A1"},
|
||||
{.address = 0x66, .description = "PCA9685 MCP4725A3 IS31FL3731 MCP4725A1"},
|
||||
{.address = 0x67, .description = "PCA9685 MCP4725A3 MCP4725A1"},
|
||||
{ .address = 0x68, .description="MPU-9250 ICM-20948 MPU6050 AMG8833 DS3231 PCA9685 PCF8573 PCF8523 DS1307 ITG3200"},
|
||||
{ .address = 0x69, .description="MPU-9250 ICM-20948 MPU6050 AMG8833 PCA9685 PCF8573 ITG3200 SPS30"},
|
||||
{.address = 0x68,
|
||||
.description =
|
||||
"MPU-9250 ICM-20948 MPU6050 AMG8833 DS3231 PCA9685 PCF8573 PCF8523 DS1307 ITG3200"},
|
||||
{.address = 0x69,
|
||||
.description = "MPU-9250 ICM-20948 MPU6050 AMG8833 PCA9685 PCF8573 ITG3200 SPS30"},
|
||||
{.address = 0x6a, .description = "PCA9685 L3GD20H PCF8573"},
|
||||
{.address = 0x6b, .description = "PCA9685 L3GD20H PCF8573"},
|
||||
{ .address = 0x6c, .description="PCA9685"},
|
||||
{ .address = 0x6d, .description="PCA9685"},
|
||||
{.address = 0x6c, .description = "PCA9685"}, {.address = 0x6d, .description = "PCA9685"},
|
||||
{.address = 0x6e, .description = "PCA9685"},
|
||||
{.address = 0x6f, .description = "PCA9685 MCP7940N"},
|
||||
{.address = 0x70, .description = "PCA9685 TCA9548 HT16K33 SHTC3"},
|
||||
@@ -240,27 +249,25 @@ static const i2c_db_t i2c_db[] = {
|
||||
{.address = 0x73, .description = "PCA9685 TCA9548 HT16K33"},
|
||||
{.address = 0x74, .description = "PCA9685 TCA9548 HT16K33"},
|
||||
{.address = 0x75, .description = "PCA9685 TCA9548 HT16K33"},
|
||||
{ .address = 0x76, .description="BME688 BME680 MS5611 MS5607 HT16K33 PCA9685 BME280 BMP280 TCA9548"},
|
||||
{ .address = 0x77, .description="PCA9685 TCA9548 HT16K33 IS31FL3731 BME280 BMP280 MS5607 BMP180 BMP085 BMA180 MS5611 BME680 BME688"},
|
||||
{ .address = 0x78, .description="PCA9685"},
|
||||
{ .address = 0x79, .description="PCA9685"},
|
||||
{ .address = 0x7a, .description="PCA9685"},
|
||||
{ .address = 0x7b, .description="PCA9685"},
|
||||
{ .address = 0x7c, .description="PCA9685"},
|
||||
{ .address = 0x7d, .description="PCA9685"},
|
||||
{ .address = 0x7e, .description="PCA9685"},
|
||||
{ .address = 0x7f, .description="PCA9685"},
|
||||
{ .address = 0, .description = NULL}
|
||||
};
|
||||
{.address = 0x76,
|
||||
.description = "BME688 BME680 MS5611 MS5607 HT16K33 PCA9685 BME280 BMP280 TCA9548"},
|
||||
{.address = 0x77,
|
||||
.description = "PCA9685 TCA9548 HT16K33 IS31FL3731 BME280 BMP280 MS5607 BMP180 BMP085 "
|
||||
"BMA180 MS5611 BME680 BME688"},
|
||||
{.address = 0x78, .description = "PCA9685"}, {.address = 0x79, .description = "PCA9685"},
|
||||
{.address = 0x7a, .description = "PCA9685"}, {.address = 0x7b, .description = "PCA9685"},
|
||||
{.address = 0x7c, .description = "PCA9685"}, {.address = 0x7d, .description = "PCA9685"},
|
||||
{.address = 0x7e, .description = "PCA9685"}, {.address = 0x7f, .description = "PCA9685"},
|
||||
{.address = 0, .description = NULL}};
|
||||
|
||||
const char* i2c_get_description(uint8_t address) {
|
||||
uint8_t i = 0;
|
||||
while(i2c_db[i].description && i2c_db[i].address!=address) i++;
|
||||
while (i2c_db[i].description && i2c_db[i].address != address)
|
||||
i++;
|
||||
return i2c_db[i].description ? i2c_db[i].description : "Unlisted";
|
||||
}
|
||||
|
||||
static esp_err_t i2c_get_port(int port, i2c_port_t *i2c_port)
|
||||
{
|
||||
#endif
|
||||
static esp_err_t i2c_get_port(int port, i2c_port_t* i2c_port) {
|
||||
if (port >= I2C_NUM_MAX) {
|
||||
log_send_messaging(MESSAGING_ERROR, "Wrong port number: %d", port);
|
||||
return ESP_FAIL;
|
||||
@@ -281,32 +288,34 @@ static esp_err_t i2c_get_port(int port, i2c_port_t *i2c_port)
|
||||
static esp_err_t i2c_master_driver_install(const char* cmdname) {
|
||||
esp_err_t err = ESP_OK;
|
||||
cmd_send_messaging(cmdname, MESSAGING_INFO, "Installing i2c driver on port %u\n", i2c_port);
|
||||
if((err=i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0))!=ESP_OK){
|
||||
cmd_send_messaging(cmdname,MESSAGING_ERROR,"Driver install failed! %s\n", esp_err_to_name(err));
|
||||
if ((err = i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE,
|
||||
I2C_MASTER_TX_BUF_DISABLE, 0)) != ESP_OK) {
|
||||
cmd_send_messaging(
|
||||
cmdname, MESSAGING_ERROR, "Driver install failed! %s\n", esp_err_to_name(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t i2c_master_driver_initialize(const char * cmdname, i2c_config_t * conf)
|
||||
{
|
||||
static esp_err_t i2c_master_driver_initialize(const char* cmdname, i2c_config_t* conf) {
|
||||
esp_err_t err = ESP_OK;
|
||||
cmd_send_messaging(cmdname,MESSAGING_INFO,"Initializing i2c driver configuration.\n mode = I2C_MODE_MASTER, \n scl_pullup_en = GPIO_PULLUP_ENABLE, \n i2c port = %u, \n sda_io_num = %u, \n sda_pullup_en = GPIO_PULLUP_ENABLE, \n scl_io_num = %u, \n scl_pullup_en = GPIO_PULLUP_ENABLE, \n master.clk_speed = %u\n", i2c_port, conf->sda_io_num,conf->scl_io_num,conf->master.clk_speed);
|
||||
cmd_send_messaging(cmdname, MESSAGING_INFO,
|
||||
"Initializing i2c driver configuration.\n mode = I2C_MODE_MASTER, \n scl_pullup_en = "
|
||||
"GPIO_PULLUP_ENABLE, \n i2c port = %u, \n sda_io_num = %u, \n sda_pullup_en = "
|
||||
"GPIO_PULLUP_ENABLE, \n scl_io_num = %u, \n scl_pullup_en = GPIO_PULLUP_ENABLE, \n "
|
||||
"master.clk_speed = %u\n",
|
||||
i2c_port, conf->sda_io_num, conf->scl_io_num, conf->master.clk_speed);
|
||||
if ((err = i2c_param_config(i2c_port, conf)) != ESP_OK) {
|
||||
cmd_send_messaging(cmdname,MESSAGING_ERROR,"i2c driver config load failed. %s\n", esp_err_to_name(err));
|
||||
cmd_send_messaging(
|
||||
cmdname, MESSAGING_ERROR, "i2c driver config load failed. %s\n", esp_err_to_name(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int do_i2c_set_display(int argc, char **argv)
|
||||
{
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
static int do_i2c_set_display(int argc, char** argv) {
|
||||
bool bHasi2cConfig = false, bHasSpiConfig = false;
|
||||
int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&i2cdisp_args);
|
||||
display_config_t config = {
|
||||
.back = -1,
|
||||
.CS_pin = -1,
|
||||
.RST_pin = -1,
|
||||
.depth = 0
|
||||
};
|
||||
display_config_t config = {.back = -1, .CS_pin = -1, .RST_pin = -1, .depth = 0};
|
||||
char* nvs_item = config_alloc_get(NVS_TYPE_STR, "i2c_config");
|
||||
if (nvs_item && strlen(nvs_item) > 0) {
|
||||
bHasi2cConfig = true;
|
||||
@@ -341,28 +350,24 @@ static int do_i2c_set_display(int argc, char **argv)
|
||||
if (i2cdisp_args.type->count) {
|
||||
if (strcasecmp(i2c_name_type, i2cdisp_args.type->sval[0]) == 0) {
|
||||
config.type = i2c_name_type;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
config.type = spi_name_type;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
config.type = i2c_name_type;
|
||||
}
|
||||
/* Check "--address" option */
|
||||
if (strcasecmp(config.type, "I2C") == 0) {
|
||||
if (i2cdisp_args.address->count > 0) {
|
||||
config.address = i2cdisp_args.address->ival[0];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
config.address = 60;
|
||||
}
|
||||
if (!bHasi2cConfig) {
|
||||
fprintf(f, "I2C bus has to be configured first. \n");
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// SPI Bus connection
|
||||
if (!bHasSpiConfig) {
|
||||
fprintf(f, "SPI bus has to be configured first. \n");
|
||||
@@ -371,8 +376,7 @@ static int do_i2c_set_display(int argc, char **argv)
|
||||
/* Check "--speed" option */
|
||||
if (i2cdisp_args.speed->count) {
|
||||
config.speed = i2cdisp_args.speed->ival[0];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
config.speed = 8000000;
|
||||
}
|
||||
/* Check "--cs" option */
|
||||
@@ -380,8 +384,7 @@ static int do_i2c_set_display(int argc, char **argv)
|
||||
/* Check "--mode" option */
|
||||
if (i2cdisp_args.mode->count) {
|
||||
config.mode = i2cdisp_args.mode->ival[0];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
config.mode = 0;
|
||||
}
|
||||
}
|
||||
@@ -436,15 +439,12 @@ static int do_i2c_set_display(int argc, char **argv)
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
|
||||
static int do_spiconfig_cmd(int argc, char** argv) {
|
||||
static spi_bus_config_t spi_config = {
|
||||
.mosi_io_num = -1,
|
||||
static spi_bus_config_t spi_config = {.mosi_io_num = -1,
|
||||
.sclk_io_num = -1,
|
||||
.miso_io_num = -1,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1
|
||||
};
|
||||
.quadhd_io_num = -1};
|
||||
int dc = -1, host = 0;
|
||||
esp_err_t err = ESP_OK;
|
||||
int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&spiconfig_args);
|
||||
@@ -476,21 +476,25 @@ static int do_spiconfig_cmd(int argc, char **argv){
|
||||
nerrors += is_output_gpio(spiconfig_args.host, f, &host, true);
|
||||
|
||||
if (!nerrors) {
|
||||
fprintf(f,"Configuring SPI data=%d clock=%d host=%u dc: %d\n", spi_config.mosi_io_num, spi_config.sclk_io_num, host, dc);
|
||||
fprintf(f, "Configuring SPI data=%d clock=%d host=%u dc: %d\n", spi_config.mosi_io_num,
|
||||
spi_config.sclk_io_num, host, dc);
|
||||
err = spi_bus_initialize(host, &spi_config, SPI_DMA_CH_AUTO);
|
||||
if (err != ESP_OK) {
|
||||
if (err == ESP_ERR_INVALID_STATE) {
|
||||
// if user is changing the host number, we need to try freeing both hosts
|
||||
if((err = spi_bus_free(host))!=ESP_OK && (err = spi_bus_free(host==1?2:1))!=ESP_OK){
|
||||
fprintf(f,"SPI bus init failed. Please clear SPI configuration, restart the device and try again. %s\n", esp_err_to_name(err));
|
||||
if ((err = spi_bus_free(host)) != ESP_OK &&
|
||||
(err = spi_bus_free(host == 1 ? 2 : 1)) != ESP_OK) {
|
||||
fprintf(f,
|
||||
"SPI bus init failed. Please clear SPI configuration, restart the device "
|
||||
"and try again. %s\n",
|
||||
esp_err_to_name(err));
|
||||
nerrors++;
|
||||
}
|
||||
else if((err=spi_bus_initialize( host, &spi_config, SPI_DMA_CH_AUTO ))!=ESP_OK){
|
||||
} else if ((err = spi_bus_initialize(host, &spi_config, SPI_DMA_CH_AUTO)) !=
|
||||
ESP_OK) {
|
||||
fprintf(f, "Failed to initialize SPI Bus. %s\n", esp_err_to_name(err));
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fprintf(f, "SPI bus initialization failed. %s\n", esp_err_to_name(err));
|
||||
nerrors++;
|
||||
}
|
||||
@@ -510,19 +514,16 @@ static int do_spiconfig_cmd(int argc, char **argv){
|
||||
FREE_AND_NULL(buf);
|
||||
return nerrors;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int do_i2cconfig_cmd(int argc, char **argv)
|
||||
{
|
||||
static int do_i2cconfig_cmd(int argc, char** argv) {
|
||||
esp_err_t err = ESP_OK;
|
||||
i2c_config_t conf = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
i2c_config_t conf = {.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = 19,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_io_num = 18,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000
|
||||
};
|
||||
.master.clk_speed = 100000};
|
||||
|
||||
int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&i2cconfig_args);
|
||||
/* Check "--clear" option */
|
||||
@@ -578,12 +579,10 @@ static int do_i2cconfig_cmd(int argc, char **argv)
|
||||
if ((err = i2c_master_driver_initialize(argv[0], &conf)) == ESP_OK) {
|
||||
if ((err = i2c_master_driver_install(argv[0])) != ESP_OK) {
|
||||
nerrors++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fprintf(f, "i2c driver successfully started.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
@@ -602,8 +601,7 @@ static int do_i2cconfig_cmd(int argc, char **argv)
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
static int do_i2cdump_cmd(int argc, char **argv)
|
||||
{
|
||||
static int do_i2cdump_cmd(int argc, char** argv) {
|
||||
int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&i2cdump_args);
|
||||
if (nerrors != 0) {
|
||||
return 1;
|
||||
@@ -617,7 +615,8 @@ static int do_i2cdump_cmd(int argc, char **argv)
|
||||
size = i2cdump_args.size->ival[0];
|
||||
}
|
||||
i2c_port_t loc_i2c_port = i2c_port;
|
||||
if (i2cset_args.port->count && i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) != ESP_OK) {
|
||||
if (i2cset_args.port->count &&
|
||||
i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) != ESP_OK) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -691,8 +690,8 @@ static int do_i2cdump_cmd(int argc, char **argv)
|
||||
FREE_AND_NULL(buf);
|
||||
return 0;
|
||||
}
|
||||
static int do_i2cset_cmd(int argc, char **argv)
|
||||
{
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
static int do_i2cset_cmd(int argc, char** argv) {
|
||||
int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&i2cset_args);
|
||||
if (nerrors != 0) {
|
||||
return 1;
|
||||
@@ -707,7 +706,8 @@ static int do_i2cset_cmd(int argc, char **argv)
|
||||
}
|
||||
|
||||
i2c_port_t loc_i2c_port = i2c_port;
|
||||
if (i2cset_args.port->count && i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) != ESP_OK) {
|
||||
if (i2cset_args.port->count &&
|
||||
i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) != ESP_OK) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -737,9 +737,8 @@ static int do_i2cset_cmd(int argc, char **argv)
|
||||
// i2c_driver_delete(i2c_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_i2cget_cmd(int argc, char **argv)
|
||||
{
|
||||
#endif
|
||||
static int do_i2cget_cmd(int argc, char** argv) {
|
||||
int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&i2cget_args);
|
||||
if (nerrors != 0) {
|
||||
return 1;
|
||||
@@ -758,7 +757,8 @@ static int do_i2cget_cmd(int argc, char **argv)
|
||||
len = i2cget_args.data_length->ival[0];
|
||||
}
|
||||
i2c_port_t loc_i2c_port = i2c_port;
|
||||
if (i2cset_args.port->count && i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) != ESP_OK) {
|
||||
if (i2cset_args.port->count &&
|
||||
i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) != ESP_OK) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -846,6 +846,10 @@ esp_err_t cmd_i2ctools_scan_bus(FILE *f,int sda, int scl){
|
||||
fprintf(f, "I2C driver install failed %s\n", esp_err_to_name(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_WITH_CONFIG_UI
|
||||
fprintf(f, "\n 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
||||
#endif
|
||||
for (int i = 0; i < 128; i++) {
|
||||
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
@@ -855,31 +859,44 @@ esp_err_t cmd_i2ctools_scan_bus(FILE *f,int sda, int scl){
|
||||
ret = i2c_master_cmd_begin(i2c_port, cmd, 50 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret == ESP_OK) {
|
||||
#ifndef CONFIG_WITH_CONFIG_UI
|
||||
fprintf(f, "%02x ", i);
|
||||
#endif
|
||||
matches[++last_match - 1] = i;
|
||||
}
|
||||
#ifndef CONFIG_WITH_CONFIG_UI
|
||||
else if (ret == ESP_ERR_TIMEOUT) {
|
||||
fprintf(f, "UU ");
|
||||
} else {
|
||||
fprintf(f, "-- ");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
i2c_driver_delete(i2c_port);
|
||||
|
||||
if (last_match) {
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
fprintf(f, "i2c device detected (names provided by https://i2cdevices.org/addresses).\n");
|
||||
for (int i = 0; i < last_match; i++) {
|
||||
fprintf(f, "%u [%02xh]- %s\n", matches[i], matches[i], i2c_get_description(matches[i]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
} else {
|
||||
fprintf(f, "No i2c devices found with scl-%d and sda-%d\n", scl, sda);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int do_i2cdetect_cmd(int argc, char **argv)
|
||||
{
|
||||
static int do_i2cdetect_cmd(int argc, char** argv) {
|
||||
uint8_t matches[128] = {};
|
||||
int last_match = 0;
|
||||
esp_err_t ret = ESP_OK;
|
||||
i2c_port_t loc_i2c_port = i2c_port;
|
||||
if (i2cset_args.port->count && i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) != ESP_OK) {
|
||||
return 1;
|
||||
}
|
||||
// if (i2cset_args.port->count && i2c_get_port(i2cset_args.port->ival[0], &loc_i2c_port) !=
|
||||
// ESP_OK) { return 1;
|
||||
// }
|
||||
int i2c_port;
|
||||
const i2c_config_t* i2c = config_i2c_get(&i2c_port);
|
||||
|
||||
uint8_t address;
|
||||
char* buf = NULL;
|
||||
@@ -890,6 +907,10 @@ static int do_i2cdetect_cmd(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!GPIO_IS_VALID_OUTPUT_GPIO(i2c->scl_io_num) || !GPIO_IS_VALID_GPIO(i2c->scl_io_num) ||
|
||||
!GPIO_IS_VALID_OUTPUT_GPIO(i2c->sda_io_num) || !GPIO_IS_VALID_GPIO(i2c->sda_io_num)) {
|
||||
fprintf(f, "I2C bus configuration invalid.\r\n");
|
||||
} else {
|
||||
|
||||
fprintf(f, "\n 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
||||
for (int i = 0; i < 128; i += 16) {
|
||||
@@ -913,19 +934,24 @@ static int do_i2cdetect_cmd(int argc, char **argv)
|
||||
}
|
||||
|
||||
fprintf(f, "\r\n");
|
||||
|
||||
}
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
if (last_match) {
|
||||
fprintf(f,"\r\n------------------------------------------------------------------------------------"
|
||||
"\r\nDetected the following devices (names provided by https://i2cdevices.org/addresses).");
|
||||
fprintf(f, "\r\n-----------------------------------------------------------------------"
|
||||
"-------------"
|
||||
"\r\nDetected the following devices (names provided by "
|
||||
"https://i2cdevices.org/addresses).");
|
||||
|
||||
for (int i = 0; i < last_match; i++) {
|
||||
// printf("%02x = %s\r\n", matches[i], i2c_get_description(matches[i]));
|
||||
fprintf(f,"\r\n%u [%02xh]- %s", matches[i], matches[i], i2c_get_description(matches[i]));
|
||||
fprintf(f, "\r\n%u [%02xh]- %s", matches[i], matches[i],
|
||||
i2c_get_description(matches[i]));
|
||||
}
|
||||
fprintf(f,"\r\n------------------------------------------------------------------------------------\r\n");
|
||||
fprintf(f, "\r\n-----------------------------------------------------------------------"
|
||||
"-------------\r\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fflush(f);
|
||||
cmd_send_messaging(argv[0], MESSAGING_INFO, "%s", buf);
|
||||
fclose(f);
|
||||
@@ -978,6 +1004,7 @@ cJSON * i2c_set_display_cb(){
|
||||
return values;
|
||||
}
|
||||
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
static void register_i2c_set_display() {
|
||||
char* supported_drivers = display_get_supported_drivers();
|
||||
|
||||
@@ -987,9 +1014,11 @@ static void register_i2c_set_display(){
|
||||
i2cdisp_args.reset = arg_int0(NULL, "reset", "<n>", "Reset GPIO");
|
||||
i2cdisp_args.hflip = arg_lit0(NULL, "hf", "Flip horizontally");
|
||||
i2cdisp_args.vflip = arg_lit0(NULL, "vf", "Flip vertically");
|
||||
i2cdisp_args.driver = arg_str0("d", "driver", supported_drivers?supported_drivers:"<string>", "Driver");
|
||||
i2cdisp_args.driver =
|
||||
arg_str0("d", "driver", supported_drivers ? supported_drivers : "<string>", "Driver");
|
||||
i2cdisp_args.cs = arg_int0("b", "cs", "<n>", "SPI Only. CS GPIO (for SPI displays)");
|
||||
i2cdisp_args.speed = arg_int0("s", "speed", "<n>","SPI Only. Bus Speed (Default 8000000). SPI interface can work up to 26MHz~40MHz");
|
||||
i2cdisp_args.speed = arg_int0("s", "speed", "<n>",
|
||||
"SPI Only. Bus Speed (Default 8000000). SPI interface can work up to 26MHz~40MHz");
|
||||
i2cdisp_args.back = arg_int0("b", "back", "<n>", "Backlight GPIO (if applicable)");
|
||||
i2cdisp_args.depth = arg_int0("p", "depth", "-1|1|4", "Bit Depth (only for SSD1326 displays)");
|
||||
i2cdisp_args.type = arg_str0("t", "type", "<I2C|SPI>", "Interface (default I2C)");
|
||||
@@ -998,82 +1027,76 @@ static void register_i2c_set_display(){
|
||||
i2cdisp_args.clear = arg_lit0(NULL, "clear", "clear configuration and return");
|
||||
i2cdisp_args.mode = arg_int0("m", "mode", "<n>", "SPI Only. Transaction Line Mode (Default 0)");
|
||||
i2cdisp_args.end = arg_end(8);
|
||||
const esp_console_cmd_t i2c_set_display= {
|
||||
.command = CFG_TYPE_HW("display"),
|
||||
const esp_console_cmd_t i2c_set_display = {.command = CFG_TYPE_HW("display"),
|
||||
.help = desc_display,
|
||||
.hint = NULL,
|
||||
.func = &do_i2c_set_display,
|
||||
.argtable = &i2cdisp_args
|
||||
};
|
||||
.argtable = &i2cdisp_args};
|
||||
cmd_to_json_with_cb(&i2c_set_display, &i2c_set_display_cb);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&i2c_set_display));
|
||||
}
|
||||
static void register_i2cdectect(void)
|
||||
{
|
||||
const esp_console_cmd_t i2cdetect_cmd = {
|
||||
.command = "i2cdetect",
|
||||
#endif
|
||||
static void register_i2cdectect(void) {
|
||||
const esp_console_cmd_t i2cdetect_cmd = {.command = "i2cdetect",
|
||||
.help = "Scan I2C bus for devices",
|
||||
.hint = NULL,
|
||||
.func = &do_i2cdetect_cmd,
|
||||
.argtable = NULL
|
||||
};
|
||||
.argtable = NULL};
|
||||
cmd_to_json(&i2cdetect_cmd);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&i2cdetect_cmd));
|
||||
}
|
||||
|
||||
static void register_i2cget(void)
|
||||
{
|
||||
i2cget_args.chip_address = arg_int1("c", "chip", "<chip_addr>", "Specify the address of the chip on that bus");
|
||||
i2cget_args.register_address = arg_int0("r", "register", "<register_addr>", "Specify the address on that chip to read from");
|
||||
i2cget_args.data_length = arg_int0("l", "length", "<length>", "Specify the length to read from that data address");
|
||||
static void register_i2cget(void) {
|
||||
i2cget_args.chip_address =
|
||||
arg_int1("c", "chip", "<chip_addr>", "Specify the address of the chip on that bus");
|
||||
i2cget_args.register_address = arg_int0(
|
||||
"r", "register", "<register_addr>", "Specify the address on that chip to read from");
|
||||
i2cget_args.data_length =
|
||||
arg_int0("l", "length", "<length>", "Specify the length to read from that data address");
|
||||
i2cget_args.end = arg_end(1);
|
||||
const esp_console_cmd_t i2cget_cmd = {
|
||||
.command = "i2cget",
|
||||
const esp_console_cmd_t i2cget_cmd = {.command = "i2cget",
|
||||
.help = "Read registers visible through the I2C bus",
|
||||
.hint = NULL,
|
||||
.func = &do_i2cget_cmd,
|
||||
.argtable = &i2cget_args
|
||||
};
|
||||
.argtable = &i2cget_args};
|
||||
cmd_to_json(&i2cget_cmd);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&i2cget_cmd));
|
||||
}
|
||||
|
||||
static void register_i2cset(void)
|
||||
{
|
||||
i2cset_args.chip_address = arg_int1("c", "chip", "<chip_addr>", "Specify the address of the chip on that bus");
|
||||
i2cset_args.register_address = arg_int0("r", "register", "<register_addr>", "Specify the address on that chip to read from");
|
||||
i2cset_args.data = arg_intn(NULL, NULL, "<data>", 0, 256, "Specify the data to write to that data address");
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
static void register_i2cset(void) {
|
||||
i2cset_args.chip_address =
|
||||
arg_int1("c", "chip", "<chip_addr>", "Specify the address of the chip on that bus");
|
||||
i2cset_args.register_address = arg_int0(
|
||||
"r", "register", "<register_addr>", "Specify the address on that chip to read from");
|
||||
i2cset_args.data =
|
||||
arg_intn(NULL, NULL, "<data>", 0, 256, "Specify the data to write to that data address");
|
||||
i2cset_args.port = arg_intn("p", "port", "<n>", 0, 1, "Specify the i2c port (0|2)");
|
||||
|
||||
i2cset_args.end = arg_end(2);
|
||||
const esp_console_cmd_t i2cset_cmd = {
|
||||
.command = "i2cset",
|
||||
const esp_console_cmd_t i2cset_cmd = {.command = "i2cset",
|
||||
.help = "Set registers visible through the I2C bus",
|
||||
.hint = NULL,
|
||||
.func = &do_i2cset_cmd,
|
||||
.argtable = &i2cset_args
|
||||
};
|
||||
.argtable = &i2cset_args};
|
||||
cmd_to_json(&i2cset_cmd);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&i2cset_cmd));
|
||||
}
|
||||
|
||||
static void register_i2cdump(void)
|
||||
{
|
||||
i2cdump_args.chip_address = arg_int1("c", "chip", "<chip_addr>", "Specify the address of the chip on that bus");
|
||||
#endif
|
||||
static void register_i2cdump(void) {
|
||||
i2cdump_args.chip_address =
|
||||
arg_int1("c", "chip", "<chip_addr>", "Specify the address of the chip on that bus");
|
||||
i2cdump_args.size = arg_int0("s", "size", "<size>", "Specify the size of each read");
|
||||
i2cdump_args.end = arg_end(3);
|
||||
const esp_console_cmd_t i2cdump_cmd = {
|
||||
.command = "i2cdump",
|
||||
const esp_console_cmd_t i2cdump_cmd = {.command = "i2cdump",
|
||||
.help = "Examine registers visible through the I2C bus",
|
||||
.hint = NULL,
|
||||
.func = &do_i2cdump_cmd,
|
||||
.argtable = &i2cdump_args
|
||||
};
|
||||
.argtable = &i2cdump_args};
|
||||
cmd_to_json(&i2cdump_cmd);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&i2cdump_cmd));
|
||||
}
|
||||
|
||||
|
||||
cJSON* i2config_cb() {
|
||||
cJSON* values = cJSON_CreateObject();
|
||||
int i2c_port;
|
||||
@@ -1109,9 +1132,8 @@ cJSON * spiconfig_cb(){
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
static void register_spiconfig(void)
|
||||
{
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
static void register_spiconfig(void) {
|
||||
spiconfig_args.clear = arg_lit0(NULL, "clear", "Clear configuration");
|
||||
spiconfig_args.clk = arg_int0("k", "clk", "<n>", "Clock GPIO");
|
||||
spiconfig_args.data = arg_int0("d", "data", "<n>", "Data OUT GPIO");
|
||||
@@ -1119,42 +1141,41 @@ static void register_spiconfig(void)
|
||||
spiconfig_args.dc = arg_int0("c", "dc", "<n>", "DC GPIO");
|
||||
spiconfig_args.host = arg_int0("h", "host", "1|2", "SPI Host Number");
|
||||
spiconfig_args.end = arg_end(4);
|
||||
const esp_console_cmd_t spiconfig_cmd = {
|
||||
.command = CFG_TYPE_HW("spi"),
|
||||
const esp_console_cmd_t spiconfig_cmd = {.command = CFG_TYPE_HW("spi"),
|
||||
.help = desc_spiconfig,
|
||||
.hint = NULL,
|
||||
.func = &do_spiconfig_cmd,
|
||||
.argtable = &spiconfig_args
|
||||
};
|
||||
.argtable = &spiconfig_args};
|
||||
cmd_to_json_with_cb(&spiconfig_cmd, &spiconfig_cb);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&spiconfig_cmd));
|
||||
}
|
||||
static void register_i2cconfig(void)
|
||||
{
|
||||
#endif
|
||||
static void register_i2cconfig(void) {
|
||||
i2cconfig_args.clear = arg_lit0(NULL, "clear", "Clear configuration");
|
||||
i2cconfig_args.port = arg_int0("p", "port", "0|1", "Port");
|
||||
i2cconfig_args.freq = arg_int0("f", "speed", "int", "Frequency (Hz) e.g. 100000");
|
||||
i2cconfig_args.sda = arg_int0("d", "sda", "<n>", "SDA GPIO. e.g. 19");
|
||||
i2cconfig_args.scl = arg_int0("c", "scl", "<n>", "SCL GPIO. e.g. 18");
|
||||
i2cconfig_args.end = arg_end(4);
|
||||
const esp_console_cmd_t i2cconfig_cmd = {
|
||||
.command = CFG_TYPE_HW("i2c"),
|
||||
const esp_console_cmd_t i2cconfig_cmd = {.command = CFG_TYPE_HW("i2c"),
|
||||
.help = desc_i2c,
|
||||
.hint = NULL,
|
||||
.func = &do_i2cconfig_cmd,
|
||||
.argtable = &i2cconfig_args
|
||||
};
|
||||
.argtable = &i2cconfig_args};
|
||||
cmd_to_json_with_cb(&i2cconfig_cmd, &i2config_cb);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&i2cconfig_cmd));
|
||||
}
|
||||
|
||||
void register_i2ctools(void)
|
||||
{
|
||||
void register_i2ctools(void) {
|
||||
register_i2cconfig();
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
register_spiconfig();
|
||||
#endif
|
||||
register_i2cdectect();
|
||||
register_i2cget();
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
register_i2cset();
|
||||
register_i2cdump();
|
||||
register_i2c_set_display();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -589,6 +589,7 @@ void register_nvs()
|
||||
.func = &list_entries,
|
||||
.argtable = &list_args
|
||||
};
|
||||
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("registering list_entries_cmd");
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&list_entries_cmd));
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("registering set_cmd");
|
||||
|
||||
@@ -62,7 +62,7 @@ static int perform_ota_update(int argc, char **argv)
|
||||
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "update",
|
||||
.help = "Updates the application binary from the provided URL",
|
||||
.help = "Update from URL",
|
||||
.hint = NULL,
|
||||
.func = &perform_ota_update,
|
||||
.argtable = &ota_args
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include "messaging.h"
|
||||
#include "platform_console.h"
|
||||
#include "tools.h"
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
#include "Metrics.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
|
||||
#pragma message("Runtime stats enabled")
|
||||
@@ -73,24 +76,42 @@ static void register_set_services();
|
||||
static void register_tasks();
|
||||
#endif
|
||||
extern BaseType_t network_manager_task;
|
||||
FILE * system_open_memstream(const char * cmdname,char **buf,size_t *buf_size){
|
||||
FILE *f = open_memstream(buf, buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(cmdname,MESSAGING_ERROR,"Unable to open memory stream.");
|
||||
}
|
||||
return f;
|
||||
}
|
||||
void register_system()
|
||||
{
|
||||
register_free();
|
||||
|
||||
register_set_services();
|
||||
register_setdevicename();
|
||||
register_free();
|
||||
register_heap();
|
||||
register_dump_heap();
|
||||
register_setdevicename();
|
||||
register_version();
|
||||
register_restart();
|
||||
register_deep_sleep();
|
||||
register_light_sleep();
|
||||
register_factory_boot();
|
||||
register_restart_ota();
|
||||
#if WITH_TASKS_INFO
|
||||
register_tasks();
|
||||
#endif
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
register_deep_sleep();
|
||||
register_light_sleep();
|
||||
#endif
|
||||
}
|
||||
void simple_restart()
|
||||
{
|
||||
log_send_messaging(MESSAGING_WARNING,"Rebooting.");
|
||||
if(!wait_for_commit()){
|
||||
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
|
||||
}
|
||||
vTaskDelay(750/ portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
/* 'version' command */
|
||||
static int get_version(int argc, char **argv)
|
||||
{
|
||||
@@ -128,36 +149,23 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
|
||||
{
|
||||
if(is_recovery_running){
|
||||
if(partition_subtype ==ESP_PARTITION_SUBTYPE_APP_FACTORY){
|
||||
log_send_messaging(MESSAGING_WARNING,"RECOVERY application is already active");
|
||||
if(!wait_for_commit()){
|
||||
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
|
||||
}
|
||||
|
||||
vTaskDelay(750/ portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
return ESP_OK;
|
||||
// log_send_messaging(MESSAGING_WARNING,"RECOVERY application is already active");
|
||||
simple_restart();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(partition_subtype !=ESP_PARTITION_SUBTYPE_APP_FACTORY){
|
||||
log_send_messaging(MESSAGING_WARNING,"SQUEEZELITE application is already active");
|
||||
if(!wait_for_commit()){
|
||||
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
|
||||
}
|
||||
|
||||
vTaskDelay(750/ portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
return ESP_OK;
|
||||
// log_send_messaging(MESSAGING_WARNING,"SQUEEZELITE application is already active");
|
||||
simple_restart();
|
||||
}
|
||||
}
|
||||
esp_err_t err = ESP_OK;
|
||||
bool bFound=false;
|
||||
log_send_messaging(MESSAGING_INFO, "Looking for partition type %u",partition_subtype);
|
||||
// log_send_messaging(MESSAGING_INFO, "Looking for partition type %u",partition_subtype);
|
||||
const esp_partition_t *partition;
|
||||
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP, partition_subtype, NULL);
|
||||
|
||||
if(it == NULL){
|
||||
log_send_messaging(MESSAGING_ERROR,"Reboot failed. Cannot iterate through partitions");
|
||||
log_send_messaging(MESSAGING_ERROR,"Reboot failed. Partitions error");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -166,15 +174,11 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
|
||||
ESP_LOGD(TAG, "Releasing partition iterator");
|
||||
esp_partition_iterator_release(it);
|
||||
if(partition != NULL){
|
||||
log_send_messaging(MESSAGING_INFO, "Found application partition %s sub type %u", partition->label,partition_subtype);
|
||||
log_send_messaging(MESSAGING_INFO, "Rebooting to %s", partition->label);
|
||||
err=esp_ota_set_boot_partition(partition);
|
||||
if(err!=ESP_OK){
|
||||
bFound=false;
|
||||
log_send_messaging(MESSAGING_ERROR,"Unable to select partition for reboot: %s",esp_err_to_name(err));
|
||||
}
|
||||
else{
|
||||
bFound=true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -183,13 +187,7 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
|
||||
}
|
||||
ESP_LOGD(TAG, "Yielding to other processes");
|
||||
taskYIELD();
|
||||
if(bFound) {
|
||||
if(!wait_for_commit()){
|
||||
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration changes. ");
|
||||
}
|
||||
vTaskDelay(750/ portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
}
|
||||
simple_restart();
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
@@ -197,46 +195,31 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
|
||||
|
||||
static int restart(int argc, char **argv)
|
||||
{
|
||||
log_send_messaging(MESSAGING_WARNING, "\n\nPerforming a simple restart to the currently active partition.");
|
||||
if(!wait_for_commit()){
|
||||
cmd_send_messaging(argv[0],MESSAGING_WARNING,"Unable to commit configuration. ");
|
||||
}
|
||||
vTaskDelay(750/ portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
simple_restart();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void simple_restart()
|
||||
{
|
||||
log_send_messaging(MESSAGING_WARNING,"System reboot requested.");
|
||||
if(!wait_for_commit()){
|
||||
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
|
||||
}
|
||||
|
||||
|
||||
vTaskDelay(750/ portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
esp_err_t guided_restart_ota(){
|
||||
log_send_messaging(MESSAGING_WARNING,"System reboot to Application requested");
|
||||
log_send_messaging(MESSAGING_WARNING,"Booting to Squeezelite");
|
||||
guided_boot(ESP_PARTITION_SUBTYPE_APP_OTA_0);
|
||||
return ESP_FAIL; // return fail. This should never return... we're rebooting!
|
||||
}
|
||||
esp_err_t guided_factory(){
|
||||
log_send_messaging(MESSAGING_WARNING,"System reboot to recovery requested");
|
||||
log_send_messaging(MESSAGING_WARNING,"Booting to recovery");
|
||||
guided_boot(ESP_PARTITION_SUBTYPE_APP_FACTORY);
|
||||
return ESP_FAIL; // return fail. This should never return... we're rebooting!
|
||||
}
|
||||
static int restart_factory(int argc, char **argv)
|
||||
{
|
||||
cmd_send_messaging(argv[0],MESSAGING_WARNING, "Executing guided boot into recovery");
|
||||
cmd_send_messaging(argv[0],MESSAGING_WARNING, "Booting to Recovery");
|
||||
guided_boot(ESP_PARTITION_SUBTYPE_APP_FACTORY);
|
||||
return 0; // return fail. This should never return... we're rebooting!
|
||||
}
|
||||
static int restart_ota(int argc, char **argv)
|
||||
{
|
||||
cmd_send_messaging(argv[0],MESSAGING_WARNING, "Executing guided boot into ota app 0");
|
||||
cmd_send_messaging(argv[0],MESSAGING_WARNING, "Booting to Squeezelite");
|
||||
guided_boot(ESP_PARTITION_SUBTYPE_APP_OTA_0);
|
||||
return 0; // return fail. This should never return... we're rebooting!
|
||||
}
|
||||
@@ -248,7 +231,9 @@ static void register_restart()
|
||||
.hint = NULL,
|
||||
.func = &restart,
|
||||
};
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
cmd_to_json(&cmd);
|
||||
#endif
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||
}
|
||||
static void register_restart_ota()
|
||||
@@ -259,7 +244,9 @@ static void register_restart_ota()
|
||||
.hint = NULL,
|
||||
.func = &restart_ota,
|
||||
};
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
cmd_to_json(&cmd);
|
||||
#endif
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||
}
|
||||
|
||||
@@ -271,7 +258,9 @@ static void register_factory_boot()
|
||||
.hint = NULL,
|
||||
.func = &restart_factory,
|
||||
};
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
cmd_to_json(&cmd);
|
||||
#endif
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||
}
|
||||
/** 'free' command prints available heap memory */
|
||||
@@ -287,11 +276,14 @@ static void register_free()
|
||||
{
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "free",
|
||||
.help = "Get the current size of free heap memory",
|
||||
.help = "Get free heap memory",
|
||||
.hint = NULL,
|
||||
.func = &free_mem,
|
||||
};
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
cmd_to_json(&cmd);
|
||||
#endif
|
||||
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||
}
|
||||
static int dump_heap(int argc, char **argv)
|
||||
@@ -303,16 +295,16 @@ static int dump_heap(int argc, char **argv)
|
||||
/* 'heap' command prints minumum heap size */
|
||||
static int heap_size(int argc, char **argv)
|
||||
{
|
||||
ESP_LOGI(TAG,"Heap internal:%zu (min:%zu) (largest block:%zu)\nexternal:%zu (min:%zu) (largest block:%zd)\ndma :%zu (min:%zu) (largest block:%zd)",
|
||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||
heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL),
|
||||
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
||||
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||
heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM),
|
||||
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA),
|
||||
heap_caps_get_largest_free_block(MALLOC_CAP_DMA));
|
||||
// ESP_LOGI(TAG,"Heap internal:%zu (min:%zu) (largest block:%zu)\nexternal:%zu (min:%zu) (largest block:%zd)\ndma :%zu (min:%zu) (largest block:%zd)",
|
||||
// heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||
// heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||
// heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL),
|
||||
// heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
||||
// heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||
// heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM),
|
||||
// heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||
// heap_caps_get_minimum_free_size(MALLOC_CAP_DMA),
|
||||
// heap_caps_get_largest_free_block(MALLOC_CAP_DMA));
|
||||
cmd_send_messaging(argv[0],MESSAGING_INFO,"Heap internal:%zu (min:%zu) (largest block:%zu)\nexternal:%zu (min:%zu) (largest block:%zd)\ndma :%zu (min:%zu) (largest block:%zd)",
|
||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||
@@ -457,9 +449,8 @@ static int setdevicename(int argc, char **argv)
|
||||
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.");
|
||||
return 1;
|
||||
}
|
||||
nerrors+=setnamevar("a2dp_dev_name", f, name);
|
||||
@@ -488,11 +479,13 @@ static void register_heap()
|
||||
{
|
||||
const esp_console_cmd_t heap_cmd = {
|
||||
.command = "heap",
|
||||
.help = "Get minimum size of free heap memory found during execution",
|
||||
.help = "Get minimum size of free heap memory",
|
||||
.hint = NULL,
|
||||
.func = &heap_size,
|
||||
};
|
||||
#if CONFIG_WITH_CONFIG_UI
|
||||
cmd_to_json(&heap_cmd);
|
||||
#endif
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&heap_cmd) );
|
||||
|
||||
}
|
||||
@@ -521,6 +514,7 @@ static void register_setdevicename()
|
||||
.func = &setdevicename,
|
||||
.argtable = &name_args
|
||||
};
|
||||
|
||||
cmd_to_json_with_cb(&set_name,&setdevicename_cb);
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&set_name));
|
||||
}
|
||||
@@ -618,9 +612,7 @@ static void register_deep_sleep()
|
||||
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "deep_sleep",
|
||||
.help = "Enter deep sleep mode. "
|
||||
"Two wakeup modes are supported: timer and GPIO. "
|
||||
"If no wakeup option is specified, will sleep indefinitely.",
|
||||
.help = "Enter deep sleep mode. ",
|
||||
.hint = NULL,
|
||||
.func = &deep_sleep,
|
||||
.argtable = &deep_sleep_args
|
||||
@@ -649,9 +641,8 @@ static int do_set_services(int argc, char **argv)
|
||||
}
|
||||
char *buf = NULL;
|
||||
size_t buf_size = 0;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
|
||||
if (f == NULL) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -674,7 +665,7 @@ static int do_set_services(int argc, char **argv)
|
||||
|
||||
if(err!=ESP_OK){
|
||||
nerrors++;
|
||||
fprintf(f,"Error setting telnet service to %s. %s\n",set_services_args.telnet->sval[0], esp_err_to_name(err));
|
||||
fprintf(f,"Error setting telnet to %s. %s\n",set_services_args.telnet->sval[0], esp_err_to_name(err));
|
||||
}
|
||||
else {
|
||||
fprintf(f,"Telnet service changed to %s\n",set_services_args.telnet->sval[0]);
|
||||
@@ -706,7 +697,6 @@ cJSON * set_services_cb(){
|
||||
#if WITH_TASKS_INFO
|
||||
console_set_bool_parameter(values,"stats",set_services_args.stats);
|
||||
#endif
|
||||
|
||||
if ((p = config_alloc_get(NVS_TYPE_STR, "telnet_enable")) != NULL) {
|
||||
if(strcasestr("YX",p)!=NULL){
|
||||
cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet Only");
|
||||
@@ -717,7 +707,9 @@ cJSON * set_services_cb(){
|
||||
else {
|
||||
cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Disabled");
|
||||
}
|
||||
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_add_feature_variant("telnet",p);
|
||||
#endif
|
||||
FREE_AND_NULL(p);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ void register_system();
|
||||
esp_err_t guided_factory();
|
||||
esp_err_t guided_restart_ota();
|
||||
void simple_restart();
|
||||
|
||||
FILE * system_open_memstream(const char * cmdname,char **buf,size_t *buf_size);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,9 @@ extern bool bypass_network_manager;
|
||||
#define JOIN_TIMEOUT_MS (10000)
|
||||
#include "platform_console.h"
|
||||
|
||||
// To enable wifi configuration from the command line, uncomment the line below
|
||||
// define WIFI_CMDLINE 1
|
||||
|
||||
|
||||
extern EventGroupHandle_t network_event_group;
|
||||
extern const int CONNECTED_BIT;
|
||||
@@ -53,13 +56,6 @@ static struct {
|
||||
|
||||
// todo: implement access point config - cmd_to_json(&i2cdetect_cmd);
|
||||
|
||||
|
||||
///** Arguments used by 'join' function */
|
||||
//static struct {
|
||||
// struct arg_int *autoconnect;
|
||||
// struct arg_end *end;
|
||||
//} auto_connect_args;
|
||||
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
@@ -72,27 +68,7 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
xEventGroupSetBits(network_event_group, CONNECTED_BIT);
|
||||
}
|
||||
}
|
||||
//bool wait_for_wifi(){
|
||||
//
|
||||
// bool connected=(xEventGroupGetBits(wifi_event_group) & CONNECTED_BIT)!=0;
|
||||
//
|
||||
// if(!connected){
|
||||
// ESP_LOGD(TAG,"Waiting for WiFi...");
|
||||
// connected = (xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
|
||||
// pdFALSE, pdTRUE, JOIN_TIMEOUT_MS / portTICK_PERIOD_MS)& CONNECTED_BIT)!=0;
|
||||
// if(!connected){
|
||||
// ESP_LOGD(TAG,"wifi timeout.");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ESP_LOGI(TAG,"WiFi Connected!");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return connected;
|
||||
//
|
||||
//}
|
||||
|
||||
static void initialise_wifi(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
@@ -204,8 +180,10 @@ void register_wifi_join()
|
||||
|
||||
void register_wifi()
|
||||
{
|
||||
#ifdef WIFI_CMDLINE
|
||||
register_wifi_join();
|
||||
if(bypass_network_manager){
|
||||
initialise_wifi();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
#include "platform_config.h"
|
||||
#include "telnet.h"
|
||||
#include "tools.h"
|
||||
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
#include "metrics.h"
|
||||
#endif
|
||||
#include "messaging.h"
|
||||
|
||||
#include "config.h"
|
||||
@@ -85,14 +87,22 @@ cJSON * get_cmd_list(){
|
||||
}
|
||||
void console_set_bool_parameter(cJSON * root,char * nvs_name, struct arg_lit *arg){
|
||||
char * p=NULL;
|
||||
bool enabled = false;
|
||||
if(!root) {
|
||||
ESP_LOGE(TAG,"Invalid json parameter. Cannot set %s from %s",arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary,nvs_name);
|
||||
return;
|
||||
}
|
||||
if ((p = config_alloc_get(NVS_TYPE_STR, nvs_name)) != NULL) {
|
||||
cJSON_AddBoolToObject(root,arg->hdr.longopts,strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0);
|
||||
enabled = strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0;
|
||||
cJSON_AddBoolToObject(root,arg->hdr.longopts,enabled);
|
||||
FREE_AND_NULL(p);
|
||||
}
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
if(enabled){
|
||||
metrics_add_feature(nvs_name,"enabled");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
struct arg_end *getParmsEnd(struct arg_hdr * * argtable){
|
||||
if(!argtable) return NULL;
|
||||
@@ -360,8 +370,6 @@ void console_start() {
|
||||
register_system();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering config commands");
|
||||
register_config_cmd();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering nvs commands");
|
||||
register_nvs();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering wifi commands");
|
||||
register_wifi();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
idf_component_register(SRC_DIRS .
|
||||
INCLUDE_DIRS .
|
||||
REQUIRES json tools platform_config display wifi-manager
|
||||
REQUIRES json tools platform_config display wifi-manager esp-tls platform_config
|
||||
PRIV_REQUIRES soc esp32
|
||||
)
|
||||
|
||||
@@ -47,6 +47,7 @@ cJSON * gpio_list=NULL;
|
||||
#define STR(macro) QUOTE(macro)
|
||||
#endif
|
||||
|
||||
extern cJSON * get_gpio_list(bool refresh);
|
||||
bool are_statistics_enabled(){
|
||||
#if defined(CONFIG_FREERTOS_USE_TRACE_FACILITY) && defined (CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS)
|
||||
return true;
|
||||
@@ -592,7 +593,7 @@ const gpio_exp_config_t* config_gpio_exp_get(int index) {
|
||||
PARSE_PARAM(item, "intr", '=', config.intr);
|
||||
PARSE_PARAM(item, "base", '=', config.base);
|
||||
PARSE_PARAM(item, "count", '=', config.count);
|
||||
PARSE_PARAM_STR(item, "model", '=', config.model, 31);
|
||||
PARSE_PARAM_STR(item, "model", '=', config.model, sizeof(config.model)-1);
|
||||
|
||||
if ((p = strcasestr(item, "port")) != NULL) {
|
||||
char port[8] = "";
|
||||
@@ -646,6 +647,12 @@ const set_GPIO_struct_t * get_gpio_struct(){
|
||||
#endif
|
||||
#ifdef CONFIG_LED_RED_GPIO
|
||||
gpio_struct.red.gpio = CONFIG_LED_RED_GPIO;
|
||||
#endif
|
||||
#if defined(CONFIG_POWER_GPIO) && CONFIG_POWER_GPIO != -1
|
||||
gpio_struct.power.gpio = CONFIG_POWER_GPIO;
|
||||
#endif
|
||||
#ifdef CONFIG_POWER_GPIO_LEVEL
|
||||
gpio_struct.power.level = CONFIG_POWER_GPIO_LEVEL;
|
||||
#endif
|
||||
if(nvs_item){
|
||||
HANDLE_GPIO_STRUCT_MEMBER(amp,false);
|
||||
@@ -658,6 +665,7 @@ const set_GPIO_struct_t * get_gpio_struct(){
|
||||
HANDLE_GPIO_STRUCT_MEMBER(vcc,false);
|
||||
HANDLE_GPIO_STRUCT_MEMBER(gnd,false);
|
||||
HANDLE_GPIO_STRUCT_MEMBER(ir,false);
|
||||
HANDLE_GPIO_STRUCT_MEMBER(power,false);
|
||||
free(nvs_item);
|
||||
}
|
||||
|
||||
@@ -823,6 +831,7 @@ cJSON * get_GPIO_nvs_list(cJSON * list) {
|
||||
ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,jack,"other");
|
||||
ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,green,"other");
|
||||
ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,red,"other");
|
||||
ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,power,"other");
|
||||
ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,spkfault,"other");
|
||||
return ilist;
|
||||
}
|
||||
@@ -1169,7 +1178,7 @@ cJSON * get_psram_gpio_list(cJSON * list){
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
cJSON * get_gpio_list(bool refresh) {
|
||||
cJSON * get_gpio_list_handler(bool refresh) {
|
||||
gpio_num_t gpio_num;
|
||||
if(gpio_list && !refresh){
|
||||
return gpio_list;
|
||||
|
||||
@@ -73,6 +73,7 @@ typedef struct {
|
||||
gpio_with_level_t green;
|
||||
gpio_with_level_t red;
|
||||
gpio_with_level_t spkfault;
|
||||
gpio_with_level_t power;
|
||||
} set_GPIO_struct_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -117,7 +118,7 @@ bool is_spdif_config_locked();
|
||||
esp_err_t free_gpio_entry( gpio_entry_t ** gpio);
|
||||
gpio_entry_t * get_gpio_by_name(char * name,char * group, bool refresh);
|
||||
gpio_entry_t * get_gpio_by_no(int gpionum, bool refresh);
|
||||
cJSON * get_gpio_list(bool refresh);
|
||||
|
||||
bool is_dac_config_locked();
|
||||
bool are_statistics_enabled();
|
||||
const rotary_struct_t * config_rotary_get();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
idf_component_register( SRCS operator.cpp tools.c trace.c
|
||||
REQUIRES esp_common pthread
|
||||
PRIV_REQUIRES esp_http_client esp-tls
|
||||
PRIV_REQUIRES esp_http_client esp-tls json
|
||||
INCLUDE_DIRS .
|
||||
)
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#error CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS must be at least 2
|
||||
#endif
|
||||
|
||||
#include "cJSON.h"
|
||||
const static char TAG[] = "tools";
|
||||
|
||||
/****************************************************************************************
|
||||
@@ -318,11 +319,30 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
time_t millis() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void dump_json_content(const char* prefix, cJSON* json, int level) {
|
||||
if (!json) {
|
||||
ESP_LOG_LEVEL(level,TAG, "%s: empty!", prefix);
|
||||
return;
|
||||
}
|
||||
char* output = cJSON_Print(json);
|
||||
if (output) {
|
||||
ESP_LOG_LEVEL(level,TAG, "%s: \n%s", prefix, output);
|
||||
}
|
||||
FREE_AND_NULL(output);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "cJSON.h"
|
||||
#include "time.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -70,6 +74,9 @@ void vTaskDeleteEXTRAM(TaskHandle_t xTask);
|
||||
|
||||
extern const char unknown_string_placeholder[];
|
||||
|
||||
time_t millis();
|
||||
void dump_json_content(const char* prefix, cJSON* json, int level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,7 @@ typedef struct session_context {
|
||||
char * sess_ip_address;
|
||||
u16_t port;
|
||||
} session_context_t;
|
||||
|
||||
extern cJSON * get_gpio_list(bool refresh);
|
||||
|
||||
union sockaddr_aligned {
|
||||
struct sockaddr sa;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
idf_component_register(SRC_DIRS .
|
||||
PRIV_REQUIRES _override esp_common wifi-manager pthread squeezelite-ota platform_console telnet display targets led_strip
|
||||
PRIV_REQUIRES _override esp_common wifi-manager pthread squeezelite-ota platform_console telnet display targets led_strip metrics
|
||||
LDFRAGMENTS "linker.lf"
|
||||
)
|
||||
|
||||
@@ -74,6 +74,16 @@ menu "Squeezelite-ESP32"
|
||||
select I2C_LOCKED
|
||||
select TARGET_LOCKED
|
||||
endchoice
|
||||
config WITH_CONFIG_UI
|
||||
bool "Enable config UI"
|
||||
default n
|
||||
help
|
||||
Enable configuring system options with the UI
|
||||
config WITH_METRICS
|
||||
bool "Enable Metrics"
|
||||
default n
|
||||
help
|
||||
Enable capturing and reporting anonymous metrics
|
||||
config RELEASE_API
|
||||
string "Software update URL"
|
||||
default "https://api.github.com/repos/sle118/squeezelite-esp32/releases"
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
#include "accessors.h"
|
||||
#include "cmd_system.h"
|
||||
#include "tools.h"
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
#include "Metrics.h"
|
||||
#endif
|
||||
|
||||
const char unknown_string_placeholder[] = "unknown";
|
||||
const char null_string_placeholder[] = "null";
|
||||
@@ -68,7 +71,68 @@ bool cold_boot=true;
|
||||
extern const char _ctype_[];
|
||||
const char* __ctype_ptr__ = _ctype_;
|
||||
#endif
|
||||
typedef struct {
|
||||
const char *key;
|
||||
const char *value;
|
||||
} DefaultStringVal;
|
||||
typedef struct {
|
||||
const char *key;
|
||||
unsigned int uint_value;
|
||||
bool is_signed;
|
||||
} DefaultNumVal;
|
||||
|
||||
const DefaultNumVal defaultNumVals[] = {
|
||||
{"ota_erase_blk", OTA_FLASH_ERASE_BLOCK, 0},
|
||||
{"ota_stack", OTA_STACK_SIZE, 0},
|
||||
{"ota_prio", OTA_TASK_PRIOTITY, 1}
|
||||
};
|
||||
const DefaultStringVal defaultStringVals[] = {
|
||||
{"equalizer", ""},
|
||||
{"loudness", "0"},
|
||||
{"actrls_config", ""},
|
||||
{"lms_ctrls_raw", "n"},
|
||||
{"rotary_config", CONFIG_ROTARY_ENCODER},
|
||||
{"display_config", CONFIG_DISPLAY_CONFIG},
|
||||
{"eth_config", CONFIG_ETH_CONFIG},
|
||||
{"i2c_config", CONFIG_I2C_CONFIG},
|
||||
{"spi_config", CONFIG_SPI_CONFIG},
|
||||
{"set_GPIO", CONFIG_SET_GPIO},
|
||||
{"sleep_config", ""},
|
||||
{"led_brightness", ""},
|
||||
{"spdif_config", ""},
|
||||
{"dac_config", ""},
|
||||
{"dac_controlset", ""},
|
||||
{"jack_mutes_amp", "n"},
|
||||
{"gpio_exp_config", CONFIG_GPIO_EXP_CONFIG},
|
||||
{"bat_config", ""},
|
||||
{"metadata_config", ""},
|
||||
{"telnet_enable", ""},
|
||||
{"telnet_buffer", "40000"},
|
||||
{"telnet_block", "500"},
|
||||
{"stats", "n"},
|
||||
{"rel_api", CONFIG_RELEASE_API},
|
||||
{"pollmx", "600"},
|
||||
{"pollmin", "15"},
|
||||
{"ethtmout", "8"},
|
||||
{"dhcp_tmout", "8"},
|
||||
{"target", CONFIG_TARGET},
|
||||
{"led_vu_config", ""},
|
||||
#ifdef CONFIG_BT_SINK
|
||||
{"bt_sink_pin", STR(CONFIG_BT_SINK_PIN)},
|
||||
{"bt_sink_volume", "127"},
|
||||
// Note: register_default_with_mac("bt_name", CONFIG_BT_NAME); is a special case
|
||||
{"enable_bt_sink", STR(CONFIG_BT_SINK)},
|
||||
{"a2dp_dev_name", CONFIG_A2DP_DEV_NAME},
|
||||
{"a2dp_ctmt", STR(CONFIG_A2DP_CONNECT_TIMEOUT_MS)},
|
||||
{"a2dp_ctrld", STR(CONFIG_A2DP_CONTROL_DELAY_MS)},
|
||||
{"a2dp_sink_name", CONFIG_A2DP_SINK_NAME},
|
||||
{"autoexec", "1"},
|
||||
#ifdef CONFIG_AIRPLAY_SINK
|
||||
{"airplay_port", CONFIG_AIRPLAY_PORT},
|
||||
{"enable_airplay", STR(CONFIG_AIRPLAY_SINK)}
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
static bool bNetworkConnected=false;
|
||||
|
||||
// as an exception _init function don't need include
|
||||
@@ -80,7 +144,9 @@ extern void target_init(char *target);
|
||||
const char * str_or_unknown(const char * str) { return (str?str:unknown_string_placeholder); }
|
||||
const char * str_or_null(const char * str) { return (str?str:null_string_placeholder); }
|
||||
bool is_recovery_running;
|
||||
|
||||
bool is_network_connected(){
|
||||
return bNetworkConnected;
|
||||
}
|
||||
void cb_connection_got_ip(nm_state_t new_state, int sub_state){
|
||||
const char *hostname;
|
||||
static ip4_addr_t ip;
|
||||
@@ -163,7 +229,7 @@ void set_log_level(char * tag, char * level){
|
||||
}
|
||||
|
||||
#define DEFAULT_NAME_WITH_MAC(var,defval) char var[strlen(defval)+sizeof(macStr)]; strcpy(var,defval); strcat(var,macStr)
|
||||
void register_default_string_val(const char * key, char * value){
|
||||
void register_default_string_val(const char * key, const char * value){
|
||||
char * existing =(char *)config_alloc_get(NVS_TYPE_STR,key );
|
||||
ESP_LOGD(TAG,"Register default called with: %s= %s",key,value );
|
||||
if(!existing) {
|
||||
@@ -175,7 +241,15 @@ void register_default_string_val(const char * key, char * value){
|
||||
}
|
||||
FREE_AND_NULL(existing);
|
||||
}
|
||||
|
||||
void register_single_default_num_val(const DefaultNumVal *entry) {
|
||||
char number_buffer[101] = {};
|
||||
if (entry->is_signed) {
|
||||
snprintf(number_buffer, sizeof(number_buffer) - 1, "%d", entry->uint_value);
|
||||
} else {
|
||||
snprintf(number_buffer, sizeof(number_buffer) - 1, "%u", entry->uint_value);
|
||||
}
|
||||
register_default_string_val(entry->key, number_buffer);
|
||||
}
|
||||
char * alloc_get_string_with_mac(const char * val) {
|
||||
uint8_t mac[6];
|
||||
char macStr[LOCAL_MAC_SIZE + 1];
|
||||
@@ -188,7 +262,7 @@ char * alloc_get_string_with_mac(const char * val) {
|
||||
strcat(fullvalue, macStr);
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG,"Memory allocation failed when getting mac value for %s", val);
|
||||
ESP_LOGE(TAG,"malloc failed for value %s", val);
|
||||
}
|
||||
return fullvalue;
|
||||
|
||||
@@ -200,7 +274,7 @@ void register_default_with_mac(const char* key, char* defval) {
|
||||
FREE_AND_NULL(fullvalue);
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG,"Memory allocation failed when registering default value for %s", key);
|
||||
ESP_LOGE(TAG,"malloc failed for value %s", key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,70 +301,20 @@ void register_default_nvs(){
|
||||
|
||||
#ifdef CONFIG_AIRPLAY_SINK
|
||||
register_default_with_mac("airplay_name", CONFIG_AIRPLAY_NAME);
|
||||
register_default_string_val("airplay_port", CONFIG_AIRPLAY_PORT);
|
||||
register_default_string_val( "enable_airplay", STR(CONFIG_AIRPLAY_SINK));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_SINK
|
||||
register_default_string_val( "bt_sink_pin", STR(CONFIG_BT_SINK_PIN));
|
||||
register_default_string_val( "bt_sink_volume", "127");
|
||||
register_default_with_mac("bt_name", CONFIG_BT_NAME);
|
||||
register_default_string_val( "enable_bt_sink", STR(CONFIG_BT_SINK));
|
||||
register_default_string_val("a2dp_dev_name", CONFIG_A2DP_DEV_NAME);
|
||||
register_default_string_val("a2dp_ctmt", STR(CONFIG_A2DP_CONNECT_TIMEOUT_MS));
|
||||
register_default_string_val("a2dp_ctrld", STR(CONFIG_A2DP_CONTROL_DELAY_MS));
|
||||
register_default_string_val("a2dp_sink_name", CONFIG_A2DP_SINK_NAME);
|
||||
#endif
|
||||
|
||||
register_default_with_mac("host_name", DEFAULT_HOST_NAME);
|
||||
register_default_with_mac("ap_ssid", CONFIG_DEFAULT_AP_SSID);
|
||||
register_default_string_val("autoexec","1");
|
||||
register_default_with_mac("autoexec1",CONFIG_DEFAULT_COMMAND_LINE " -n " DEFAULT_HOST_NAME);
|
||||
for (int i = 0; i < sizeof(defaultStringVals) / sizeof(DefaultStringVal); ++i) {
|
||||
register_default_string_val(defaultStringVals[i].key, defaultStringVals[i].value);
|
||||
}
|
||||
for (int i = 0; i < sizeof(defaultNumVals) / sizeof(DefaultNumVal); ++i) {
|
||||
register_single_default_num_val(&defaultNumVals[i]);
|
||||
}
|
||||
|
||||
register_default_string_val("release_url", CONFIG_SQUEEZELITE_ESP32_RELEASE_URL);
|
||||
register_default_string_val("ap_ip_address",CONFIG_DEFAULT_AP_IP);
|
||||
register_default_string_val("ap_ip_gateway",CONFIG_DEFAULT_AP_GATEWAY );
|
||||
register_default_string_val("ap_ip_netmask",CONFIG_DEFAULT_AP_NETMASK);
|
||||
register_default_string_val("ap_channel",STR(CONFIG_DEFAULT_AP_CHANNEL));
|
||||
register_default_string_val("ap_pwd", CONFIG_DEFAULT_AP_PASSWORD);
|
||||
register_default_string_val("bypass_wm", "0");
|
||||
register_default_string_val("equalizer", "");
|
||||
register_default_string_val("loudness", "0");
|
||||
register_default_string_val("actrls_config", "");
|
||||
register_default_string_val("lms_ctrls_raw", "n");
|
||||
register_default_string_val("rotary_config", CONFIG_ROTARY_ENCODER);
|
||||
char number_buffer[101] = {};
|
||||
snprintf(number_buffer,sizeof(number_buffer)-1,"%u",OTA_FLASH_ERASE_BLOCK);
|
||||
register_default_string_val( "ota_erase_blk", number_buffer);
|
||||
snprintf(number_buffer,sizeof(number_buffer)-1,"%u",OTA_STACK_SIZE);
|
||||
register_default_string_val( "ota_stack", number_buffer);
|
||||
snprintf(number_buffer,sizeof(number_buffer)-1,"%d",OTA_TASK_PRIOTITY);
|
||||
register_default_string_val( "ota_prio", number_buffer);
|
||||
register_default_string_val( "display_config", CONFIG_DISPLAY_CONFIG);
|
||||
register_default_string_val( "eth_config", CONFIG_ETH_CONFIG);
|
||||
register_default_string_val( "i2c_config", CONFIG_I2C_CONFIG);
|
||||
register_default_string_val( "spi_config", CONFIG_SPI_CONFIG);
|
||||
register_default_string_val( "set_GPIO", CONFIG_SET_GPIO);
|
||||
register_default_string_val( "sleep_config", "");
|
||||
register_default_string_val( "led_brightness", "");
|
||||
register_default_string_val( "spdif_config", "");
|
||||
register_default_string_val( "dac_config", "");
|
||||
register_default_string_val( "dac_controlset", "");
|
||||
register_default_string_val( "jack_mutes_amp", "n");
|
||||
register_default_string_val("gpio_exp_config", CONFIG_GPIO_EXP_CONFIG);
|
||||
register_default_string_val( "bat_config", "");
|
||||
register_default_string_val( "metadata_config", "");
|
||||
register_default_string_val( "telnet_enable", "");
|
||||
register_default_string_val( "telnet_buffer", "40000");
|
||||
register_default_string_val( "telnet_block", "500");
|
||||
register_default_string_val( "stats", "n");
|
||||
register_default_string_val( "rel_api", CONFIG_RELEASE_API);
|
||||
register_default_string_val("pollmx","600");
|
||||
register_default_string_val("pollmin","15");
|
||||
register_default_string_val("ethtmout","8");
|
||||
register_default_string_val("dhcp_tmout","8");
|
||||
register_default_string_val("target", CONFIG_TARGET);
|
||||
register_default_string_val("led_vu_config", "");
|
||||
wait_for_commit();
|
||||
ESP_LOGD(TAG,"Done setting default values in nvs.");
|
||||
}
|
||||
@@ -303,7 +327,7 @@ uint32_t halSTORAGE_RebootCounterUpdate(int32_t xValue) {
|
||||
}
|
||||
RebootCounter = (xValue != 0) ? (RebootCounter + xValue) : 0;
|
||||
RecoveryRebootCounter = (xValue != 0) && is_recovery_running ? (RecoveryRebootCounter + xValue) : 0;
|
||||
return (RebootCounter) ;
|
||||
return RebootCounter ;
|
||||
}
|
||||
|
||||
void handle_ap_connect(nm_state_t new_state, int sub_state){
|
||||
@@ -356,11 +380,17 @@ void app_main()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char * fwurl = NULL;
|
||||
MEMTRACE_PRINT_DELTA();
|
||||
ESP_LOGI(TAG,"Starting app_main");
|
||||
initialize_nvs();
|
||||
MEMTRACE_PRINT_DELTA();
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
ESP_LOGI(TAG,"Setting up metrics.");
|
||||
metrics_init();
|
||||
MEMTRACE_PRINT_DELTA();
|
||||
#endif
|
||||
ESP_LOGI(TAG,"Setting up telnet.");
|
||||
init_telnet(); // align on 32 bits boundaries
|
||||
MEMTRACE_PRINT_DELTA();
|
||||
@@ -371,7 +401,6 @@ void app_main()
|
||||
network_event_group = xEventGroupCreate();
|
||||
ESP_LOGD(TAG,"Clearing CONNECTED_BIT from wifi group");
|
||||
xEventGroupClearBits(network_event_group, CONNECTED_BIT);
|
||||
|
||||
ESP_LOGI(TAG,"Registering default values");
|
||||
register_default_nvs();
|
||||
MEMTRACE_PRINT_DELTA();
|
||||
@@ -399,6 +428,9 @@ void app_main()
|
||||
led_vu_color_yellow(LED_VU_BRIGHT);
|
||||
}
|
||||
}
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_event_boot(is_recovery_running?"recovery":"ota");
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG,"Getting firmware OTA URL (if any)");
|
||||
fwurl = process_ota_url();
|
||||
@@ -457,6 +489,9 @@ void app_main()
|
||||
taskYIELD();
|
||||
}
|
||||
ESP_LOGI(TAG,"Updating firmware from link: %s",fwurl);
|
||||
#if defined(CONFIG_WITH_METRICS)
|
||||
metrics_event("fw_update");
|
||||
#endif
|
||||
start_ota(fwurl, NULL, 0);
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user