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