@@ -17,17 +17,9 @@ static const char *TAG = "manual_ota";
17
17
bool manual_ota::begin ()
18
18
{
19
19
if (status != state::UNDEF) {
20
- ESP_LOGE (TAG, " Invalid state" );
20
+ ESP_LOGE (TAG, " Invalid state for manual_ota::perform " );
21
21
return false ;
22
22
}
23
- status = state::INIT;
24
- esp_transport_handle_t tcp = esp_transport_tcp_init ();
25
- ssl_ = esp_transport_batch_tls_init (tcp, max_buffer_size_);
26
-
27
- esp_http_client_config_t config = { };
28
- config.skip_cert_common_name_check = true ;
29
- config.url = uri_;
30
- config.transport = ssl_;
31
23
const esp_partition_t *configured = esp_ota_get_boot_partition ();
32
24
const esp_partition_t *running = esp_ota_get_running_partition ();
33
25
@@ -36,38 +28,40 @@ bool manual_ota::begin()
36
28
return false ;
37
29
}
38
30
39
- http_ = esp_http_client_init (&config);
40
- if (http_ == nullptr ) {
41
- ESP_LOGE (TAG, " Failed to initialise HTTP connection" );
42
- return false ;
43
- }
44
- esp_http_client_set_method (http_, HTTP_METHOD_HEAD);
45
- esp_err_t err = esp_http_client_perform (http_);
46
- if (err == ESP_OK) {
47
- int http_status = esp_http_client_get_status_code (http_);
48
- if (http_status != HttpStatus_Ok) {
49
- ESP_LOGE (TAG, " Received incorrect http status %d" , http_status);
50
- return false ;
31
+ status = state::INIT;
32
+ max_buffer_size_ = size_ * 1024 ;
33
+ if (mode_ == mode::BATCH) {
34
+ #ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT
35
+ esp_transport_handle_t tcp = esp_transport_tcp_init ();
36
+ ssl_ = esp_transport_batch_tls_init (tcp, max_buffer_size_);
37
+ http_.config_ .transport = ssl_;
38
+ if (!esp_transport_batch_set_ca_cert (ssl_, http_.config_ .cert_pem , 0 )) {
39
+ return fail ();
51
40
}
52
- } else {
53
- ESP_LOGE (TAG, " ESP HTTP client perform failed: %d" , err);
41
+ if (!esp_transport_batch_set_cn (ssl_, common_name_)) {
42
+ return fail ();
43
+ }
44
+ #else
45
+ ESP_LOGE (TAG, " mode::BATCH Cannot be used without CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT" );
54
46
return false ;
47
+ #endif
48
+ }
49
+
50
+ if (!http_.init ()) {
51
+ return fail ();
52
+ }
53
+
54
+ image_length_ = http_.get_image_len ();
55
+ if (image_length_ <= 0 ) {
56
+ return fail ();
55
57
}
56
- image_length_ = esp_http_client_get_content_length (http_);
57
- ESP_LOGI (TAG, " image_length = %lld" , image_length_);
58
- esp_http_client_close (http_);
59
58
60
59
if (image_length_ > size_) {
61
- char *header_val = nullptr ;
62
- asprintf (&header_val, " bytes=0-%d" , max_buffer_size_ - 1 );
63
- if (header_val == nullptr ) {
64
- ESP_LOGE (TAG, " Failed to allocate memory for HTTP header" );
65
- return false ;
60
+ if (!http_.set_range (0 , max_buffer_size_ - 1 )) {
61
+ return fail ();
66
62
}
67
- esp_http_client_set_header (http_, " Range" , header_val);
68
- free (header_val);
69
63
}
70
- esp_http_client_set_method (http_, HTTP_METHOD_GET);
64
+ esp_http_client_set_method (http_. handle_ , HTTP_METHOD_GET);
71
65
72
66
partition_ = esp_ota_get_next_update_partition (nullptr );
73
67
if (partition_ == nullptr ) {
@@ -86,40 +80,42 @@ bool manual_ota::begin()
86
80
bool manual_ota::perform ()
87
81
{
88
82
if (status != state::IMAGE_CHECK && status != state::START) {
89
- ESP_LOGE (TAG, " Invalid state" );
83
+ ESP_LOGE (TAG, " Invalid state for manual_ota::perform " );
90
84
return false ;
91
85
}
92
- esp_err_t err = esp_http_client_open (http_, 0 );
86
+ esp_err_t err = esp_http_client_open (http_. handle_ , 0 );
93
87
if (err != ESP_OK) {
94
88
if (image_length_ == file_length_) {
95
89
status = state::END;
96
90
return false ;
97
91
}
98
92
99
- esp_http_client_close (http_);
93
+ esp_http_client_close (http_. handle_ );
100
94
ESP_LOGI (TAG, " Failed to open HTTP connection: %s" , esp_err_to_name (err));
101
95
if (reconnect_attempts_++ < max_reconnect_attempts_) {
102
- if (prepare_reconnect ()) {
103
- return true ; // will retry in the next iteration
104
- }
96
+ return true ; // will retry in the next iteration
105
97
}
106
- return fail_cleanup ();
98
+ return fail ();
107
99
}
108
- esp_http_client_fetch_headers (http_);
100
+ esp_http_client_fetch_headers (http_. handle_ );
109
101
110
- int batch_len = esp_transport_batch_tls_pre_read (ssl_, max_buffer_size_, timeout_ * 1000 );
111
- if (batch_len < 0 ) {
112
- ESP_LOGE (TAG, " Error: Failed to pre-read plain text data!" );
113
- return fail_cleanup ();
102
+ int batch_len = max_buffer_size_;
103
+ if (mode_ == mode::BATCH) {
104
+ batch_len = esp_transport_batch_tls_pre_read (ssl_, max_buffer_size_, timeout_ * 1000 );
105
+ if (batch_len < 0 ) {
106
+ ESP_LOGE (TAG, " Error: Failed to pre-read plain text data!" );
107
+ fail ();
108
+ return false ;
109
+ }
114
110
}
115
111
116
- int data_read = esp_http_client_read (http_, buffer_.data (), batch_len);
112
+ int data_read = esp_http_client_read (http_. handle_ , buffer_.data (), batch_len);
117
113
118
114
if (data_read < 0 ) {
119
115
ESP_LOGE (TAG, " Error: SSL data read error" );
120
- return fail_cleanup ();
116
+ return fail ();
121
117
} else if (data_read > 0 ) {
122
- esp_http_client_close (http_);
118
+ esp_http_client_close (http_. handle_ );
123
119
124
120
if (status == state::IMAGE_CHECK) {
125
121
esp_app_desc_t new_app_info;
@@ -146,28 +142,26 @@ bool manual_ota::perform()
146
142
ESP_LOGW (TAG, " New version is the same as invalid version." );
147
143
ESP_LOGW (TAG, " Previously, there was an attempt to launch the firmware with %s version, but it failed." , invalid_app_info.version );
148
144
ESP_LOGW (TAG, " The firmware has been rolled back to the previous version." );
149
- return fail_cleanup ();
145
+ return fail ();
150
146
}
151
147
}
152
148
153
149
status = state::START;
154
150
err = esp_ota_begin (partition_, OTA_WITH_SEQUENTIAL_WRITES, &update_handle_);
155
151
if (err != ESP_OK) {
156
152
ESP_LOGE (TAG, " esp_ota_begin failed (%s)" , esp_err_to_name (err));
157
- esp_ota_abort (update_handle_);
158
- return fail_cleanup ();
153
+ return fail ();
159
154
}
155
+ ota_begin = true ;
160
156
ESP_LOGI (TAG, " esp_ota_begin succeeded" );
161
157
} else {
162
158
ESP_LOGE (TAG, " Received chunk doesn't contain app descriptor" );
163
- esp_ota_abort (update_handle_);
164
- return fail_cleanup ();
159
+ return fail ();
165
160
}
166
161
}
167
162
err = esp_ota_write (update_handle_, (const void *)buffer_.data (), data_read);
168
163
if (err != ESP_OK) {
169
- esp_ota_abort (update_handle_);
170
- return fail_cleanup ();
164
+ return fail ();
171
165
}
172
166
file_length_ += data_read;
173
167
ESP_LOGI (TAG, " Written image length %d" , file_length_);
@@ -178,28 +172,22 @@ bool manual_ota::perform()
178
172
}
179
173
180
174
if (!prepare_reconnect ()) {
181
- esp_ota_abort (update_handle_);
182
- return fail_cleanup ();
175
+ return fail ();
183
176
}
184
177
185
178
} else if (data_read == 0 ) {
186
179
if (file_length_ == 0 ) {
187
180
// Try to handle possible HTTP redirections
188
- int status_code = esp_http_client_get_status_code (http_);
189
- ESP_LOGW (TAG, " Status code: %d" , status_code);
190
- err = esp_http_client_set_redirection (http_);
191
- if (err != ESP_OK) {
192
- ESP_LOGE (TAG, " URL redirection Failed" );
193
- esp_ota_abort (update_handle_);
194
- return fail_cleanup ();
181
+ if (!http_.handle_redirects ()) {
182
+ return fail ();
195
183
}
196
184
197
- err = esp_http_client_open (http_, 0 );
185
+ err = esp_http_client_open (http_. handle_ , 0 );
198
186
if (err != ESP_OK) {
199
187
ESP_LOGE (TAG, " Failed to open HTTP connection: %s" , esp_err_to_name (err));
200
- return fail_cleanup ();
188
+ return fail ();
201
189
}
202
- esp_http_client_fetch_headers (http_);
190
+ esp_http_client_fetch_headers (http_. handle_ );
203
191
}
204
192
}
205
193
@@ -208,36 +196,23 @@ bool manual_ota::perform()
208
196
209
197
bool manual_ota::prepare_reconnect ()
210
198
{
211
- esp_http_client_set_method (http_, HTTP_METHOD_GET);
212
- char *header_val = nullptr ;
213
- if ((image_length_ - file_length_) > max_buffer_size_) {
214
- asprintf (&header_val, " bytes=%d-%d" , file_length_, (file_length_ + max_buffer_size_ - 1 ));
215
- } else {
216
- asprintf (&header_val, " bytes=%d-" , file_length_);
217
- }
218
- if (header_val == nullptr ) {
219
- ESP_LOGE (TAG, " Failed to allocate memory for HTTP header" );
220
- return false ;
221
- }
222
- esp_http_client_set_header (http_, " Range" , header_val);
223
- free (header_val);
224
- return true ;
199
+ esp_http_client_set_method (http_.handle_ , HTTP_METHOD_GET);
200
+ return http_.set_range (file_length_,
201
+ (image_length_ - file_length_) > max_buffer_size_ ? (file_length_ + max_buffer_size_ - 1 ) : 0 );
225
202
}
226
203
227
- bool manual_ota::fail_cleanup ()
204
+ bool manual_ota::fail ()
228
205
{
229
- esp_http_client_close (http_);
230
- esp_http_client_cleanup (http_);
231
206
status = state::FAIL;
232
207
return false ;
233
208
}
234
209
235
210
bool manual_ota::end ()
236
211
{
237
212
if (status == state::END) {
238
- if (!esp_http_client_is_complete_data_received ( http_)) {
213
+ if (!http_. is_data_complete ( )) {
239
214
ESP_LOGE (TAG, " Error in receiving complete file" );
240
- return fail_cleanup ();
215
+ return fail ();
241
216
}
242
217
esp_err_t err = esp_ota_end (update_handle_);
243
218
if (err != ESP_OK) {
@@ -246,14 +221,97 @@ bool manual_ota::end()
246
221
} else {
247
222
ESP_LOGE (TAG, " esp_ota_end failed (%s)!" , esp_err_to_name (err));
248
223
}
249
- return fail_cleanup ();
224
+ return fail ();
250
225
}
226
+ ota_begin = false ;
251
227
err = esp_ota_set_boot_partition (partition_);
252
228
if (err != ESP_OK) {
253
229
ESP_LOGE (TAG, " esp_ota_set_boot_partition failed (%s)!" , esp_err_to_name (err));
254
- return fail_cleanup ();
230
+ return fail ();
255
231
}
256
232
return true ;
257
233
}
258
234
return false ;
259
235
}
236
+
237
+ manual_ota::~manual_ota ()
238
+ {
239
+ if (ota_begin) {
240
+ esp_ota_abort (update_handle_);
241
+ }
242
+ }
243
+
244
+ bool manual_ota::http_client::handle_redirects ()
245
+ {
246
+ int status_code = esp_http_client_get_status_code (handle_);
247
+ ESP_LOGW (TAG, " Status code: %d" , status_code);
248
+ esp_err_t err = esp_http_client_set_redirection (handle_);
249
+ if (err != ESP_OK) {
250
+ ESP_LOGE (TAG, " URL redirection Failed" );
251
+ return false ;
252
+ }
253
+
254
+ err = esp_http_client_open (handle_, 0 );
255
+ if (err != ESP_OK) {
256
+ ESP_LOGE (TAG, " Failed to open HTTP connection: %s" , esp_err_to_name (err));
257
+ return false ;
258
+ }
259
+ esp_http_client_fetch_headers (handle_);
260
+ return true ;
261
+ }
262
+
263
+ bool manual_ota::http_client::set_range (size_t from, size_t to)
264
+ {
265
+ char *header_val = nullptr ;
266
+ if (to != 0 ) {
267
+ asprintf (&header_val, " bytes=%d-%d" , from, to);
268
+ } else {
269
+ asprintf (&header_val, " bytes=%d-" , from);
270
+ }
271
+ if (header_val == nullptr ) {
272
+ ESP_LOGE (TAG, " Failed to allocate memory for HTTP header" );
273
+ return false ;
274
+ }
275
+ esp_http_client_set_header (handle_, " Range" , header_val);
276
+ free (header_val);
277
+ return true ;
278
+ }
279
+
280
+ bool manual_ota::http_client::is_data_complete ()
281
+ {
282
+ return esp_http_client_is_complete_data_received (handle_);
283
+ }
284
+
285
+ manual_ota::http_client::~http_client ()
286
+ {
287
+ if (handle_) {
288
+ esp_http_client_close (handle_);
289
+ esp_http_client_cleanup (handle_);
290
+ }
291
+ }
292
+
293
+ bool manual_ota::http_client::init ()
294
+ {
295
+ handle_ = esp_http_client_init (&config_);
296
+ return handle_ != nullptr ;
297
+ }
298
+
299
+ int64_t manual_ota::http_client::get_image_len ()
300
+ {
301
+ esp_http_client_set_method (handle_, HTTP_METHOD_HEAD);
302
+ esp_err_t err = esp_http_client_perform (handle_);
303
+ if (err == ESP_OK) {
304
+ int http_status = esp_http_client_get_status_code (handle_);
305
+ if (http_status != HttpStatus_Ok) {
306
+ ESP_LOGE (TAG, " Received incorrect http status %d" , http_status);
307
+ return -1 ;
308
+ }
309
+ } else {
310
+ ESP_LOGE (TAG, " ESP HTTP client perform failed: %d" , err);
311
+ return -1 ;
312
+ }
313
+ int64_t image_length = esp_http_client_get_content_length (handle_);
314
+ ESP_LOGI (TAG, " image_length = %lld" , image_length);
315
+ esp_http_client_close (handle_);
316
+ return image_length;
317
+ }
0 commit comments