refactor(architecture): enforce component layering constraints
- move runtime policy/diag contracts to domain-owned facade and remove control_plane leapfrog usage - enforce single declaration point for direct debug config in domain public API (constraint #6) - harden timeout/idempotent semantics in REST/voice/printer/wifi/ble paths
This commit is contained in:
@@ -37,7 +37,7 @@ static void lifecycle_set_state_locked(controller_lifecycle_state_t state,
|
||||
s_status.last_error = last_error;
|
||||
s_status.last_transition_ms = esp_timer_get_time() / 1000;
|
||||
strlcpy(s_status.last_stage, stage != NULL ? stage : "unknown", sizeof(s_status.last_stage));
|
||||
runtime_diag_set_gauge(RUNTIME_DIAG_GAUGE_LIFECYCLE_STATE, (int32_t)state);
|
||||
domain_diag_set_gauge(DOMAIN_DIAG_GAUGE_LIFECYCLE_STATE, (int32_t)state);
|
||||
}
|
||||
|
||||
const char *controller_lifecycle_state_str(controller_lifecycle_state_t state) {
|
||||
@@ -87,7 +87,7 @@ static esp_err_t lifecycle_stop_voice(void) {
|
||||
}
|
||||
|
||||
static esp_err_t lifecycle_stop_printer_protocol(void) {
|
||||
esp_err_t rc = printer_protocol_stop(runtime_policy_printer_stop_timeout_ms());
|
||||
esp_err_t rc = printer_protocol_stop(domain_policy_printer_stop_timeout_ms());
|
||||
if (rc == ESP_OK || rc == ESP_ERR_INVALID_STATE) {
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -101,7 +101,7 @@ static esp_err_t lifecycle_stop_system_runtime(void) {
|
||||
typedef esp_err_t (*lifecycle_step_fn_t)(void);
|
||||
|
||||
static esp_err_t lifecycle_run_step_with_retry(const char *stage, lifecycle_step_fn_t fn) {
|
||||
uint32_t retry_count = runtime_policy_lifecycle_start_retry_count();
|
||||
uint32_t retry_count = domain_policy_lifecycle_start_retry_count();
|
||||
uint32_t max_attempts = retry_count + 1;
|
||||
|
||||
for (uint32_t attempt = 0; attempt < max_attempts; ++attempt) {
|
||||
@@ -113,7 +113,7 @@ static esp_err_t lifecycle_run_step_with_retry(const char *stage, lifecycle_step
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool can_retry = (attempt + 1 < max_attempts) && runtime_policy_is_retryable_error(rc);
|
||||
bool can_retry = (attempt + 1 < max_attempts) && domain_policy_is_retryable_error(rc);
|
||||
ESP_LOGW(TAG,
|
||||
"stage %s failed, rc=0x%x, attempt=%u/%u, retry=%d",
|
||||
stage,
|
||||
@@ -126,19 +126,19 @@ static esp_err_t lifecycle_run_step_with_retry(const char *stage, lifecycle_step
|
||||
return rc;
|
||||
}
|
||||
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_START_RETRY, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(runtime_policy_lifecycle_retry_backoff_ms(attempt)));
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_START_RETRY, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(domain_policy_lifecycle_retry_backoff_ms(attempt)));
|
||||
}
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t controller_lifecycle_start(void) {
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_START_ATTEMPT, 1);
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_START_ATTEMPT, 1);
|
||||
|
||||
if (!lifecycle_lock_take(1000)) {
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_START_FAILED, 1);
|
||||
runtime_diag_record_error("lifecycle_start", ESP_ERR_TIMEOUT, "lifecycle lock timeout");
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_START_FAILED, 1);
|
||||
domain_diag_record_error("lifecycle_start", ESP_ERR_TIMEOUT, "lifecycle lock timeout");
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ esp_err_t controller_lifecycle_start(void) {
|
||||
xSemaphoreGive(s_lock);
|
||||
}
|
||||
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_START_SUCCESS, 1);
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_START_SUCCESS, 1);
|
||||
ESP_LOGI(TAG, "controller lifecycle started");
|
||||
return ESP_OK;
|
||||
|
||||
@@ -220,8 +220,8 @@ start_failed:
|
||||
xSemaphoreGive(s_lock);
|
||||
}
|
||||
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_START_FAILED, 1);
|
||||
runtime_diag_record_error("lifecycle_start", rc, failed_stage);
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_START_FAILED, 1);
|
||||
domain_diag_record_error("lifecycle_start", rc, failed_stage);
|
||||
ESP_LOGE(TAG,
|
||||
"controller lifecycle start failed at stage=%s, rc=0x%x",
|
||||
failed_stage,
|
||||
@@ -230,11 +230,11 @@ start_failed:
|
||||
}
|
||||
|
||||
esp_err_t controller_lifecycle_stop(void) {
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_ATTEMPT, 1);
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_ATTEMPT, 1);
|
||||
|
||||
if (!lifecycle_lock_take(1000)) {
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_FAILED, 1);
|
||||
runtime_diag_record_error("lifecycle_stop", ESP_ERR_TIMEOUT, "lifecycle lock timeout");
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_FAILED, 1);
|
||||
domain_diag_record_error("lifecycle_stop", ESP_ERR_TIMEOUT, "lifecycle lock timeout");
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
@@ -283,11 +283,11 @@ esp_err_t controller_lifecycle_stop(void) {
|
||||
}
|
||||
|
||||
if (first_err == ESP_OK) {
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_SUCCESS, 1);
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_SUCCESS, 1);
|
||||
ESP_LOGI(TAG, "controller lifecycle stopped");
|
||||
} else {
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_FAILED, 1);
|
||||
runtime_diag_record_error("lifecycle_stop", first_err, "controller stop failed");
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_FAILED, 1);
|
||||
domain_diag_record_error("lifecycle_stop", first_err, "controller stop failed");
|
||||
ESP_LOGE(TAG, "controller lifecycle stop failed, rc=0x%x", (unsigned)first_err);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ esp_err_t rest_server_send_json(httpd_req_t *req, const char *status, cJSON *roo
|
||||
httpd_resp_set_status(req, status);
|
||||
esp_err_t err = httpd_resp_sendstr(req, text);
|
||||
cJSON_free(text);
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_REST_RESPONSES_TOTAL, 1);
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_REST_RESPONSES_TOTAL, 1);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ esp_err_t rest_server_send_error(httpd_req_t *req, const char *status, const cha
|
||||
cJSON_AddStringToObject(root, "error", message != NULL ? message : "unknown");
|
||||
esp_err_t err = rest_server_send_json(req, status, root);
|
||||
cJSON_Delete(root);
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_REST_ERRORS_TOTAL, 1);
|
||||
runtime_diag_record_error("rest_api", ESP_FAIL, message != NULL ? message : "unknown");
|
||||
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_REST_ERRORS_TOTAL, 1);
|
||||
domain_diag_record_error("rest_api", ESP_FAIL, message != NULL ? message : "unknown");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ static bool parse_printer_backend(const cJSON *json, printer_backend_t *out_back
|
||||
}
|
||||
|
||||
static void fill_runtime_diag_json(cJSON *root) {
|
||||
runtime_diag_snapshot_t snapshot = {0};
|
||||
runtime_diag_get_snapshot(&snapshot);
|
||||
domain_diag_snapshot_t snapshot = {0};
|
||||
domain_diag_get_snapshot(&snapshot);
|
||||
|
||||
cJSON *diag = cJSON_AddObjectToObject(root, "diagnostics");
|
||||
if (diag == NULL) {
|
||||
@@ -49,18 +49,18 @@ static void fill_runtime_diag_json(cJSON *root) {
|
||||
|
||||
cJSON *counters = cJSON_AddObjectToObject(diag, "counters");
|
||||
if (counters != NULL) {
|
||||
for (int i = 0; i < RUNTIME_DIAG_COUNTER_MAX; ++i) {
|
||||
for (int i = 0; i < DOMAIN_DIAG_COUNTER_MAX; ++i) {
|
||||
cJSON_AddNumberToObject(counters,
|
||||
runtime_diag_counter_name((runtime_diag_counter_t)i),
|
||||
domain_diag_counter_name((domain_diag_counter_t)i),
|
||||
(double)snapshot.counters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *gauges = cJSON_AddObjectToObject(diag, "gauges");
|
||||
if (gauges != NULL) {
|
||||
for (int i = 0; i < RUNTIME_DIAG_GAUGE_MAX; ++i) {
|
||||
for (int i = 0; i < DOMAIN_DIAG_GAUGE_MAX; ++i) {
|
||||
cJSON_AddNumberToObject(gauges,
|
||||
runtime_diag_gauge_name((runtime_diag_gauge_t)i),
|
||||
domain_diag_gauge_name((domain_diag_gauge_t)i),
|
||||
snapshot.gauges[i]);
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ esp_err_t rest_server_health_get(httpd_req_t *req) {
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
controller_lifecycle_status_t lifecycle = {0};
|
||||
controller_lifecycle_get_status(&lifecycle);
|
||||
bool healthy = (lifecycle.state == CONTROLLER_LIFECYCLE_STATE_RUNNING);
|
||||
bool healthy = (lifecycle.state == CONTROLLER_LIFECYCLE_STATE_RUNNING) && system_runtime_wifi_ready();
|
||||
cJSON_AddBoolToObject(root, "ok", healthy);
|
||||
fill_runtime_json(root);
|
||||
|
||||
@@ -155,7 +155,7 @@ esp_err_t rest_server_connect_post(httpd_req_t *req) {
|
||||
|
||||
char *body = NULL;
|
||||
char name[32] = "TQPrinter";
|
||||
uint32_t timeout_ms = runtime_policy_rest_printer_connect_timeout_ms();
|
||||
uint32_t timeout_ms = domain_policy_rest_printer_connect_timeout_ms();
|
||||
printer_backend_t backend = printer_protocol_get_backend();
|
||||
bool backend_specified = false;
|
||||
|
||||
@@ -177,8 +177,16 @@ esp_err_t rest_server_connect_post(httpd_req_t *req) {
|
||||
}
|
||||
|
||||
cJSON *jtimeout = cJSON_GetObjectItemCaseSensitive(json, "timeout_ms");
|
||||
if (cJSON_IsNumber(jtimeout) && jtimeout->valuedouble > 0) {
|
||||
timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
if (cJSON_IsNumber(jtimeout)) {
|
||||
uint32_t min_ms = domain_policy_rest_printer_connect_timeout_min_ms();
|
||||
uint32_t max_ms = domain_policy_rest_printer_connect_timeout_max_ms();
|
||||
if (jtimeout->valuedouble >= (double)min_ms && jtimeout->valuedouble <= (double)max_ms) {
|
||||
timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
} else {
|
||||
cJSON_Delete(json);
|
||||
free(body);
|
||||
return rest_server_send_error(req, "400 Bad Request", "timeout_ms out of range");
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *jbackend = cJSON_GetObjectItemCaseSensitive(json, "backend");
|
||||
@@ -490,7 +498,7 @@ esp_err_t rest_server_label_gap_move_post(httpd_req_t *req) {
|
||||
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
||||
}
|
||||
|
||||
uint32_t timeout_ms = runtime_policy_rest_label_timeout_ms();
|
||||
uint32_t timeout_ms = domain_policy_rest_label_timeout_ms();
|
||||
if (req->content_len > 0) {
|
||||
char *body = NULL;
|
||||
esp_err_t body_err = rest_server_read_body(req, &body);
|
||||
@@ -503,7 +511,13 @@ esp_err_t rest_server_label_gap_move_post(httpd_req_t *req) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid json");
|
||||
}
|
||||
cJSON *jtimeout = cJSON_GetObjectItemCaseSensitive(json, "timeout_ms");
|
||||
if (cJSON_IsNumber(jtimeout) && jtimeout->valuedouble > 0 && jtimeout->valuedouble <= 30000) {
|
||||
if (jtimeout != NULL) {
|
||||
if (!cJSON_IsNumber(jtimeout) ||
|
||||
jtimeout->valuedouble < (double)domain_policy_rest_label_timeout_min_ms() ||
|
||||
jtimeout->valuedouble > (double)domain_policy_rest_label_timeout_max_ms()) {
|
||||
cJSON_Delete(json);
|
||||
return rest_server_send_error(req, "400 Bad Request", "timeout_ms out of range");
|
||||
}
|
||||
timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
}
|
||||
cJSON_Delete(json);
|
||||
@@ -532,7 +546,7 @@ esp_err_t rest_server_label_offset_get(httpd_req_t *req) {
|
||||
uint8_t offset = 0;
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t rc = printer_protocol_get_label_offset(&offset,
|
||||
runtime_policy_rest_label_timeout_ms(),
|
||||
domain_policy_rest_label_timeout_ms(),
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
@@ -576,7 +590,7 @@ esp_err_t rest_server_label_offset_post(httpd_req_t *req) {
|
||||
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t rc = printer_protocol_set_label_offset(value,
|
||||
runtime_policy_rest_label_timeout_ms(),
|
||||
domain_policy_rest_label_timeout_ms(),
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
@@ -600,7 +614,7 @@ esp_err_t rest_server_ota_version_get(httpd_req_t *req) {
|
||||
printer_ota_version_t version = {0};
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t rc = printer_protocol_ota_get_version(&version,
|
||||
runtime_policy_rest_ota_timeout_ms(),
|
||||
domain_policy_rest_ota_timeout_ms(),
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
@@ -626,7 +640,7 @@ esp_err_t rest_server_ota_jump_boot_post(httpd_req_t *req) {
|
||||
}
|
||||
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t rc = printer_protocol_ota_jump_boot(runtime_policy_rest_ota_timeout_ms(),
|
||||
esp_err_t rc = printer_protocol_ota_jump_boot(domain_policy_rest_ota_timeout_ms(),
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
@@ -647,7 +661,7 @@ esp_err_t rest_server_ota_jump_app_post(httpd_req_t *req) {
|
||||
}
|
||||
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t rc = printer_protocol_ota_jump_app(runtime_policy_rest_ota_timeout_ms(),
|
||||
esp_err_t rc = printer_protocol_ota_jump_app(domain_policy_rest_ota_timeout_ms(),
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
@@ -685,8 +699,14 @@ esp_err_t rest_server_ota_erase_page_post(httpd_req_t *req) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "page_num must be 0..65535");
|
||||
}
|
||||
|
||||
uint32_t timeout_ms = runtime_policy_rest_ota_timeout_ms();
|
||||
if (cJSON_IsNumber(jtimeout) && jtimeout->valuedouble > 0 && jtimeout->valuedouble <= 30000) {
|
||||
uint32_t timeout_ms = domain_policy_rest_ota_timeout_ms();
|
||||
if (jtimeout != NULL) {
|
||||
if (!cJSON_IsNumber(jtimeout) ||
|
||||
jtimeout->valuedouble < (double)domain_policy_rest_ota_timeout_min_ms() ||
|
||||
jtimeout->valuedouble > (double)domain_policy_rest_ota_timeout_max_ms()) {
|
||||
cJSON_Delete(json);
|
||||
return rest_server_send_error(req, "400 Bad Request", "timeout_ms out of range");
|
||||
}
|
||||
timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
}
|
||||
|
||||
@@ -734,8 +754,14 @@ esp_err_t rest_server_ota_write_frame_post(httpd_req_t *req) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "packet_num and data are required");
|
||||
}
|
||||
|
||||
uint32_t timeout_ms = runtime_policy_rest_ota_timeout_ms();
|
||||
if (cJSON_IsNumber(jtimeout) && jtimeout->valuedouble > 0 && jtimeout->valuedouble <= 30000) {
|
||||
uint32_t timeout_ms = domain_policy_rest_ota_timeout_ms();
|
||||
if (jtimeout != NULL) {
|
||||
if (!cJSON_IsNumber(jtimeout) ||
|
||||
jtimeout->valuedouble < (double)domain_policy_rest_ota_timeout_min_ms() ||
|
||||
jtimeout->valuedouble > (double)domain_policy_rest_ota_timeout_max_ms()) {
|
||||
cJSON_Delete(json);
|
||||
return rest_server_send_error(req, "400 Bad Request", "timeout_ms out of range");
|
||||
}
|
||||
timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
}
|
||||
bool is_last = rest_server_json_bool_with_default(jlast, false);
|
||||
@@ -775,134 +801,7 @@ esp_err_t rest_server_ota_upgrade_post(httpd_req_t *req) {
|
||||
if (!rest_server_auth_ok(req)) {
|
||||
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
||||
}
|
||||
|
||||
char *body = NULL;
|
||||
esp_err_t body_err = rest_server_read_body(req, &body);
|
||||
if (body_err != ESP_OK) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
||||
}
|
||||
cJSON *json = cJSON_Parse(body);
|
||||
free(body);
|
||||
if (json == NULL) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid json");
|
||||
}
|
||||
|
||||
cJSON *jfirmware = cJSON_GetObjectItemCaseSensitive(json, "firmware");
|
||||
cJSON *jjumpboot = cJSON_GetObjectItemCaseSensitive(json, "jump_boot");
|
||||
cJSON *jjumpapp = cJSON_GetObjectItemCaseSensitive(json, "jump_app");
|
||||
cJSON *jpagesize = cJSON_GetObjectItemCaseSensitive(json, "page_size");
|
||||
cJSON *jpacketsize = cJSON_GetObjectItemCaseSensitive(json, "packet_size");
|
||||
cJSON *jtimeout = cJSON_GetObjectItemCaseSensitive(json, "timeout_ms_per_step");
|
||||
cJSON *jreadversion = cJSON_GetObjectItemCaseSensitive(json, "read_version_after");
|
||||
|
||||
if (!cJSON_IsString(jfirmware) || jfirmware->valuestring == NULL) {
|
||||
cJSON_Delete(json);
|
||||
return rest_server_send_error(req, "400 Bad Request", "firmware(base64) is required");
|
||||
}
|
||||
|
||||
bool jump_boot = rest_server_json_bool_with_default(jjumpboot, true);
|
||||
bool jump_app = rest_server_json_bool_with_default(jjumpapp, true);
|
||||
bool read_version_after = rest_server_json_bool_with_default(jreadversion, true);
|
||||
|
||||
uint16_t page_size = 1024;
|
||||
uint16_t packet_size = 236;
|
||||
uint32_t timeout_ms = runtime_policy_rest_ota_timeout_ms();
|
||||
if (cJSON_IsNumber(jpagesize) && jpagesize->valuedouble >= 256 && jpagesize->valuedouble <= 4096) {
|
||||
page_size = (uint16_t)jpagesize->valuedouble;
|
||||
}
|
||||
if (cJSON_IsNumber(jpacketsize) && jpacketsize->valuedouble >= 16 && jpacketsize->valuedouble <= 236) {
|
||||
packet_size = (uint16_t)jpacketsize->valuedouble;
|
||||
}
|
||||
if (cJSON_IsNumber(jtimeout) && jtimeout->valuedouble >= 500 && jtimeout->valuedouble <= 60000) {
|
||||
timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
}
|
||||
|
||||
uint8_t *firmware = NULL;
|
||||
size_t firmware_len = 0;
|
||||
esp_err_t b64_rc = rest_server_base64_decode_alloc(jfirmware->valuestring, &firmware, &firmware_len);
|
||||
cJSON_Delete(json);
|
||||
if (b64_rc != ESP_OK || firmware_len == 0) {
|
||||
free(firmware);
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid firmware base64");
|
||||
}
|
||||
|
||||
char cmd_err[128] = {0};
|
||||
if (jump_boot) {
|
||||
esp_err_t rc = printer_protocol_ota_jump_boot(timeout_ms, cmd_err, sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
free(firmware);
|
||||
return rest_server_send_error(req, "409 Conflict", cmd_err[0] != '\0' ? cmd_err : "jump boot failed");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t total_pages = (uint32_t)((firmware_len + page_size - 1) / page_size);
|
||||
for (uint32_t page = 0; page < total_pages; ++page) {
|
||||
esp_err_t rc = printer_protocol_ota_erase_page((uint16_t)page, timeout_ms, cmd_err, sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
free(firmware);
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
cmd_err[0] != '\0' ? cmd_err : "erase page failed");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t total_packets = (uint32_t)((firmware_len + packet_size - 1) / packet_size);
|
||||
for (uint32_t packet = 0; packet < total_packets; ++packet) {
|
||||
size_t start = (size_t)packet * packet_size;
|
||||
size_t remain = firmware_len - start;
|
||||
size_t len = remain > packet_size ? packet_size : remain;
|
||||
bool is_last = (packet + 1) == total_packets;
|
||||
|
||||
esp_err_t rc = printer_protocol_ota_write_frame((uint16_t)packet,
|
||||
is_last,
|
||||
firmware + start,
|
||||
len,
|
||||
timeout_ms,
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
free(firmware);
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
cmd_err[0] != '\0' ? cmd_err : "write frame failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (jump_app) {
|
||||
esp_err_t rc = printer_protocol_ota_jump_app(timeout_ms, cmd_err, sizeof(cmd_err));
|
||||
if (rc != ESP_OK) {
|
||||
free(firmware);
|
||||
return rest_server_send_error(req, "409 Conflict", cmd_err[0] != '\0' ? cmd_err : "jump app failed");
|
||||
}
|
||||
}
|
||||
|
||||
printer_ota_version_t version = {0};
|
||||
bool version_ok = false;
|
||||
if (read_version_after) {
|
||||
if (printer_protocol_ota_get_version(&version, timeout_ms, cmd_err, sizeof(cmd_err)) == ESP_OK) {
|
||||
version_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
free(firmware);
|
||||
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(root, "ok", true);
|
||||
cJSON_AddNumberToObject(root, "firmware_len", (double)firmware_len);
|
||||
cJSON_AddNumberToObject(root, "page_size", page_size);
|
||||
cJSON_AddNumberToObject(root, "packet_size", packet_size);
|
||||
cJSON_AddNumberToObject(root, "total_pages", total_pages);
|
||||
cJSON_AddNumberToObject(root, "total_packets", total_packets);
|
||||
cJSON_AddBoolToObject(root, "jump_boot", jump_boot);
|
||||
cJSON_AddBoolToObject(root, "jump_app", jump_app);
|
||||
if (version_ok) {
|
||||
cJSON *v = cJSON_AddObjectToObject(root, "version");
|
||||
cJSON_AddNumberToObject(v, "major", version.major);
|
||||
cJSON_AddNumberToObject(v, "minor", version.minor);
|
||||
cJSON_AddNumberToObject(v, "patch", version.patch);
|
||||
}
|
||||
|
||||
esp_err_t err = rest_server_send_json(req, "200 OK", root);
|
||||
cJSON_Delete(root);
|
||||
return err;
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
"bulk ota upgrade endpoint disabled; use jump/erase/write/version step APIs");
|
||||
}
|
||||
|
||||
@@ -244,8 +244,8 @@ static bool parse_image_generation_options(cJSON *json,
|
||||
}
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
out->timeout_ms = runtime_policy_image_generation_timeout_default_ms();
|
||||
out->fetch_timeout_ms = runtime_policy_image_download_timeout_default_ms();
|
||||
out->timeout_ms = domain_policy_image_generation_timeout_default_ms();
|
||||
out->fetch_timeout_ms = domain_policy_image_download_timeout_default_ms();
|
||||
|
||||
cJSON *jprompt = cJSON_GetObjectItemCaseSensitive(json, "prompt");
|
||||
if (!cJSON_IsString(jprompt) || jprompt->valuestring == NULL || jprompt->valuestring[0] == '\0') {
|
||||
@@ -304,14 +304,14 @@ static bool parse_image_generation_options(cJSON *json,
|
||||
|
||||
cJSON *jtimeout = cJSON_GetObjectItemCaseSensitive(json, "timeout_ms");
|
||||
if (cJSON_IsNumber(jtimeout)) {
|
||||
if (jtimeout->valuedouble < runtime_policy_image_generation_timeout_min_ms() ||
|
||||
jtimeout->valuedouble > runtime_policy_image_generation_timeout_max_ms()) {
|
||||
if (jtimeout->valuedouble < domain_policy_image_generation_timeout_min_ms() ||
|
||||
jtimeout->valuedouble > domain_policy_image_generation_timeout_max_ms()) {
|
||||
if (err != NULL && err_len > 0) {
|
||||
snprintf(err,
|
||||
err_len,
|
||||
"timeout_ms must be %u..%u",
|
||||
(unsigned)runtime_policy_image_generation_timeout_min_ms(),
|
||||
(unsigned)runtime_policy_image_generation_timeout_max_ms());
|
||||
(unsigned)domain_policy_image_generation_timeout_min_ms(),
|
||||
(unsigned)domain_policy_image_generation_timeout_max_ms());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -320,14 +320,14 @@ static bool parse_image_generation_options(cJSON *json,
|
||||
|
||||
cJSON *jfetch_timeout = cJSON_GetObjectItemCaseSensitive(json, "fetch_timeout_ms");
|
||||
if (cJSON_IsNumber(jfetch_timeout)) {
|
||||
if (jfetch_timeout->valuedouble < runtime_policy_image_download_timeout_min_ms() ||
|
||||
jfetch_timeout->valuedouble > runtime_policy_image_download_timeout_max_ms()) {
|
||||
if (jfetch_timeout->valuedouble < domain_policy_image_download_timeout_min_ms() ||
|
||||
jfetch_timeout->valuedouble > domain_policy_image_download_timeout_max_ms()) {
|
||||
if (err != NULL && err_len > 0) {
|
||||
snprintf(err,
|
||||
err_len,
|
||||
"fetch_timeout_ms must be %u..%u",
|
||||
(unsigned)runtime_policy_image_download_timeout_min_ms(),
|
||||
(unsigned)runtime_policy_image_download_timeout_max_ms());
|
||||
(unsigned)domain_policy_image_download_timeout_min_ms(),
|
||||
(unsigned)domain_policy_image_download_timeout_max_ms());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -266,28 +266,6 @@ esp_err_t rest_server_print_label_post(httpd_req_t *req) {
|
||||
offset_value = (uint8_t)joffset->valuedouble;
|
||||
}
|
||||
|
||||
if (has_offset) {
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t offset_rc = printer_protocol_set_label_offset(offset_value, 3000, cmd_err, sizeof(cmd_err));
|
||||
if (offset_rc != ESP_OK) {
|
||||
cJSON_Delete(json);
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
cmd_err[0] != '\0' ? cmd_err : "set label offset failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (gap_move_before) {
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t gap_rc = printer_protocol_gap_move(5000, cmd_err, sizeof(cmd_err));
|
||||
if (gap_rc != ESP_OK) {
|
||||
cJSON_Delete(json);
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
cmd_err[0] != '\0' ? cmd_err : "gap move failed");
|
||||
}
|
||||
}
|
||||
|
||||
const char *density = (cJSON_IsString(jdensity) && jdensity->valuestring != NULL)
|
||||
? jdensity->valuestring
|
||||
: "中等";
|
||||
@@ -312,6 +290,33 @@ esp_err_t rest_server_print_label_post(httpd_req_t *req) {
|
||||
decode_err[0] != '\0' ? decode_err : "decode image failed");
|
||||
}
|
||||
|
||||
if (has_offset) {
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t offset_rc = printer_protocol_set_label_offset(offset_value,
|
||||
domain_policy_rest_label_timeout_ms(),
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (offset_rc != ESP_OK) {
|
||||
free(raster);
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
cmd_err[0] != '\0' ? cmd_err : "set label offset failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (gap_move_before) {
|
||||
char cmd_err[128] = {0};
|
||||
esp_err_t gap_rc = printer_protocol_gap_move(domain_policy_rest_label_timeout_ms(),
|
||||
cmd_err,
|
||||
sizeof(cmd_err));
|
||||
if (gap_rc != ESP_OK) {
|
||||
free(raster);
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
cmd_err[0] != '\0' ? cmd_err : "gap move failed");
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t submit_rc = rest_server_print_submit_raster_job_and_reply(req,
|
||||
raster,
|
||||
raster_len,
|
||||
|
||||
@@ -4,6 +4,45 @@
|
||||
|
||||
#include "domain.h"
|
||||
|
||||
#define VOICE_CONTROL_TIMEOUT_MIN_MS 500
|
||||
#define VOICE_CONTROL_TIMEOUT_MAX_MS 30000
|
||||
|
||||
static esp_err_t rest_server_parse_voice_timeout(httpd_req_t *req, uint32_t *out_timeout_ms) {
|
||||
if (out_timeout_ms == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
*out_timeout_ms = 0;
|
||||
if (req->content_len <= 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
char *body = NULL;
|
||||
esp_err_t body_err = rest_server_read_body(req, &body);
|
||||
if (body_err != ESP_OK) {
|
||||
return body_err;
|
||||
}
|
||||
|
||||
cJSON *json = cJSON_Parse(body);
|
||||
free(body);
|
||||
if (json == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
cJSON *jtimeout = cJSON_GetObjectItemCaseSensitive(json, "timeout_ms");
|
||||
if (jtimeout != NULL) {
|
||||
if (!cJSON_IsNumber(jtimeout) ||
|
||||
jtimeout->valuedouble < VOICE_CONTROL_TIMEOUT_MIN_MS ||
|
||||
jtimeout->valuedouble > VOICE_CONTROL_TIMEOUT_MAX_MS) {
|
||||
cJSON_Delete(json);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
*out_timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void rest_server_add_voice_status(cJSON *root) {
|
||||
voice_interaction_status_t st = {0};
|
||||
voice_interaction_get_status(&st);
|
||||
@@ -48,18 +87,19 @@ esp_err_t rest_server_voice_session_start_post(httpd_req_t *req) {
|
||||
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
||||
}
|
||||
|
||||
if (req->content_len > 0) {
|
||||
char *body = NULL;
|
||||
esp_err_t body_err = rest_server_read_body(req, &body);
|
||||
if (body_err != ESP_OK) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
||||
}
|
||||
free(body);
|
||||
uint32_t timeout_ms = 0;
|
||||
if (rest_server_parse_voice_timeout(req, &timeout_ms) != ESP_OK) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
||||
}
|
||||
|
||||
char start_err[128] = {0};
|
||||
esp_err_t rc = voice_interaction_start(start_err, sizeof(start_err));
|
||||
esp_err_t rc = voice_interaction_start_with_timeout(timeout_ms, start_err, sizeof(start_err));
|
||||
if (rc != ESP_OK) {
|
||||
if (rc == ESP_ERR_TIMEOUT) {
|
||||
return rest_server_send_error(req,
|
||||
"504 Gateway Timeout",
|
||||
start_err[0] != '\0' ? start_err : "voice session start timeout");
|
||||
}
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
start_err[0] != '\0' ? start_err : "voice session start failed");
|
||||
@@ -80,18 +120,19 @@ esp_err_t rest_server_voice_session_stop_post(httpd_req_t *req) {
|
||||
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
||||
}
|
||||
|
||||
if (req->content_len > 0) {
|
||||
char *body = NULL;
|
||||
esp_err_t body_err = rest_server_read_body(req, &body);
|
||||
if (body_err != ESP_OK) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
||||
}
|
||||
free(body);
|
||||
uint32_t timeout_ms = 0;
|
||||
if (rest_server_parse_voice_timeout(req, &timeout_ms) != ESP_OK) {
|
||||
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
||||
}
|
||||
|
||||
char stop_err[128] = {0};
|
||||
esp_err_t rc = voice_interaction_stop(stop_err, sizeof(stop_err));
|
||||
esp_err_t rc = voice_interaction_stop_with_timeout(timeout_ms, stop_err, sizeof(stop_err));
|
||||
if (rc != ESP_OK) {
|
||||
if (rc == ESP_ERR_TIMEOUT) {
|
||||
return rest_server_send_error(req,
|
||||
"504 Gateway Timeout",
|
||||
stop_err[0] != '\0' ? stop_err : "voice session stop timeout");
|
||||
}
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
stop_err[0] != '\0' ? stop_err : "voice session stop failed");
|
||||
|
||||
@@ -9,6 +9,7 @@ idf_component_register(
|
||||
"src/image_generation.c"
|
||||
"src/screen_preview.c"
|
||||
"src/system_runtime.c"
|
||||
"src/domain_runtime_contracts.c"
|
||||
"src/voice_interaction.c"
|
||||
"src/voice_interaction_common.c"
|
||||
"src/voice_interaction_ws.c"
|
||||
@@ -19,9 +20,9 @@ idf_component_register(
|
||||
"third_party/qrcodegen.c"
|
||||
INCLUDE_DIRS
|
||||
"include"
|
||||
"third_party"
|
||||
PRIV_INCLUDE_DIRS
|
||||
"internal"
|
||||
"third_party"
|
||||
REQUIRES
|
||||
platform
|
||||
esp_http_client
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -19,6 +18,81 @@ esp_err_t system_runtime_bootstrap(void);
|
||||
bool system_runtime_wifi_ready(void);
|
||||
void system_runtime_get_ip(char *buf, size_t buf_len);
|
||||
|
||||
// ---------- domain_policy ----------
|
||||
uint32_t domain_policy_lifecycle_start_retry_count(void);
|
||||
uint32_t domain_policy_lifecycle_retry_backoff_ms(uint32_t attempt);
|
||||
bool domain_policy_is_retryable_error(esp_err_t err);
|
||||
|
||||
uint32_t domain_policy_printer_stop_timeout_ms(void);
|
||||
|
||||
uint32_t domain_policy_rest_printer_connect_timeout_ms(void);
|
||||
uint32_t domain_policy_rest_printer_connect_timeout_min_ms(void);
|
||||
uint32_t domain_policy_rest_printer_connect_timeout_max_ms(void);
|
||||
|
||||
uint32_t domain_policy_rest_label_timeout_ms(void);
|
||||
uint32_t domain_policy_rest_label_timeout_min_ms(void);
|
||||
uint32_t domain_policy_rest_label_timeout_max_ms(void);
|
||||
|
||||
uint32_t domain_policy_rest_ota_timeout_ms(void);
|
||||
uint32_t domain_policy_rest_ota_timeout_min_ms(void);
|
||||
uint32_t domain_policy_rest_ota_timeout_max_ms(void);
|
||||
|
||||
uint32_t domain_policy_image_generation_timeout_default_ms(void);
|
||||
uint32_t domain_policy_image_generation_timeout_min_ms(void);
|
||||
uint32_t domain_policy_image_generation_timeout_max_ms(void);
|
||||
|
||||
uint32_t domain_policy_image_download_timeout_default_ms(void);
|
||||
uint32_t domain_policy_image_download_timeout_min_ms(void);
|
||||
uint32_t domain_policy_image_download_timeout_max_ms(void);
|
||||
|
||||
// ---------- domain_diagnostics ----------
|
||||
typedef enum {
|
||||
DOMAIN_DIAG_COUNTER_LIFECYCLE_START_ATTEMPT = 0,
|
||||
DOMAIN_DIAG_COUNTER_LIFECYCLE_START_SUCCESS,
|
||||
DOMAIN_DIAG_COUNTER_LIFECYCLE_START_FAILED,
|
||||
DOMAIN_DIAG_COUNTER_LIFECYCLE_START_RETRY,
|
||||
DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_ATTEMPT,
|
||||
DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_SUCCESS,
|
||||
DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_FAILED,
|
||||
DOMAIN_DIAG_COUNTER_WIFI_CONNECT_SUCCESS,
|
||||
DOMAIN_DIAG_COUNTER_WIFI_CONNECT_FAILED,
|
||||
DOMAIN_DIAG_COUNTER_WIFI_CONNECT_TIMEOUT,
|
||||
DOMAIN_DIAG_COUNTER_PRINTER_JOB_SUBMITTED,
|
||||
DOMAIN_DIAG_COUNTER_PRINTER_JOB_SUCCESS,
|
||||
DOMAIN_DIAG_COUNTER_PRINTER_JOB_FAILED,
|
||||
DOMAIN_DIAG_COUNTER_PRINTER_JOB_CANCELED,
|
||||
DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_ATTEMPT,
|
||||
DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_SUCCESS,
|
||||
DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_FAILED,
|
||||
DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_TIMEOUT,
|
||||
DOMAIN_DIAG_COUNTER_REST_RESPONSES_TOTAL,
|
||||
DOMAIN_DIAG_COUNTER_REST_ERRORS_TOTAL,
|
||||
DOMAIN_DIAG_COUNTER_MAX,
|
||||
} domain_diag_counter_t;
|
||||
|
||||
typedef enum {
|
||||
DOMAIN_DIAG_GAUGE_LIFECYCLE_STATE = 0,
|
||||
DOMAIN_DIAG_GAUGE_STATUS_POLL_PAUSE_DEPTH,
|
||||
DOMAIN_DIAG_GAUGE_PRINTER_QUEUE_DEPTH,
|
||||
DOMAIN_DIAG_GAUGE_MAX,
|
||||
} domain_diag_gauge_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t counters[DOMAIN_DIAG_COUNTER_MAX];
|
||||
int32_t gauges[DOMAIN_DIAG_GAUGE_MAX];
|
||||
int64_t last_error_ms;
|
||||
esp_err_t last_error_code;
|
||||
char last_error_source[32];
|
||||
char last_error_message[96];
|
||||
} domain_diag_snapshot_t;
|
||||
|
||||
void domain_diag_counter_add(domain_diag_counter_t counter, uint32_t delta);
|
||||
void domain_diag_set_gauge(domain_diag_gauge_t gauge, int32_t value);
|
||||
void domain_diag_record_error(const char *source, esp_err_t code, const char *message);
|
||||
void domain_diag_get_snapshot(domain_diag_snapshot_t *out_snapshot);
|
||||
const char *domain_diag_counter_name(domain_diag_counter_t counter);
|
||||
const char *domain_diag_gauge_name(domain_diag_gauge_t gauge);
|
||||
|
||||
// ---------- raster_tools ----------
|
||||
esp_err_t raster_tools_render_text_384(const char *text,
|
||||
uint8_t scale,
|
||||
@@ -286,7 +360,9 @@ typedef struct {
|
||||
} voice_interaction_status_t;
|
||||
|
||||
esp_err_t voice_interaction_init(void);
|
||||
esp_err_t voice_interaction_start_with_timeout(uint32_t timeout_ms, char *err, size_t err_len);
|
||||
esp_err_t voice_interaction_start(char *err, size_t err_len);
|
||||
esp_err_t voice_interaction_stop_with_timeout(uint32_t timeout_ms, char *err, size_t err_len);
|
||||
esp_err_t voice_interaction_stop(char *err, size_t err_len);
|
||||
|
||||
esp_err_t voice_interaction_tap_start(char *err, size_t err_len);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "domain.h"
|
||||
#include "esp_err.h"
|
||||
#include "platform.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/queue.h"
|
||||
@@ -93,6 +94,7 @@ esp_err_t printer_protocol_send_cmd_wait_response(uint8_t cmd,
|
||||
bool with_checksum,
|
||||
uint32_t timeout_ms,
|
||||
bool expect_ack,
|
||||
bool reset_transport_on_timeout,
|
||||
uint8_t *out_payload,
|
||||
size_t out_payload_cap,
|
||||
uint16_t *out_payload_len,
|
||||
@@ -111,7 +113,8 @@ bool printer_protocol_send_cmd_with_ack(uint8_t cmd,
|
||||
const uint8_t *payload,
|
||||
uint16_t payload_len,
|
||||
bool with_checksum,
|
||||
uint32_t timeout_ms);
|
||||
uint32_t timeout_ms,
|
||||
bool reset_transport_on_timeout);
|
||||
|
||||
int printer_protocol_find_job_idx_locked(uint32_t id);
|
||||
int printer_protocol_alloc_job_slot_locked(void);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
#include "domain.h"
|
||||
#include "platform.h"
|
||||
|
||||
#define VOICE_STREAMING_MODE "duplex"
|
||||
#define VOICE_TASK_GROUP "aigc"
|
||||
|
||||
201
components/domain/src/domain_runtime_contracts.c
Normal file
201
components/domain/src/domain_runtime_contracts.c
Normal file
@@ -0,0 +1,201 @@
|
||||
#include "domain.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
static runtime_diag_counter_t to_platform_counter(domain_diag_counter_t counter) {
|
||||
switch (counter) {
|
||||
case DOMAIN_DIAG_COUNTER_LIFECYCLE_START_ATTEMPT:
|
||||
return RUNTIME_DIAG_COUNTER_LIFECYCLE_START_ATTEMPT;
|
||||
case DOMAIN_DIAG_COUNTER_LIFECYCLE_START_SUCCESS:
|
||||
return RUNTIME_DIAG_COUNTER_LIFECYCLE_START_SUCCESS;
|
||||
case DOMAIN_DIAG_COUNTER_LIFECYCLE_START_FAILED:
|
||||
return RUNTIME_DIAG_COUNTER_LIFECYCLE_START_FAILED;
|
||||
case DOMAIN_DIAG_COUNTER_LIFECYCLE_START_RETRY:
|
||||
return RUNTIME_DIAG_COUNTER_LIFECYCLE_START_RETRY;
|
||||
case DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_ATTEMPT:
|
||||
return RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_ATTEMPT;
|
||||
case DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_SUCCESS:
|
||||
return RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_SUCCESS;
|
||||
case DOMAIN_DIAG_COUNTER_LIFECYCLE_STOP_FAILED:
|
||||
return RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_FAILED;
|
||||
case DOMAIN_DIAG_COUNTER_WIFI_CONNECT_SUCCESS:
|
||||
return RUNTIME_DIAG_COUNTER_WIFI_CONNECT_SUCCESS;
|
||||
case DOMAIN_DIAG_COUNTER_WIFI_CONNECT_FAILED:
|
||||
return RUNTIME_DIAG_COUNTER_WIFI_CONNECT_FAILED;
|
||||
case DOMAIN_DIAG_COUNTER_WIFI_CONNECT_TIMEOUT:
|
||||
return RUNTIME_DIAG_COUNTER_WIFI_CONNECT_TIMEOUT;
|
||||
case DOMAIN_DIAG_COUNTER_PRINTER_JOB_SUBMITTED:
|
||||
return RUNTIME_DIAG_COUNTER_PRINTER_JOB_SUBMITTED;
|
||||
case DOMAIN_DIAG_COUNTER_PRINTER_JOB_SUCCESS:
|
||||
return RUNTIME_DIAG_COUNTER_PRINTER_JOB_SUCCESS;
|
||||
case DOMAIN_DIAG_COUNTER_PRINTER_JOB_FAILED:
|
||||
return RUNTIME_DIAG_COUNTER_PRINTER_JOB_FAILED;
|
||||
case DOMAIN_DIAG_COUNTER_PRINTER_JOB_CANCELED:
|
||||
return RUNTIME_DIAG_COUNTER_PRINTER_JOB_CANCELED;
|
||||
case DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_ATTEMPT:
|
||||
return RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_ATTEMPT;
|
||||
case DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_SUCCESS:
|
||||
return RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_SUCCESS;
|
||||
case DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_FAILED:
|
||||
return RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_FAILED;
|
||||
case DOMAIN_DIAG_COUNTER_IMAGE_GENERATE_TIMEOUT:
|
||||
return RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_TIMEOUT;
|
||||
case DOMAIN_DIAG_COUNTER_REST_RESPONSES_TOTAL:
|
||||
return RUNTIME_DIAG_COUNTER_REST_RESPONSES_TOTAL;
|
||||
case DOMAIN_DIAG_COUNTER_REST_ERRORS_TOTAL:
|
||||
return RUNTIME_DIAG_COUNTER_REST_ERRORS_TOTAL;
|
||||
default:
|
||||
return RUNTIME_DIAG_COUNTER_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static runtime_diag_gauge_t to_platform_gauge(domain_diag_gauge_t gauge) {
|
||||
switch (gauge) {
|
||||
case DOMAIN_DIAG_GAUGE_LIFECYCLE_STATE:
|
||||
return RUNTIME_DIAG_GAUGE_LIFECYCLE_STATE;
|
||||
case DOMAIN_DIAG_GAUGE_STATUS_POLL_PAUSE_DEPTH:
|
||||
return RUNTIME_DIAG_GAUGE_STATUS_POLL_PAUSE_DEPTH;
|
||||
case DOMAIN_DIAG_GAUGE_PRINTER_QUEUE_DEPTH:
|
||||
return RUNTIME_DIAG_GAUGE_PRINTER_QUEUE_DEPTH;
|
||||
default:
|
||||
return RUNTIME_DIAG_GAUGE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t domain_policy_lifecycle_start_retry_count(void) {
|
||||
return runtime_policy_lifecycle_start_retry_count();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_lifecycle_retry_backoff_ms(uint32_t attempt) {
|
||||
return runtime_policy_lifecycle_retry_backoff_ms(attempt);
|
||||
}
|
||||
|
||||
bool domain_policy_is_retryable_error(esp_err_t err) {
|
||||
return runtime_policy_is_retryable_error(err);
|
||||
}
|
||||
|
||||
uint32_t domain_policy_printer_stop_timeout_ms(void) {
|
||||
return runtime_policy_printer_stop_timeout_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_printer_connect_timeout_ms(void) {
|
||||
return runtime_policy_rest_printer_connect_timeout_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_printer_connect_timeout_min_ms(void) {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_printer_connect_timeout_max_ms(void) {
|
||||
return 60000;
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_label_timeout_ms(void) {
|
||||
return runtime_policy_rest_label_timeout_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_label_timeout_min_ms(void) {
|
||||
return 500;
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_label_timeout_max_ms(void) {
|
||||
return 30000;
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_ota_timeout_ms(void) {
|
||||
return runtime_policy_rest_ota_timeout_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_ota_timeout_min_ms(void) {
|
||||
return 500;
|
||||
}
|
||||
|
||||
uint32_t domain_policy_rest_ota_timeout_max_ms(void) {
|
||||
return 60000;
|
||||
}
|
||||
|
||||
uint32_t domain_policy_image_generation_timeout_default_ms(void) {
|
||||
return runtime_policy_image_generation_timeout_default_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_image_generation_timeout_min_ms(void) {
|
||||
return runtime_policy_image_generation_timeout_min_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_image_generation_timeout_max_ms(void) {
|
||||
return runtime_policy_image_generation_timeout_max_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_image_download_timeout_default_ms(void) {
|
||||
return runtime_policy_image_download_timeout_default_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_image_download_timeout_min_ms(void) {
|
||||
return runtime_policy_image_download_timeout_min_ms();
|
||||
}
|
||||
|
||||
uint32_t domain_policy_image_download_timeout_max_ms(void) {
|
||||
return runtime_policy_image_download_timeout_max_ms();
|
||||
}
|
||||
|
||||
void domain_diag_counter_add(domain_diag_counter_t counter, uint32_t delta) {
|
||||
runtime_diag_counter_t mapped = to_platform_counter(counter);
|
||||
if (mapped >= RUNTIME_DIAG_COUNTER_MAX) {
|
||||
return;
|
||||
}
|
||||
runtime_diag_counter_add(mapped, delta);
|
||||
}
|
||||
|
||||
void domain_diag_set_gauge(domain_diag_gauge_t gauge, int32_t value) {
|
||||
runtime_diag_gauge_t mapped = to_platform_gauge(gauge);
|
||||
if (mapped >= RUNTIME_DIAG_GAUGE_MAX) {
|
||||
return;
|
||||
}
|
||||
runtime_diag_set_gauge(mapped, value);
|
||||
}
|
||||
|
||||
void domain_diag_record_error(const char *source, esp_err_t code, const char *message) {
|
||||
runtime_diag_record_error(source, code, message);
|
||||
}
|
||||
|
||||
void domain_diag_get_snapshot(domain_diag_snapshot_t *out_snapshot) {
|
||||
if (out_snapshot == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
runtime_diag_snapshot_t platform_snapshot = {0};
|
||||
runtime_diag_get_snapshot(&platform_snapshot);
|
||||
|
||||
for (int i = 0; i < DOMAIN_DIAG_COUNTER_MAX && i < RUNTIME_DIAG_COUNTER_MAX; ++i) {
|
||||
out_snapshot->counters[i] = platform_snapshot.counters[i];
|
||||
}
|
||||
for (int i = 0; i < DOMAIN_DIAG_GAUGE_MAX && i < RUNTIME_DIAG_GAUGE_MAX; ++i) {
|
||||
out_snapshot->gauges[i] = platform_snapshot.gauges[i];
|
||||
}
|
||||
out_snapshot->last_error_ms = platform_snapshot.last_error_ms;
|
||||
out_snapshot->last_error_code = platform_snapshot.last_error_code;
|
||||
strlcpy(out_snapshot->last_error_source,
|
||||
platform_snapshot.last_error_source,
|
||||
sizeof(out_snapshot->last_error_source));
|
||||
strlcpy(out_snapshot->last_error_message,
|
||||
platform_snapshot.last_error_message,
|
||||
sizeof(out_snapshot->last_error_message));
|
||||
}
|
||||
|
||||
const char *domain_diag_counter_name(domain_diag_counter_t counter) {
|
||||
runtime_diag_counter_t mapped = to_platform_counter(counter);
|
||||
if (mapped >= RUNTIME_DIAG_COUNTER_MAX) {
|
||||
return "unknown";
|
||||
}
|
||||
return runtime_diag_counter_name(mapped);
|
||||
}
|
||||
|
||||
const char *domain_diag_gauge_name(domain_diag_gauge_t gauge) {
|
||||
runtime_diag_gauge_t mapped = to_platform_gauge(gauge);
|
||||
if (mapped >= RUNTIME_DIAG_GAUGE_MAX) {
|
||||
return "unknown";
|
||||
}
|
||||
return runtime_diag_gauge_name(mapped);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "domain.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -441,16 +441,30 @@ static bool wait_ack(uint8_t cmd, uint32_t timeout_ms) {
|
||||
return payload_len >= 1 && payload[0] == 0x01;
|
||||
}
|
||||
|
||||
static void reset_transport_after_timeout(void) {
|
||||
if (printer_protocol_is_stopping()) {
|
||||
return;
|
||||
}
|
||||
if (printer_protocol_get_backend() == PRINTER_BACKEND_BLE) {
|
||||
ble_printer_client_disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
bool printer_protocol_send_cmd_with_ack(uint8_t cmd,
|
||||
const uint8_t *payload,
|
||||
uint16_t payload_len,
|
||||
bool with_checksum,
|
||||
uint32_t timeout_ms) {
|
||||
uint32_t timeout_ms,
|
||||
bool reset_transport_on_timeout) {
|
||||
clear_ack_signal();
|
||||
if (printer_protocol_send_frame(cmd, payload, payload_len, with_checksum) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
return wait_ack(cmd, timeout_ms);
|
||||
bool ok = wait_ack(cmd, timeout_ms);
|
||||
if (!ok && reset_transport_on_timeout) {
|
||||
reset_transport_after_timeout();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
esp_err_t printer_protocol_send_cmd_wait_response(uint8_t cmd,
|
||||
@@ -459,6 +473,7 @@ esp_err_t printer_protocol_send_cmd_wait_response(uint8_t cmd,
|
||||
bool with_checksum,
|
||||
uint32_t timeout_ms,
|
||||
bool expect_ack,
|
||||
bool reset_transport_on_timeout,
|
||||
uint8_t *out_payload,
|
||||
size_t out_payload_cap,
|
||||
uint16_t *out_payload_len,
|
||||
@@ -475,14 +490,21 @@ esp_err_t printer_protocol_send_cmd_wait_response(uint8_t cmd,
|
||||
uint8_t rsp[252];
|
||||
uint16_t rsp_len = 0;
|
||||
if (!printer_protocol_wait_response(cmd, rsp, sizeof(rsp), &rsp_len, timeout_ms)) {
|
||||
bool stopping = printer_protocol_is_stopping();
|
||||
if (!stopping && reset_transport_on_timeout) {
|
||||
reset_transport_after_timeout();
|
||||
}
|
||||
if (err != NULL && err_len > 0) {
|
||||
if (printer_protocol_is_stopping()) {
|
||||
if (stopping) {
|
||||
snprintf(err, err_len, "protocol stopping");
|
||||
} else {
|
||||
snprintf(err, err_len, "response timeout");
|
||||
snprintf(err,
|
||||
err_len,
|
||||
reset_transport_on_timeout ? "response timeout, transport reset"
|
||||
: "response timeout");
|
||||
}
|
||||
}
|
||||
return printer_protocol_is_stopping() ? ESP_ERR_INVALID_STATE : ESP_ERR_TIMEOUT;
|
||||
return stopping ? ESP_ERR_INVALID_STATE : ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
if (expect_ack && (rsp_len < 1 || rsp[0] != 0x01)) {
|
||||
|
||||
@@ -44,6 +44,7 @@ esp_err_t printer_protocol_gap_move(uint32_t timeout_ms, char *err, size_t err_l
|
||||
true,
|
||||
timeout_ms,
|
||||
true,
|
||||
true,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
@@ -85,6 +86,7 @@ esp_err_t printer_protocol_get_label_offset(uint8_t *out_offset, uint32_t timeou
|
||||
true,
|
||||
timeout_ms,
|
||||
false,
|
||||
false,
|
||||
rsp,
|
||||
sizeof(rsp),
|
||||
&rsp_len,
|
||||
@@ -133,6 +135,7 @@ esp_err_t printer_protocol_set_label_offset(uint8_t offset, uint32_t timeout_ms,
|
||||
true,
|
||||
timeout_ms,
|
||||
true,
|
||||
true,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
@@ -164,6 +167,7 @@ esp_err_t printer_protocol_ota_jump_boot(uint32_t timeout_ms, char *err, size_t
|
||||
true,
|
||||
timeout_ms,
|
||||
true,
|
||||
true,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
@@ -195,6 +199,7 @@ esp_err_t printer_protocol_ota_jump_app(uint32_t timeout_ms, char *err, size_t e
|
||||
true,
|
||||
timeout_ms,
|
||||
true,
|
||||
true,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
@@ -231,6 +236,7 @@ esp_err_t printer_protocol_ota_erase_page(uint16_t page_num, uint32_t timeout_ms
|
||||
true,
|
||||
timeout_ms,
|
||||
true,
|
||||
true,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
@@ -283,6 +289,7 @@ esp_err_t printer_protocol_ota_write_frame(uint16_t packet_num,
|
||||
true,
|
||||
timeout_ms,
|
||||
true,
|
||||
true,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
@@ -326,6 +333,7 @@ esp_err_t printer_protocol_ota_get_version(printer_ota_version_t *out_version,
|
||||
true,
|
||||
timeout_ms,
|
||||
false,
|
||||
false,
|
||||
rsp,
|
||||
sizeof(rsp),
|
||||
&rsp_len,
|
||||
@@ -361,22 +369,19 @@ esp_err_t printer_protocol_get_direct_debug_config(printer_direct_debug_config_t
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
platform_direct_debug_config_t cfg = {0};
|
||||
esp_err_t rc = platform_direct_printer_get_debug_config(&cfg);
|
||||
esp_err_t rc = platform_direct_printer_get_debug_config(&out_config->shift_clock_high_us,
|
||||
&out_config->shift_clock_low_us,
|
||||
&out_config->latch_pulse_us,
|
||||
&out_config->strobe_active_high,
|
||||
&out_config->boost_active_high,
|
||||
&out_config->override_strobe_on_us,
|
||||
&out_config->override_strobe_interval_us,
|
||||
&out_config->override_motor_step_us,
|
||||
&out_config->override_steps_per_line);
|
||||
if (rc != ESP_OK) {
|
||||
write_err(err, err_len, "get direct debug config failed");
|
||||
return rc;
|
||||
}
|
||||
|
||||
out_config->shift_clock_high_us = cfg.shift_clock_high_us;
|
||||
out_config->shift_clock_low_us = cfg.shift_clock_low_us;
|
||||
out_config->latch_pulse_us = cfg.latch_pulse_us;
|
||||
out_config->strobe_active_high = cfg.strobe_active_high;
|
||||
out_config->boost_active_high = cfg.boost_active_high;
|
||||
out_config->override_strobe_on_us = cfg.override_strobe_on_us;
|
||||
out_config->override_strobe_interval_us = cfg.override_strobe_interval_us;
|
||||
out_config->override_motor_step_us = cfg.override_motor_step_us;
|
||||
out_config->override_steps_per_line = cfg.override_steps_per_line;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -393,22 +398,19 @@ esp_err_t printer_protocol_set_direct_debug_config(const printer_direct_debug_co
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
platform_direct_debug_config_t cfg = {0};
|
||||
platform_direct_debug_config_t *pcfg = NULL;
|
||||
if (config != NULL) {
|
||||
cfg.shift_clock_high_us = config->shift_clock_high_us;
|
||||
cfg.shift_clock_low_us = config->shift_clock_low_us;
|
||||
cfg.latch_pulse_us = config->latch_pulse_us;
|
||||
cfg.strobe_active_high = config->strobe_active_high;
|
||||
cfg.boost_active_high = config->boost_active_high;
|
||||
cfg.override_strobe_on_us = config->override_strobe_on_us;
|
||||
cfg.override_strobe_interval_us = config->override_strobe_interval_us;
|
||||
cfg.override_motor_step_us = config->override_motor_step_us;
|
||||
cfg.override_steps_per_line = config->override_steps_per_line;
|
||||
pcfg = &cfg;
|
||||
}
|
||||
|
||||
return platform_direct_printer_set_debug_config(pcfg, reset_defaults, err, err_len);
|
||||
return platform_direct_printer_set_debug_config(config != NULL,
|
||||
config != NULL ? config->shift_clock_high_us : 0,
|
||||
config != NULL ? config->shift_clock_low_us : 0,
|
||||
config != NULL ? config->latch_pulse_us : 0,
|
||||
config != NULL ? config->strobe_active_high : false,
|
||||
config != NULL ? config->boost_active_high : false,
|
||||
config != NULL ? config->override_strobe_on_us : 0,
|
||||
config != NULL ? config->override_strobe_interval_us : 0,
|
||||
config != NULL ? config->override_motor_step_us : 0,
|
||||
config != NULL ? config->override_steps_per_line : 0,
|
||||
reset_defaults,
|
||||
err,
|
||||
err_len);
|
||||
}
|
||||
|
||||
const char *printer_protocol_job_state_str(print_job_state_t state) {
|
||||
|
||||
@@ -164,7 +164,7 @@ static bool run_print_job_ble(job_slot_t *job) {
|
||||
}
|
||||
|
||||
uint8_t power_on = 0x01;
|
||||
if (!printer_protocol_send_cmd_with_ack(CMD_POWER, &power_on, 1, true, 1500)) {
|
||||
if (!printer_protocol_send_cmd_with_ack(CMD_POWER, &power_on, 1, true, 1500, true)) {
|
||||
snprintf(job->error, sizeof(job->error), "power on failed");
|
||||
ESP_LOGW(TAG, "job %u print aborted: %s", (unsigned)job->id, job->error);
|
||||
return false;
|
||||
@@ -178,7 +178,7 @@ static bool run_print_job_ble(job_slot_t *job) {
|
||||
(uint8_t)(hot_time & 0xFF),
|
||||
};
|
||||
|
||||
if (!printer_protocol_send_cmd_with_ack(CMD_SET_PARAM, param, sizeof(param), true, 1500)) {
|
||||
if (!printer_protocol_send_cmd_with_ack(CMD_SET_PARAM, param, sizeof(param), true, 1500, true)) {
|
||||
snprintf(job->error, sizeof(job->error), "set print param failed");
|
||||
ESP_LOGW(TAG, "job %u print aborted: %s", (unsigned)job->id, job->error);
|
||||
return false;
|
||||
@@ -217,7 +217,8 @@ static bool run_print_job_ble(job_slot_t *job) {
|
||||
&job->data[start],
|
||||
(uint16_t)chunk_len,
|
||||
false,
|
||||
2500)) {
|
||||
2500,
|
||||
true)) {
|
||||
snprintf(job->error, sizeof(job->error), "send chunk timeout at %u", (unsigned)i);
|
||||
ESP_LOGW(TAG, "job %u print aborted: %s", (unsigned)job->id, job->error);
|
||||
return false;
|
||||
@@ -245,10 +246,15 @@ static bool run_print_job_ble(job_slot_t *job) {
|
||||
ESP_LOGI(TAG, "job %u data transfer done", (unsigned)job->id);
|
||||
|
||||
uint8_t power_off = 0x00;
|
||||
(void)printer_protocol_send_cmd_with_ack(CMD_POWER, &power_off, 1, true, 1200);
|
||||
(void)printer_protocol_send_cmd_with_ack(CMD_POWER, &power_off, 1, true, 1200, false);
|
||||
|
||||
uint8_t feed_payload[3] = {0x2B, 0x00, 0x0C};
|
||||
(void)printer_protocol_send_cmd_with_ack(CMD_SET_DISTANCE, feed_payload, sizeof(feed_payload), true, 1200);
|
||||
(void)printer_protocol_send_cmd_with_ack(CMD_SET_DISTANCE,
|
||||
feed_payload,
|
||||
sizeof(feed_payload),
|
||||
true,
|
||||
1200,
|
||||
false);
|
||||
|
||||
ESP_LOGI(TAG, "job %u print command sequence done", (unsigned)job->id);
|
||||
return true;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "domain.h"
|
||||
#include "platform.h"
|
||||
|
||||
esp_err_t screen_preview_show_raster(const uint8_t *raster,
|
||||
size_t raster_len,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "domain.h"
|
||||
#include "platform.h"
|
||||
|
||||
esp_err_t system_runtime_start(void) {
|
||||
esp_err_t err = platform_bootstrap_init();
|
||||
|
||||
@@ -9,7 +9,18 @@
|
||||
|
||||
static const char *TAG = "voice_interaction";
|
||||
|
||||
static void voice_wait_worker_tasks_exit(uint32_t timeout_ms) {
|
||||
static uint32_t clamp_timeout_ms(uint32_t timeout_ms, uint32_t default_ms, uint32_t min_ms, uint32_t max_ms) {
|
||||
uint32_t value = timeout_ms == 0 ? default_ms : timeout_ms;
|
||||
if (value < min_ms) {
|
||||
value = min_ms;
|
||||
}
|
||||
if (value > max_ms) {
|
||||
value = max_ms;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static bool voice_wait_worker_tasks_exit(uint32_t timeout_ms) {
|
||||
int64_t deadline_ms = voice_now_ms() + (int64_t)timeout_ms;
|
||||
while (voice_now_ms() < deadline_ms) {
|
||||
bool uplink_alive = false;
|
||||
@@ -21,7 +32,7 @@ static void voice_wait_worker_tasks_exit(uint32_t timeout_ms) {
|
||||
}
|
||||
|
||||
if (!uplink_alive && !heartbeat_alive) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
@@ -33,6 +44,7 @@ static void voice_wait_worker_tasks_exit(uint32_t timeout_ms) {
|
||||
s_voice.heartbeat_task != NULL);
|
||||
voice_unlock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *voice_interaction_dialog_state_str(voice_dialog_state_t state) {
|
||||
@@ -68,7 +80,9 @@ esp_err_t voice_interaction_init(void) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t voice_interaction_start(char *err, size_t err_len) {
|
||||
esp_err_t voice_interaction_start_with_timeout(uint32_t timeout_ms, char *err, size_t err_len) {
|
||||
uint32_t connect_timeout_ms =
|
||||
clamp_timeout_ms(timeout_ms, VOICE_START_CONNECT_TIMEOUT_MS, 1000, 30000);
|
||||
ESP_LOGI(TAG, "[stage] session_start_enter");
|
||||
if (!s_voice.ready) {
|
||||
voice_fill_err(err, err_len, "voice interaction not initialized");
|
||||
@@ -260,8 +274,8 @@ esp_err_t voice_interaction_start(char *err, size_t err_len) {
|
||||
ESP_LOGI(TAG, "[stage] heartbeat_task_create_ok");
|
||||
voice_log_heap_snapshot("after_create_heartbeat");
|
||||
|
||||
ESP_LOGI(TAG, "[stage] wait_ws_connected_begin: timeout_ms=%d", VOICE_START_CONNECT_TIMEOUT_MS);
|
||||
int64_t deadline = voice_now_ms() + VOICE_START_CONNECT_TIMEOUT_MS;
|
||||
ESP_LOGI(TAG, "[stage] wait_ws_connected_begin: timeout_ms=%u", (unsigned)connect_timeout_ms);
|
||||
int64_t deadline = voice_now_ms() + connect_timeout_ms;
|
||||
while (voice_now_ms() < deadline) {
|
||||
bool connected = false;
|
||||
if (voice_lock(VOICE_STATUS_LOCK_TIMEOUT_MS)) {
|
||||
@@ -301,17 +315,22 @@ exit_err:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t voice_interaction_stop(char *err, size_t err_len) {
|
||||
(void)err;
|
||||
(void)err_len;
|
||||
esp_err_t voice_interaction_start(char *err, size_t err_len) {
|
||||
return voice_interaction_start_with_timeout(VOICE_START_CONNECT_TIMEOUT_MS, err, err_len);
|
||||
}
|
||||
|
||||
esp_err_t voice_interaction_stop_with_timeout(uint32_t timeout_ms, char *err, size_t err_len) {
|
||||
uint32_t worker_exit_timeout_ms = clamp_timeout_ms(timeout_ms, 1500, 500, 10000);
|
||||
ESP_LOGI(TAG, "[stage] session_stop_enter");
|
||||
|
||||
if (!s_voice.ready) {
|
||||
voice_fill_err(err, err_len, "voice interaction not initialized");
|
||||
ESP_LOGW(TAG, "[stage] session_stop_abort: not initialized");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!voice_lock(VOICE_STATUS_LOCK_TIMEOUT_MS)) {
|
||||
voice_fill_err(err, err_len, "voice lock timeout");
|
||||
ESP_LOGW(TAG, "[stage] session_stop_abort: lock timeout");
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
@@ -343,7 +362,16 @@ esp_err_t voice_interaction_stop(char *err, size_t err_len) {
|
||||
if (heartbeat_task != NULL) {
|
||||
(void)xTaskAbortDelay(heartbeat_task);
|
||||
}
|
||||
voice_wait_worker_tasks_exit(1500);
|
||||
bool workers_exited = voice_wait_worker_tasks_exit(worker_exit_timeout_ms);
|
||||
if (!workers_exited) {
|
||||
voice_fill_err(err, err_len, "voice worker exit timeout");
|
||||
if (voice_lock(VOICE_STATUS_LOCK_TIMEOUT_MS)) {
|
||||
voice_set_last_error_locked("worker exit timeout");
|
||||
voice_unlock();
|
||||
}
|
||||
ESP_LOGW(TAG, "[stage] session_stop_abort: workers still alive");
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
if (ws != NULL) {
|
||||
ESP_LOGI(TAG, "[stage] ws_stop_destroy_begin");
|
||||
@@ -380,6 +408,10 @@ esp_err_t voice_interaction_stop(char *err, size_t err_len) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t voice_interaction_stop(char *err, size_t err_len) {
|
||||
return voice_interaction_stop_with_timeout(1500, err, err_len);
|
||||
}
|
||||
|
||||
esp_err_t voice_interaction_tap_start(char *err, size_t err_len) {
|
||||
ESP_LOGI(TAG, "[stage] tap_start_enter");
|
||||
if (!voice_lock(VOICE_STATUS_LOCK_TIMEOUT_MS)) {
|
||||
|
||||
@@ -61,26 +61,31 @@ typedef struct {
|
||||
const volatile bool *cancel_flag;
|
||||
} platform_direct_print_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t shift_clock_high_us;
|
||||
uint16_t shift_clock_low_us;
|
||||
uint16_t latch_pulse_us;
|
||||
bool strobe_active_high;
|
||||
bool boost_active_high;
|
||||
uint16_t override_strobe_on_us;
|
||||
uint16_t override_strobe_interval_us;
|
||||
uint16_t override_motor_step_us;
|
||||
uint8_t override_steps_per_line;
|
||||
} platform_direct_debug_config_t;
|
||||
|
||||
esp_err_t platform_direct_printer_init(void);
|
||||
void platform_direct_printer_deinit(void);
|
||||
esp_err_t platform_direct_printer_connect(uint32_t timeout_ms);
|
||||
void platform_direct_printer_disconnect(void);
|
||||
bool platform_direct_printer_is_connected(void);
|
||||
esp_err_t platform_direct_printer_get_sensors(platform_printer_sensors_t *out_sensors);
|
||||
esp_err_t platform_direct_printer_get_debug_config(platform_direct_debug_config_t *out_config);
|
||||
esp_err_t platform_direct_printer_set_debug_config(const platform_direct_debug_config_t *config,
|
||||
esp_err_t platform_direct_printer_get_debug_config(uint16_t *out_shift_clock_high_us,
|
||||
uint16_t *out_shift_clock_low_us,
|
||||
uint16_t *out_latch_pulse_us,
|
||||
bool *out_strobe_active_high,
|
||||
bool *out_boost_active_high,
|
||||
uint16_t *out_override_strobe_on_us,
|
||||
uint16_t *out_override_strobe_interval_us,
|
||||
uint16_t *out_override_motor_step_us,
|
||||
uint8_t *out_override_steps_per_line);
|
||||
esp_err_t platform_direct_printer_set_debug_config(bool has_config,
|
||||
uint16_t shift_clock_high_us,
|
||||
uint16_t shift_clock_low_us,
|
||||
uint16_t latch_pulse_us,
|
||||
bool strobe_active_high,
|
||||
bool boost_active_high,
|
||||
uint16_t override_strobe_on_us,
|
||||
uint16_t override_strobe_interval_us,
|
||||
uint16_t override_motor_step_us,
|
||||
uint8_t override_steps_per_line,
|
||||
bool reset_defaults,
|
||||
char *err,
|
||||
size_t err_len);
|
||||
@@ -115,11 +120,15 @@ void voice_audio_close(void);
|
||||
|
||||
bool voice_audio_is_open(void);
|
||||
|
||||
// timeout_ms applies to voice-audio mutex acquisition.
|
||||
// Underlying codec driver I/O duration depends on driver/clocking state.
|
||||
esp_err_t voice_audio_read_pcm(int16_t *pcm,
|
||||
size_t samples,
|
||||
uint32_t timeout_ms,
|
||||
char *err,
|
||||
size_t err_len);
|
||||
// timeout_ms applies to voice-audio mutex acquisition.
|
||||
// Underlying codec driver I/O duration depends on driver/clocking state.
|
||||
esp_err_t voice_audio_write_pcm(const int16_t *pcm,
|
||||
size_t samples,
|
||||
uint32_t timeout_ms,
|
||||
|
||||
@@ -52,6 +52,8 @@ static bool s_scanning;
|
||||
static bool s_notify_ready;
|
||||
static bool s_host_synced;
|
||||
static bool s_initialized;
|
||||
static bool s_connecting;
|
||||
static uint32_t s_connect_timeout_ms = 15000;
|
||||
|
||||
static uint16_t uuid16(const ble_uuid_t *uuid) {
|
||||
if (uuid == NULL || uuid->type != BLE_UUID_TYPE_16) {
|
||||
@@ -397,12 +399,13 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) {
|
||||
|
||||
rc = ble_gap_connect(s_addr_type,
|
||||
&s_target_addr,
|
||||
30000,
|
||||
s_connect_timeout_ms > 30000 ? 30000 : s_connect_timeout_ms,
|
||||
&conn_params,
|
||||
gap_event_cb,
|
||||
NULL);
|
||||
if (rc != 0) {
|
||||
ESP_LOGE(TAG, "ble_gap_connect failed rc=%d", rc);
|
||||
s_connecting = false;
|
||||
signal_failure();
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Connecting...");
|
||||
@@ -417,6 +420,11 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) {
|
||||
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
if (event->connect.status == 0) {
|
||||
if (!s_connecting) {
|
||||
(void)ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
|
||||
return 0;
|
||||
}
|
||||
s_connecting = false;
|
||||
s_conn_handle = event->connect.conn_handle;
|
||||
xEventGroupSetBits(s_evt_group, EVT_CONNECTED);
|
||||
ESP_LOGI(TAG, "Connected handle=%u", s_conn_handle);
|
||||
@@ -424,6 +432,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) {
|
||||
ble_gattc_exchange_mtu(s_conn_handle, NULL, NULL);
|
||||
start_service_discovery();
|
||||
} else {
|
||||
s_connecting = false;
|
||||
ESP_LOGE(TAG, "Connect failed status=%d", event->connect.status);
|
||||
signal_failure();
|
||||
}
|
||||
@@ -431,6 +440,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) {
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
ESP_LOGW(TAG, "Disconnected reason=%d", event->disconnect.reason);
|
||||
s_connecting = false;
|
||||
s_conn_handle = BLE_HS_CONN_HANDLE_NONE;
|
||||
s_notify_ready = false;
|
||||
reset_discovery_state();
|
||||
@@ -564,6 +574,13 @@ esp_err_t ble_printer_client_connect(const char *target_name, uint32_t timeout_m
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
uint32_t effective_timeout_ms = timeout_ms;
|
||||
if (effective_timeout_ms < 1000) {
|
||||
effective_timeout_ms = 1000;
|
||||
} else if (effective_timeout_ms > 60000) {
|
||||
effective_timeout_ms = 60000;
|
||||
}
|
||||
|
||||
s_match_any_compatible = false;
|
||||
if (target_name != NULL && target_name[0] != '\0') {
|
||||
if (strcmp(target_name, "*") == 0) {
|
||||
@@ -581,9 +598,15 @@ esp_err_t ble_printer_client_connect(const char *target_name, uint32_t timeout_m
|
||||
xSemaphoreGive(s_lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
if (s_connecting) {
|
||||
xSemaphoreGive(s_lock);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
xEventGroupClearBits(s_evt_group, EVT_CONNECTED | EVT_READY | EVT_FAILED);
|
||||
reset_discovery_state();
|
||||
s_connect_timeout_ms = effective_timeout_ms;
|
||||
s_connecting = true;
|
||||
|
||||
int wait_sync_ms = 3000;
|
||||
while (!s_host_synced && wait_sync_ms > 0) {
|
||||
@@ -602,36 +625,21 @@ esp_err_t ble_printer_client_connect(const char *target_name, uint32_t timeout_m
|
||||
EVT_READY | EVT_FAILED,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
pdMS_TO_TICKS(timeout_ms));
|
||||
pdMS_TO_TICKS(effective_timeout_ms));
|
||||
|
||||
if (bits & EVT_READY) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(500)) == pdTRUE) {
|
||||
stop_scan_if_running();
|
||||
xSemaphoreGive(s_lock);
|
||||
}
|
||||
|
||||
// Similar to Android app behavior: quick retry when initial attempt fails or times out.
|
||||
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
xEventGroupClearBits(s_evt_group, EVT_CONNECTED | EVT_READY | EVT_FAILED);
|
||||
stop_scan_if_running();
|
||||
if (s_conn_handle != BLE_HS_CONN_HANDLE_NONE) {
|
||||
(void)ble_gap_terminate(s_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
|
||||
}
|
||||
s_connecting = false;
|
||||
reset_discovery_state();
|
||||
start_scan();
|
||||
xSemaphoreGive(s_lock);
|
||||
}
|
||||
|
||||
bits = xEventGroupWaitBits(s_evt_group,
|
||||
EVT_READY | EVT_FAILED,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
pdMS_TO_TICKS(timeout_ms));
|
||||
if (bits & EVT_READY) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(500)) == pdTRUE) {
|
||||
stop_scan_if_running();
|
||||
xSemaphoreGive(s_lock);
|
||||
}
|
||||
if (bits & EVT_FAILED) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -653,6 +661,7 @@ void ble_printer_client_disconnect(void) {
|
||||
ble_gap_terminate(s_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
|
||||
}
|
||||
|
||||
s_connecting = false;
|
||||
s_conn_handle = BLE_HS_CONN_HANDLE_NONE;
|
||||
reset_discovery_state();
|
||||
xSemaphoreGive(s_lock);
|
||||
|
||||
@@ -49,11 +49,23 @@ typedef struct {
|
||||
adc_channel_t channel;
|
||||
} adc_pin_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t shift_clock_high_us;
|
||||
uint16_t shift_clock_low_us;
|
||||
uint16_t latch_pulse_us;
|
||||
bool strobe_active_high;
|
||||
bool boost_active_high;
|
||||
uint16_t override_strobe_on_us;
|
||||
uint16_t override_strobe_interval_us;
|
||||
uint16_t override_motor_step_us;
|
||||
uint8_t override_steps_per_line;
|
||||
} direct_debug_config_t;
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
bool connected;
|
||||
uint8_t motor_phase;
|
||||
platform_direct_debug_config_t debug;
|
||||
direct_debug_config_t debug;
|
||||
SemaphoreHandle_t lock;
|
||||
adc_oneshot_unit_handle_t adc1_handle;
|
||||
adc_oneshot_unit_handle_t adc2_handle;
|
||||
@@ -567,8 +579,8 @@ void platform_direct_printer_deinit(void) {
|
||||
}
|
||||
|
||||
esp_err_t platform_direct_printer_connect(uint32_t timeout_ms) {
|
||||
(void)timeout_ms;
|
||||
#if !CONFIG_TQ_DIRECT_PRINTER_ENABLE
|
||||
(void)timeout_ms;
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#else
|
||||
esp_err_t err = platform_direct_printer_init();
|
||||
@@ -576,7 +588,12 @@ esp_err_t platform_direct_printer_connect(uint32_t timeout_ms) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(s_state.lock, pdMS_TO_TICKS(500)) != pdTRUE) {
|
||||
uint32_t lock_timeout_ms = timeout_ms == 0 ? 500 : timeout_ms;
|
||||
if (lock_timeout_ms > 5000) {
|
||||
lock_timeout_ms = 5000;
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(s_state.lock, pdMS_TO_TICKS(lock_timeout_ms)) != pdTRUE) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
@@ -631,12 +648,31 @@ esp_err_t platform_direct_printer_get_sensors(platform_printer_sensors_t *out_se
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t platform_direct_printer_get_debug_config(platform_direct_debug_config_t *out_config) {
|
||||
esp_err_t platform_direct_printer_get_debug_config(uint16_t *out_shift_clock_high_us,
|
||||
uint16_t *out_shift_clock_low_us,
|
||||
uint16_t *out_latch_pulse_us,
|
||||
bool *out_strobe_active_high,
|
||||
bool *out_boost_active_high,
|
||||
uint16_t *out_override_strobe_on_us,
|
||||
uint16_t *out_override_strobe_interval_us,
|
||||
uint16_t *out_override_motor_step_us,
|
||||
uint8_t *out_override_steps_per_line) {
|
||||
#if !CONFIG_TQ_DIRECT_PRINTER_ENABLE
|
||||
(void)out_config;
|
||||
(void)out_shift_clock_high_us;
|
||||
(void)out_shift_clock_low_us;
|
||||
(void)out_latch_pulse_us;
|
||||
(void)out_strobe_active_high;
|
||||
(void)out_boost_active_high;
|
||||
(void)out_override_strobe_on_us;
|
||||
(void)out_override_strobe_interval_us;
|
||||
(void)out_override_motor_step_us;
|
||||
(void)out_override_steps_per_line;
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#else
|
||||
if (out_config == NULL) {
|
||||
if (out_shift_clock_high_us == NULL || out_shift_clock_low_us == NULL || out_latch_pulse_us == NULL ||
|
||||
out_strobe_active_high == NULL || out_boost_active_high == NULL || out_override_strobe_on_us == NULL ||
|
||||
out_override_strobe_interval_us == NULL || out_override_motor_step_us == NULL ||
|
||||
out_override_steps_per_line == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t init_rc = platform_direct_printer_init();
|
||||
@@ -646,23 +682,49 @@ esp_err_t platform_direct_printer_get_debug_config(platform_direct_debug_config_
|
||||
if (xSemaphoreTake(s_state.lock, pdMS_TO_TICKS(500)) != pdTRUE) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
*out_config = s_state.debug;
|
||||
*out_shift_clock_high_us = s_state.debug.shift_clock_high_us;
|
||||
*out_shift_clock_low_us = s_state.debug.shift_clock_low_us;
|
||||
*out_latch_pulse_us = s_state.debug.latch_pulse_us;
|
||||
*out_strobe_active_high = s_state.debug.strobe_active_high;
|
||||
*out_boost_active_high = s_state.debug.boost_active_high;
|
||||
*out_override_strobe_on_us = s_state.debug.override_strobe_on_us;
|
||||
*out_override_strobe_interval_us = s_state.debug.override_strobe_interval_us;
|
||||
*out_override_motor_step_us = s_state.debug.override_motor_step_us;
|
||||
*out_override_steps_per_line = s_state.debug.override_steps_per_line;
|
||||
xSemaphoreGive(s_state.lock);
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t platform_direct_printer_set_debug_config(const platform_direct_debug_config_t *config,
|
||||
esp_err_t platform_direct_printer_set_debug_config(bool has_config,
|
||||
uint16_t shift_clock_high_us,
|
||||
uint16_t shift_clock_low_us,
|
||||
uint16_t latch_pulse_us,
|
||||
bool strobe_active_high,
|
||||
bool boost_active_high,
|
||||
uint16_t override_strobe_on_us,
|
||||
uint16_t override_strobe_interval_us,
|
||||
uint16_t override_motor_step_us,
|
||||
uint8_t override_steps_per_line,
|
||||
bool reset_defaults,
|
||||
char *err,
|
||||
size_t err_len) {
|
||||
#if !CONFIG_TQ_DIRECT_PRINTER_ENABLE
|
||||
(void)config;
|
||||
(void)has_config;
|
||||
(void)shift_clock_high_us;
|
||||
(void)shift_clock_low_us;
|
||||
(void)latch_pulse_us;
|
||||
(void)strobe_active_high;
|
||||
(void)boost_active_high;
|
||||
(void)override_strobe_on_us;
|
||||
(void)override_strobe_interval_us;
|
||||
(void)override_motor_step_us;
|
||||
(void)override_steps_per_line;
|
||||
(void)reset_defaults;
|
||||
write_err(err, err_len, "direct backend disabled");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#else
|
||||
if (config == NULL && !reset_defaults) {
|
||||
if (!has_config && !reset_defaults) {
|
||||
write_err(err, err_len, "invalid args");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@@ -681,45 +743,48 @@ esp_err_t platform_direct_printer_set_debug_config(const platform_direct_debug_c
|
||||
set_debug_defaults_locked();
|
||||
}
|
||||
|
||||
if (config != NULL) {
|
||||
if (config->shift_clock_high_us < DEBUG_SHIFT_CLOCK_US_MIN ||
|
||||
config->shift_clock_high_us > DEBUG_SHIFT_CLOCK_US_MAX ||
|
||||
config->shift_clock_low_us < DEBUG_SHIFT_CLOCK_US_MIN ||
|
||||
config->shift_clock_low_us > DEBUG_SHIFT_CLOCK_US_MAX) {
|
||||
if (has_config) {
|
||||
if (shift_clock_high_us < DEBUG_SHIFT_CLOCK_US_MIN || shift_clock_high_us > DEBUG_SHIFT_CLOCK_US_MAX ||
|
||||
shift_clock_low_us < DEBUG_SHIFT_CLOCK_US_MIN || shift_clock_low_us > DEBUG_SHIFT_CLOCK_US_MAX) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "shift clock us out of range (1..50)");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->latch_pulse_us < DEBUG_LATCH_PULSE_US_MIN ||
|
||||
config->latch_pulse_us > DEBUG_LATCH_PULSE_US_MAX) {
|
||||
if (latch_pulse_us < DEBUG_LATCH_PULSE_US_MIN || latch_pulse_us > DEBUG_LATCH_PULSE_US_MAX) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "latch pulse us out of range (1..50)");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_strobe_on_us != 0 &&
|
||||
(config->override_strobe_on_us < 100 || config->override_strobe_on_us > 10000)) {
|
||||
if (override_strobe_on_us != 0 && (override_strobe_on_us < 100 || override_strobe_on_us > 10000)) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "strobe_on_us must be 0 or 100..10000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_strobe_interval_us > 10000) {
|
||||
if (override_strobe_interval_us > 10000) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "strobe_interval_us must be 0..10000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_motor_step_us != 0 &&
|
||||
(config->override_motor_step_us < 100 || config->override_motor_step_us > 20000)) {
|
||||
if (override_motor_step_us != 0 && (override_motor_step_us < 100 || override_motor_step_us > 20000)) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "motor_step_us must be 0 or 100..20000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_steps_per_line > 8) {
|
||||
if (override_steps_per_line > 8) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "steps_per_line must be 0..8");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
s_state.debug = *config;
|
||||
s_state.debug.shift_clock_high_us = shift_clock_high_us;
|
||||
s_state.debug.shift_clock_low_us = shift_clock_low_us;
|
||||
s_state.debug.latch_pulse_us = latch_pulse_us;
|
||||
s_state.debug.strobe_active_high = strobe_active_high;
|
||||
s_state.debug.boost_active_high = boost_active_high;
|
||||
s_state.debug.override_strobe_on_us = override_strobe_on_us;
|
||||
s_state.debug.override_strobe_interval_us = override_strobe_interval_us;
|
||||
s_state.debug.override_motor_step_us = override_motor_step_us;
|
||||
s_state.debug.override_steps_per_line = override_steps_per_line;
|
||||
}
|
||||
|
||||
safe_drive_off_locked(s_state.connected);
|
||||
|
||||
@@ -292,7 +292,9 @@ void lcd_module_deinit(void)
|
||||
{
|
||||
#if CONFIG_TQ_SCREEN_ENABLE
|
||||
if (s_lcd.lock != NULL) {
|
||||
(void)xSemaphoreTake(s_lcd.lock, portMAX_DELAY);
|
||||
if (xSemaphoreTake(s_lcd.lock, pdMS_TO_TICKS(1000)) != pdTRUE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_lcd.lv_disp != NULL) {
|
||||
|
||||
@@ -56,12 +56,18 @@ static void wifi_event_handler(void *arg,
|
||||
(void)event_data;
|
||||
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
if (!s_started) {
|
||||
return;
|
||||
}
|
||||
(void)esp_wifi_connect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
s_ready = false;
|
||||
if (!s_started) {
|
||||
return;
|
||||
}
|
||||
if (s_retry_num < CONFIG_TQ_WIFI_MAXIMUM_RETRY) {
|
||||
(void)esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
@@ -73,6 +79,9 @@ static void wifi_event_handler(void *arg,
|
||||
}
|
||||
|
||||
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
if (!s_started) {
|
||||
return;
|
||||
}
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
s_retry_num = 0;
|
||||
@@ -218,6 +227,7 @@ esp_err_t wifi_manager_start(void) {
|
||||
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_WIFI_CONNECT_FAILED, 1);
|
||||
}
|
||||
runtime_diag_record_error("wifi_connect", err, "STA connect failed");
|
||||
(void)wifi_manager_stop();
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user