diff --git a/private_include/ota_ws_private.h b/private_include/ota_ws_private.h index 591e64a..110b90b 100644 --- a/private_include/ota_ws_private.h +++ b/private_include/ota_ws_private.h @@ -12,8 +12,9 @@ #define OTA_ERROR "otaError" #define OTA_CANCEL "otaCancel" -#define OTA_CHUNK_SIZE 4096 +#define OTA_CHUNK_SIZE 4096*2 esp_err_t start_ota_ws(void); esp_err_t write_ota_ws(int data_read, uint8_t *ota_write_data); -esp_err_t end_ota_ws(void); \ No newline at end of file +esp_err_t end_ota_ws(void); +esp_err_t abort_ota_ws(void); \ No newline at end of file diff --git a/sdkconfig b/sdkconfig index afacf19..5ff7911 100644 --- a/sdkconfig +++ b/sdkconfig @@ -480,12 +480,12 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # # Partition Table # -CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table diff --git a/sdkconfig.old b/sdkconfig.old index 22bfe5b..94cba3e 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -459,15 +459,15 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_FLASHSIZE="16MB" +CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set CONFIG_ESPTOOLPY_BEFORE="default_reset" @@ -480,13 +480,13 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # # Partition Table # -CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x9000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table @@ -752,7 +752,7 @@ CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set +CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set # end of HTTP Server diff --git a/source/ota_ws.html b/source/ota_ws.html index b93cca7..44858ef 100644 --- a/source/ota_ws.html +++ b/source/ota_ws.html @@ -171,7 +171,7 @@ function receiveWsData(data) { try { let obj = JSON.parse(data); - console.log(data); + //console.log(data); switch (obj.name) { case "otaSetChunkSize": otaSetChunkSize = obj.value; @@ -180,7 +180,7 @@ let otaDataSend = otaData.subarray(obj.value, obj.value + otaSetChunkSize); document.getElementById("otaPogress").value = obj.value; document.getElementById("otaStartCancel").innerHTML = "Ota Transfer. Size = " + otaData.length + " Segment = " + obj.value + " Click to Cancel"; - console.log("sock send " + obj.value + " " + otaDataSend.length); + //console.log("sock send " + obj.value + " " + otaDataSend.length); socket.send(otaDataSend); break; case "otaEnd": diff --git a/source/ota_ws_esp.c b/source/ota_ws_esp.c index 8212296..421970d 100644 --- a/source/ota_ws_esp.c +++ b/source/ota_ws_esp.c @@ -16,7 +16,7 @@ static esp_ota_handle_t update_handle = 0; esp_err_t start_ota_ws(void) { - return ESP_OK; // debug return + //return ESP_OK; // debug return esp_err_t err; ESP_LOGI(TAG, "Starting OTA"); @@ -51,7 +51,7 @@ esp_err_t start_ota_ws(void) esp_err_t write_ota_ws(int data_read, uint8_t *ota_write_data) { - return ESP_OK; // debug return + //return ESP_OK; // debug return if (image_header_was_checked == false) // first segment @@ -83,7 +83,7 @@ esp_err_t write_ota_ws(int data_read, uint8_t *ota_write_data) esp_err_t end_ota_ws(void) { - return ESP_OK; // debug return + //return ESP_OK; // debug return esp_err_t err = esp_ota_end(update_handle); if (err != ESP_OK) { @@ -99,4 +99,8 @@ esp_err_t end_ota_ws(void) return ESP_FAIL; } return ESP_OK; +} +esp_err_t abort_ota_ws(void) +{ + return esp_ota_abort(update_handle); } \ No newline at end of file diff --git a/source/ota_ws_http.c b/source/ota_ws_http.c index 855ea7c..6ee3808 100644 --- a/source/ota_ws_http.c +++ b/source/ota_ws_http.c @@ -11,6 +11,25 @@ static const char *TAG = "ota_ws"; +static int ota_size; +static int ota_start_chunk; +static int ota_started; + +static esp_err_t json_to_str_parm(char *jsonstr, char *nameStr, char *valStr); +static esp_err_t send_json_string(char *str, httpd_req_t *req); +static esp_err_t ota_ws_handler(httpd_req_t *req); +static void ota_error(httpd_req_t *req, char *code, char *msg); + +static void ota_error(httpd_req_t *req, char *code, char *msg) +{ + char json_str[128]; + ota_size = ota_start_chunk = ota_started = 0; + abort_ota_ws(); + ESP_LOGE(TAG, "%s %s", code, msg); + snprintf(json_str, sizeof(json_str), "{\"name\":\"%s\",\"value\":\"%s\"}", code, msg); + send_json_string(json_str, req); +} + // simple json parse -> only one parametr name/val static esp_err_t json_to_str_parm(char *jsonstr, char *nameStr, char *valStr) // распаковать строку json в пару name/val { @@ -48,27 +67,24 @@ static esp_err_t send_json_string(char *str, httpd_req_t *req) } static esp_err_t ota_ws_handler(httpd_req_t *req) { - static int ota_size; - static int ota_start_chunk; if (req->method == HTTP_GET) { ESP_LOGI(TAG, "Handshake done, the new connection was opened"); return ESP_OK; } - char json_key[64]={0}; - char json_value[64]={0}; - char json_str[64] = {0}; + char json_key[64] = {0}; + char json_value[64] = {0}; + char json_str[128] = {0}; httpd_ws_frame_t ws_pkt; uint8_t *buf = NULL; memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t)); - // ws_pkt.type = HTTPD_WS_TYPE_TEXT; /* Set max_len = 0 to get the frame len */ esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, 0); if (ret != ESP_OK) { - ESP_LOGE(TAG, "httpd_ws_recv_frame failed to get frame len with %d", ret); + ota_error(req, OTA_ERROR, "httpd_ws_recv_frame failed to get frame len"); return ret; } if (ws_pkt.len) @@ -77,7 +93,7 @@ static esp_err_t ota_ws_handler(httpd_req_t *req) buf = calloc(1, ws_pkt.len + 1); if (buf == NULL) { - ESP_LOGE(TAG, "Failed to calloc memory for buf"); + ota_error(req, OTA_ERROR, "Failed to calloc memory for buf"); return ESP_ERR_NO_MEM; } ws_pkt.payload = buf; @@ -85,55 +101,97 @@ static esp_err_t ota_ws_handler(httpd_req_t *req) ret = httpd_ws_recv_frame(req, &ws_pkt, ws_pkt.len); if (ret != ESP_OK) { - ESP_LOGE(TAG, "httpd_ws_recv_frame failed with %d", ret); + ota_error(req, OTA_ERROR, "httpd_ws_recv_frame failed"); goto _recv_ret; } } ret = ESP_OK; if (ws_pkt.type == HTTPD_WS_TYPE_TEXT) { - ESP_LOGI(TAG, "Rcv txt msg len=%d data=%s", ws_pkt.len, buf); - if (json_to_str_parm((char*)buf,json_key,json_value)) + //ESP_LOGI(TAG, "Rcv txt msg len=%d data=%s", ws_pkt.len, buf); + if (json_to_str_parm((char *)buf, json_key, json_value)) { - ESP_LOGE(TAG,"error json str: %s",buf); + ota_error(req, OTA_ERROR, "Error json str"); goto _recv_ret; } - if(strcmp(json_key,OTA_SIZE_START)==0)// start ota + if (strncmp(json_key, OTA_SIZE_START, sizeof(OTA_SIZE_START)) == 0) // start ota { ota_size = atoi(json_value); + if (ota_size == 0) + { + ota_error(req, OTA_ERROR, "Error ota size = 0"); + goto _recv_ret; + } + ret = start_ota_ws(); + if (ret) + { + ota_error(req, OTA_ERROR, "Error start ota"); + goto _recv_ret; + } + ota_started = 1; ota_start_chunk = 0; snprintf(json_str, sizeof(json_str), "{\"name\":\"%s\",\"value\":%d}", OTA_SET_CHUNK_SIZE, OTA_CHUNK_SIZE); - send_json_string(json_str,req); + send_json_string(json_str, req); snprintf(json_str, sizeof(json_str), "{\"name\":\"%s\",\"value\":%d}", OTA_GET_CHUNK, ota_start_chunk); - send_json_string(json_str,req); + send_json_string(json_str, req); } - - } - else if (ws_pkt.type == HTTPD_WS_TYPE_BINARY) - { - ESP_LOGI(TAG, "Rcv bin msg len=%d", ws_pkt.len); - ota_start_chunk += ws_pkt.len; - if(ota_start_chunk < ota_size) + if (strncmp(json_key, OTA_CANCEL, sizeof(OTA_CANCEL)) == 0) // cancel ota { + ota_error(req, OTA_CANCEL, "Cancel command"); + ret = ESP_OK; + goto _recv_ret; + } + if (strncmp(json_key, OTA_ERROR, sizeof(OTA_ERROR)) == 0) // error ota + { + ota_error(req, OTA_ERROR, "Error command"); + ret = ESP_OK; + goto _recv_ret; + } + if (strncmp(json_key, OTA_RESTART_ESP, sizeof(OTA_RESTART_ESP)) == 0) // cancel ota + { + esp_restart(); + } + } + else if (ws_pkt.type == HTTPD_WS_TYPE_BINARY && ota_started) + { + //ESP_LOGI(TAG, "Rcv bin msg start=%d len=%d", ota_start_chunk, ws_pkt.len); + + if (ota_start_chunk + ws_pkt.len < ota_size) + { + ret = write_ota_ws(ws_pkt.len, buf); + if (ret) + { + ota_error(req, OTA_ERROR, "Error write ota"); + goto _recv_ret; + } + ota_start_chunk += ws_pkt.len; snprintf(json_str, sizeof(json_str), "{\"name\":\"%s\",\"value\": %d }", OTA_GET_CHUNK, ota_start_chunk); - send_json_string(json_str,req); + send_json_string(json_str, req); } - else{ -// end ota + else + { + // last chunk and end ota + ret = write_ota_ws(ws_pkt.len, buf); + if (ret) + { + ota_error(req, OTA_ERROR, "Error write ota"); + goto _recv_ret; + } + ret = end_ota_ws(); + if (ret) + { + ota_error(req, OTA_ERROR, "Error end ota"); + goto _recv_ret; + } ota_size = 0; ota_start_chunk = 0; + ota_started = 0; + ESP_LOGI(TAG,"OTA END OK"); snprintf(json_str, sizeof(json_str), "{\"name\":\"%s\",\"value\":\"%s\" }", OTA_END, "OK"); - send_json_string(json_str,req); - + send_json_string(json_str, req); } } - else - { - ESP_LOGE(TAG, "httpd_ws_recv_frame unknown frame type %d", ws_pkt.type); - ret = ESP_FAIL; - goto _recv_ret; - } _recv_ret: free(buf); return ret;