|
| 1 | +/* |
| 2 | + * ota_update.c |
| 3 | + * |
| 4 | + * Created on: 2018-04-06 15:12 |
| 5 | + * Author: Jack Chen <[email protected]> |
| 6 | + */ |
| 7 | + |
| 8 | +#include <string.h> |
| 9 | + |
| 10 | +#include "cJSON.h" |
| 11 | +#include "esp_log.h" |
| 12 | +#include "esp_ota_ops.h" |
| 13 | + |
| 14 | +#include "device/wifi.h" |
| 15 | +#include "system/event.h" |
| 16 | +#include "system/firmware.h" |
| 17 | +#include "tasks/gui_daemon.h" |
| 18 | +#include "tasks/nfc_daemon.h" |
| 19 | +#include "tasks/led_daemon.h" |
| 20 | +#include "tasks/audio_daemon.h" |
| 21 | +#include "tasks/http2_client.h" |
| 22 | + |
| 23 | +#define TAG "ota" |
| 24 | + |
| 25 | +int ota_update_parse_data(struct http2c_handle *handle, const char *data, size_t len, int flags) |
| 26 | +{ |
| 27 | + static const esp_partition_t *update_partition = NULL; |
| 28 | + static esp_ota_handle_t update_handle = 0; |
| 29 | + static long binary_file_length = 0; |
| 30 | + |
| 31 | + if (len) { |
| 32 | + EventBits_t uxBits = xEventGroupGetBits(daemon_event_group); |
| 33 | + if (!(uxBits & HTTP2_DAEMON_OTA_RUN_BIT)) { |
| 34 | + xEventGroupSetBits(daemon_event_group, HTTP2_DAEMON_OTA_RUN_BIT); |
| 35 | + |
| 36 | + led_set_mode(3); |
| 37 | + gui_show_image(8); |
| 38 | + |
| 39 | + update_partition = esp_ota_get_next_update_partition(NULL); |
| 40 | + ESP_LOGI(TAG, "writing to partition subtype %d at offset 0x%x", |
| 41 | + update_partition->subtype, update_partition->address); |
| 42 | + assert(update_partition != NULL); |
| 43 | + |
| 44 | + esp_err_t err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle); |
| 45 | + if (err != ESP_OK) { |
| 46 | + ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err)); |
| 47 | + goto exit; |
| 48 | + } |
| 49 | + |
| 50 | + binary_file_length = 0; |
| 51 | + } |
| 52 | + esp_err_t err = esp_ota_write(update_handle, (const void *)data, len); |
| 53 | + if (err != ESP_OK) { |
| 54 | + ESP_LOGE(TAG, "esp_ota_write failed (%s)!", esp_err_to_name(err)); |
| 55 | + xEventGroupSetBits(daemon_event_group, HTTP2_DAEMON_OTA_FAILED_BIT); |
| 56 | + goto exit; |
| 57 | + } |
| 58 | + binary_file_length += len; |
| 59 | + ESP_LOGI(TAG, "have written image length %ld", binary_file_length); |
| 60 | + } |
| 61 | + |
| 62 | + if (flags == DATA_RECV_RST_STREAM) { |
| 63 | + EventBits_t uxBits = xEventGroupGetBits(daemon_event_group); |
| 64 | + if (uxBits & HTTP2_DAEMON_OTA_FAILED_BIT) { |
| 65 | + ESP_LOGE(TAG, "ota update failed"); |
| 66 | + } else if (binary_file_length != 0) { |
| 67 | + if (esp_ota_end(update_handle) != ESP_OK) { |
| 68 | + ESP_LOGE(TAG, "esp_ota_end failed!"); |
| 69 | + goto exit; |
| 70 | + } |
| 71 | + esp_err_t err = esp_ota_set_boot_partition(update_partition); |
| 72 | + if (err != ESP_OK) { |
| 73 | + ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); |
| 74 | + goto exit; |
| 75 | + } |
| 76 | + ESP_LOGW(TAG, "prepare to restart system!"); |
| 77 | + gui_show_image(4); |
| 78 | + vTaskDelay(2000 / portTICK_RATE_MS); |
| 79 | + esp_restart(); |
| 80 | + } else { |
| 81 | + ESP_LOGI(TAG, "no update found"); |
| 82 | + } |
| 83 | +exit: |
| 84 | + xEventGroupClearBits(daemon_event_group, HTTP2_DAEMON_OTA_READY_BIT); |
| 85 | + } |
| 86 | + |
| 87 | + return 0; |
| 88 | +} |
| 89 | + |
| 90 | +int ota_update_prepare_data(struct http2c_handle *handle, char *buf, size_t length, uint32_t *data_flags) |
| 91 | +{ |
| 92 | + cJSON *root = NULL; |
| 93 | + root = cJSON_CreateObject(); |
| 94 | + cJSON_AddNumberToObject(root, "request", 105); |
| 95 | + cJSON_AddStringToObject(root, "version", firmware_get_version()); |
| 96 | + cJSON_AddStringToObject(root, "mac", wifi0_mac_str); |
| 97 | + cJSON_PrintPreallocated(root, buf, length, 0); |
| 98 | + cJSON_Delete(root); |
| 99 | + (*data_flags) |= NGHTTP2_DATA_FLAG_EOF; |
| 100 | + return strlen(buf); |
| 101 | +} |
| 102 | + |
| 103 | +void ota_update(void) |
| 104 | +{ |
| 105 | +#if defined(CONFIG_ENABLE_OTA) |
| 106 | + EventBits_t uxBits = xEventGroupSync( |
| 107 | + daemon_event_group, |
| 108 | + HTTP2_DAEMON_OTA_READY_BIT, |
| 109 | + HTTP2_DAEMON_OTA_FINISH_BIT, |
| 110 | + 300000 / portTICK_RATE_MS |
| 111 | + ); |
| 112 | + if ((uxBits & HTTP2_DAEMON_OTA_FINISH_BIT) == 0) { |
| 113 | + xEventGroupClearBits(daemon_event_group, HTTP2_DAEMON_OTA_READY_BIT); |
| 114 | + } |
| 115 | +#endif |
| 116 | +} |
0 commit comments