-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathesp_https_ota.c
142 lines (126 loc) · 4.65 KB
/
esp_https_ota.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <esp_https_ota.h>
#include <esp_ota_ops.h>
#include <esp_log.h>
#include "sdkconfig.h"
#define OTA_BUF_SIZE CONFIG_OTA_BUF_SIZE
static const char *TAG = "esp_https_ota";
static void http_cleanup(esp_http_client_handle_t client)
{
esp_http_client_close(client);
esp_http_client_cleanup(client);
}
esp_err_t esp_https_ota(const esp_http_client_config_t *config)
{
if (!config) {
ESP_LOGE(TAG, "esp_http_client config not found");
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_OTA_ALLOW_HTTP
if (!config->cert_pem) {
ESP_LOGE(TAG, "Server certificate not found in esp_http_client config");
return ESP_FAIL;
}
#endif
esp_http_client_handle_t client = esp_http_client_init(config);
if (client == NULL) {
ESP_LOGE(TAG, "Failed to initialise HTTP connection");
return ESP_FAIL;
}
#if !CONFIG_OTA_ALLOW_HTTP
if (esp_http_client_get_transport_type(client) != HTTP_TRANSPORT_OVER_SSL) {
ESP_LOGE(TAG, "Transport is not over HTTPS");
return ESP_FAIL;
}
#endif
esp_err_t err = esp_http_client_open(client, 0);
if (err != ESP_OK) {
esp_http_client_cleanup(client);
ESP_LOGE(TAG, "Failed to open HTTP connection: %d", err);
return err;
}
esp_http_client_fetch_headers(client);
int statusCode = esp_http_client_get_status_code(client);
if (statusCode != 200) {
ESP_LOGE(TAG, "Received incorrect HTTP status code: %d (expected: 200)", statusCode);
http_cleanup(client);
return ESP_FAIL;
}
esp_ota_handle_t update_handle = 0;
const esp_partition_t *update_partition = NULL;
ESP_LOGI(TAG, "Starting OTA...");
update_partition = esp_ota_get_next_update_partition(NULL);
if (update_partition == NULL) {
ESP_LOGE(TAG, "Passive OTA partition not found");
http_cleanup(client);
return ESP_FAIL;
}
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
update_partition->subtype, update_partition->address);
err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_begin failed, error=%d", err);
http_cleanup(client);
return err;
}
ESP_LOGI(TAG, "esp_ota_begin succeeded");
ESP_LOGI(TAG, "Please Wait. This may take time");
esp_err_t ota_write_err = ESP_OK;
char *upgrade_data_buf = (char *)malloc(OTA_BUF_SIZE);
if (!upgrade_data_buf) {
ESP_LOGE(TAG, "Couldn't allocate memory to upgrade data buffer");
return ESP_ERR_NO_MEM;
}
int binary_file_len = 0;
while (1) {
int data_read = esp_http_client_read(client, upgrade_data_buf, OTA_BUF_SIZE);
if (data_read == 0) {
ESP_LOGI(TAG, "Connection closed,all data received");
break;
}
if (data_read < 0) {
ESP_LOGE(TAG, "Error: SSL data read error");
break;
}
if (data_read > 0) {
ota_write_err = esp_ota_write( update_handle, (const void *)upgrade_data_buf, data_read);
if (ota_write_err != ESP_OK) {
break;
}
binary_file_len += data_read;
ESP_LOGD(TAG, "Written image length %d", binary_file_len);
}
}
free(upgrade_data_buf);
http_cleanup(client);
ESP_LOGD(TAG, "Total binary data length writen: %d", binary_file_len);
esp_err_t ota_end_err = esp_ota_end(update_handle);
if (ota_write_err != ESP_OK) {
ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%d", err);
return ota_write_err;
} else if (ota_end_err != ESP_OK) {
ESP_LOGE(TAG, "Error: esp_ota_end failed! err=0x%d. Image is invalid", ota_end_err);
return ota_end_err;
}
err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%d", err);
return err;
}
ESP_LOGI(TAG, "esp_ota_set_boot_partition succeeded");
return ESP_OK;
}