Bug Fix: OTA now works from the Squeezelite app partition - release

This commit is contained in:
Sebastien
2019-11-13 17:16:57 -05:00
parent 2c3df6a8ce
commit 4369614bb4
8 changed files with 123 additions and 26 deletions

View File

@@ -6,14 +6,13 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "esp_log.h"
#include "esp_console.h"
#include "esp_system.h"
#include "esp_sleep.h"
#include "esp_spi_flash.h"
#include "driver/rtc_io.h"
#include "driver/uart.h"
@@ -28,13 +27,15 @@
#include "esp_ota_ops.h"
#include "platform_esp32.h"
#include "nvs_utilities.h"
#include "esp_sleep.h"
#include "driver/uart.h" // for the uart driver access
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
#define WITH_TASKS_INFO 1
#endif
static const char * TAG = "platform_esp32";
static const char * TAG = "cmd_system";
static void register_free();
static void register_heap();
@@ -43,6 +44,7 @@ static void register_restart();
static void register_deep_sleep();
static void register_light_sleep();
static void register_factory_boot();
static void register_restart_ota();
#if WITH_TASKS_INFO
static void register_tasks();
#endif
@@ -56,6 +58,7 @@ void register_system()
register_deep_sleep();
register_light_sleep();
register_factory_boot();
register_restart_ota();
#if WITH_TASKS_INFO
register_tasks();
#endif
@@ -99,6 +102,17 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
#if RECOVERY_APPLICATION
if(partition_subtype ==ESP_PARTITION_SUBTYPE_APP_FACTORY){
ESP_LOGW(TAG,"RECOVERY application is already active");
ESP_LOGW(TAG, "Restarting after tx complete");
uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS);
esp_restart();
return ESP_OK;
}
#else
if(partition_subtype !=ESP_PARTITION_SUBTYPE_APP_FACTORY){
ESP_LOGW(TAG,"SQUEEZELITE application is already active");
ESP_LOGW(TAG, "Restarting after tx complete");
uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS);
esp_restart();
return ESP_OK;
}
#endif
@@ -115,30 +129,36 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
else
{
partition = (esp_partition_t *) esp_partition_get(it);
ESP_LOGD(TAG, "Releasing partition iterator");
esp_partition_iterator_release(it);
if(partition != NULL){
ESP_LOGI(TAG, "Found application partition %s sub type %u", partition->label,partition_subtype);
err=esp_ota_set_boot_partition(partition);
if(err!=ESP_OK){
ESP_LOGE(TAG,"Unable to set partition as active for next boot. %s",esp_err_to_name(err));
bFound=false;
set_status_message(ERROR, "Unable to select partition for reboot.");
}
else{
ESP_LOGW(TAG, "Application partition %s sub type %u is selected for boot", partition->label,partition_subtype);
bFound=true;
set_status_message(WARNING, "Rebooting!");
}
}
else
{
ESP_LOGE(TAG,"partition type %u not found! Unable to reboot to recovery.",partition_subtype);
set_status_message(ERROR, "Partition not found.");
}
esp_partition_iterator_release(it);
ESP_LOGD(TAG, "Yielding to other processes");
taskYIELD();
if(bFound) {
ESP_LOGW(TAG,"Configuration %s changes. ",config_has_changes()?"has":"does not have");
if(!wait_for_commit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGI(TAG, "Restarting!.");
ESP_LOGW(TAG, "Restarting after tx complete");
uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS);
esp_restart();
}
}
@@ -148,39 +168,50 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
static int restart(int argc, char **argv)
{
ESP_LOGW(TAG, "\n\nPerforming a simple restart to the currently active partition.");
if(!wait_for_commit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGW(TAG, "Restarting");
ESP_LOGW(TAG, "Restarting after tx complete");
uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS);
esp_restart();
return 0;
}
void simple_restart()
{
ESP_LOGW(TAG,"\n\n Called to perform a simple system reboot.");
if(!wait_for_commit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGW(TAG, "Restarting");
ESP_LOGW(TAG, "Restarting after tx complete");
uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS);
esp_restart();
}
esp_err_t guided_restart_ota(){
ESP_LOGW(TAG,"\n\nCalled for a reboot to OTA Application");
guided_boot(ESP_PARTITION_SUBTYPE_APP_OTA_0);
// If we're still alive, then there may not be an ota partition to boot from
guided_boot(ESP_PARTITION_SUBTYPE_APP_FACTORY);
return ESP_FAIL; // return fail. This should never return... we're rebooting!
}
esp_err_t guided_factory(){
ESP_LOGW(TAG,"\n\nCalled for a reboot to recovery application");
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)
{
ESP_LOGW(TAG, "Executing guided boot into 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)
{
ESP_LOGW(TAG, "Executing guided boot into ota app 0");
guided_boot(ESP_PARTITION_SUBTYPE_APP_OTA_0);
return 0; // return fail. This should never return... we're rebooting!
}
static void register_restart()
{
const esp_console_cmd_t cmd = {
@@ -191,6 +222,16 @@ static void register_restart()
};
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}
static void register_restart_ota()
{
const esp_console_cmd_t cmd = {
.command = "restart_ota",
.help = "Selects the ota app partition to boot from and performa a software reset of the chip",
.hint = NULL,
.func = &restart_ota,
};
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}
static void register_factory_boot()
{

View File

@@ -6,7 +6,7 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
@@ -175,8 +175,10 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
uint32_t elapsed_ms= (tv.tv_sec-ota_status.OTA_start.tv_sec )*1000+(tv.tv_usec-ota_status.OTA_start.tv_usec)/1000;
ESP_LOGI(TAG,"OTA progress : %d/%d (%d pct), %d KB/s", ota_status.ota_actual_len, ota_status.ota_total_len, ota_status.newpct, elapsed_ms>0?ota_status.ota_actual_len*1000/elapsed_ms/1024:0);
wifi_manager_refresh_ota_json();
ota_status.lastpct=ota_status.newpct;
}
taskYIELD();
}
break;
case HTTP_EVENT_ON_FINISH:

View File

@@ -474,11 +474,8 @@ void http_server_netconn_serve(struct netconn *conn) {
ESP_LOGW(TAG, "Starting process OTA for url %s",otaURL);
#else
ESP_LOGW(TAG, "Restarting system to process OTA for url %s",otaURL);
// close the connection cleanly
netconn_close(conn);
netconn_delete(conn);
#endif
start_ota(otaURL,false);
wifi_manager_reboot_ota(otaURL);
free(otaURL);
}
}
@@ -537,23 +534,23 @@ void http_server_netconn_serve(struct netconn *conn) {
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
netconn_close(conn);
netconn_delete(conn);
guided_restart_ota();
wifi_manager_reboot(OTA);
ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST reboot.json");
}
else if(strstr(line, "POST /reboot.json ")) {
ESP_LOGI(TAG, "http_server_netconn_serve: POST restart.json");
ESP_LOGI(TAG, "http_server_netconn_serve: POST reboot.json");
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
netconn_close(conn);
netconn_delete(conn);
simple_restart();
ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST restart.json");
wifi_manager_reboot(RESTART);
ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST reboot.json");
}
else if(strstr(line, "POST /recovery.json ")) {
ESP_LOGI(TAG, "http_server_netconn_serve: POST recovery.json");
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
netconn_close(conn);
netconn_delete(conn);
guided_factory();
wifi_manager_reboot(RECOVERY);
ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST recovery.json");
}
else if(strstr(line, "GET /status.json ")) {

View File

@@ -61,6 +61,7 @@ Contains the freeRTOS task and all necessary support
#include "driver/adc.h"
#include "cJSON.h"
#include "nvs_utilities.h"
#include "cmd_system.h"
#ifndef RECOVERY_APPLICATION
#define RECOVERY_APPLICATION 0
@@ -222,6 +223,35 @@ void wifi_manager_disconnect_async(){
//xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT); TODO: delete
}
void wifi_manager_reboot_ota(char * url){
if(url == NULL){
wifi_manager_send_message(ORDER_RESTART_OTA, NULL);
}
else {
wifi_manager_send_message(ORDER_RESTART_OTA_URL,strdup(url) );
}
}
void wifi_manager_reboot(reboot_type_t rtype){
switch (rtype) {
case OTA:
wifi_manager_send_message(ORDER_RESTART_OTA, NULL);
break;
case RECOVERY:
wifi_manager_send_message(ORDER_RESTART_RECOVERY, NULL);
break;
case RESTART:
wifi_manager_send_message(ORDER_RESTART, NULL);
break;
default:
ESP_LOGE(TAG,"Unknown reboot type %d", rtype);
break;
}
wifi_manager_send_message(ORDER_DISCONNECT_STA, NULL);
//xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT); TODO: delete
}
void wifi_manager_init_wifi(){
/* event handler and event group for the wifi driver */
ESP_LOGD(TAG, "Initializing wifi. Creating event group");
@@ -1432,6 +1462,20 @@ void wifi_manager( void * pvParameters ){
/* callback */
if(cb_ptr_arr[msg.code]) (*cb_ptr_arr[msg.code])(NULL);
break;
case ORDER_RESTART_OTA:
guided_restart_ota();
break;
case ORDER_RESTART_OTA_URL:
start_ota(msg.param,false);
free(msg.param);
break;
case ORDER_RESTART_RECOVERY:
guided_factory();
break;
case ORDER_RESTART:
simple_restart();
break;
default:
break;

View File

@@ -200,10 +200,24 @@ typedef enum message_code_t {
EVENT_SCAN_DONE = 13,
EVENT_STA_GOT_IP = 14,
EVENT_REFRESH_OTA = 15,
MESSAGE_CODE_COUNT = 16 /* important for the callback array */
ORDER_RESTART_OTA = 16,
ORDER_RESTART_RECOVERY = 17,
ORDER_RESTART_OTA_URL = 18,
ORDER_RESTART = 19,
MESSAGE_CODE_COUNT = 20 /* important for the callback array */
}message_code_t;
typedef enum reboot_type_t{
OTA,
RECOVERY,
RESTART,
} reboot_type_t;
void wifi_manager_reboot(reboot_type_t rtype);
void wifi_manager_reboot_ota(char * url);
/**
* @brief simplified reason codes for a lost connection.
*

View File

@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "config.h"
#include "nvs_utilities.h"
@@ -565,7 +565,7 @@ void config_delete_key(const char *key){
ESP_LOGV(TAG, "Structure before delete \n%s", struc_str);
free(struc_str);
}
cJSON * entry = cJSON_GetObjectItemCaseSensitive(nvs_json, key);
cJSON * entry = cJSON_DetachItemFromObjectCaseSensitive(nvs_json, key);
if(entry !=NULL){
ESP_LOGI(TAG, "Removing config key [%s]", entry->string);
cJSON_Delete(entry);
@@ -574,7 +574,6 @@ void config_delete_key(const char *key){
ESP_LOGV(TAG, "Structure after delete \n%s", struc_str);
free(struc_str);
}
}
else {
ESP_LOGW(TAG, "Unable to remove config key [%s]: not found.", key);

View File

@@ -10,7 +10,7 @@ extern "C" {
#ifdef __cplusplus
}
#endif
bool config_has_uncommitted();
bool config_has_changes();
void config_commit_to_nvs();
void config_start_timer();
void config_init();

View File

@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "platform_esp32.h"
#include "led.h"
#include <stdio.h>