2222#include <bspatch.h>
2323#include <deflate.h>
2424
25- typedef struct {
26- jade_ota_ctx_t * joctx ;
27- char * id ;
28- struct deflate_ctx * const dctx ;
29- size_t written ;
30- bool header_validated ;
31- } bsdiff_ctx_t ;
32-
3325// Error reply in ota_delta is complicated by the fact that we reply 'ok' when we push the received patch data
3426// into the decompressor, but we carry on copying the base firmware and inflating/applying patch data.
3527// If an error occurs at this stage - we have no message id to reply to so must cache the error until we do receive
@@ -59,36 +51,36 @@ typedef struct {
5951// NOTE: uses macros above so may return error immediately, or may just cache it for later return
6052static int patch_stream_reader (const struct bspatch_stream * stream , void * buffer , int length )
6153{
62- bsdiff_ctx_t * bctx = (bsdiff_ctx_t * )stream -> opaque ;
63- JADE_ASSERT (bctx );
54+ jade_ota_ctx_t * joctx = (jade_ota_ctx_t * )stream -> opaque ;
55+ JADE_ASSERT (joctx );
6456
6557 if (length <= 0 ) {
66- HANDLE_NEW_ERROR (bctx -> joctx , ERROR_PATCH );
58+ HANDLE_NEW_ERROR (joctx , ERROR_PATCH );
6759 }
6860
6961 // Return any non-zero error code from the read routine
70- const int ret = read_uncompressed (bctx -> dctx , buffer , length );
62+ const int ret = read_uncompressed (joctx -> dctx , buffer , length );
7163 if (ret ) {
72- HANDLE_NEW_ERROR (bctx -> joctx , ret );
64+ HANDLE_NEW_ERROR (joctx , ret );
7365 }
7466
75- * bctx -> joctx -> remaining_uncompressed -= length ;
67+ * joctx -> remaining_uncompressed -= length ;
7668
7769 return SUCCESS ;
7870}
7971
8072// NOTE: uses macros above so may return error immediately, or may just cache it for later return
8173static int base_firmware_stream_reader (const struct bspatch_stream_i * stream , void * buffer , int pos , int length )
8274{
83- bsdiff_ctx_t * bctx = (bsdiff_ctx_t * )stream -> opaque ;
84- JADE_ASSERT (bctx );
75+ jade_ota_ctx_t * joctx = (jade_ota_ctx_t * )stream -> opaque ;
76+ JADE_ASSERT (joctx );
8577
8678 // If currently in error, return immediately without reading anything
87- HANDLE_ANY_CACHED_ERROR (bctx -> joctx );
79+ HANDLE_ANY_CACHED_ERROR (joctx );
8880
89- if (length <= 0 || pos + length >= bctx -> joctx -> running_partition -> size
90- || esp_partition_read (bctx -> joctx -> running_partition , pos , buffer , length ) != ESP_OK ) {
91- HANDLE_NEW_ERROR (bctx -> joctx , ERROR_PATCH );
81+ if (length <= 0 || pos + length >= joctx -> running_partition -> size
82+ || esp_partition_read (joctx -> running_partition , pos , buffer , length ) != ESP_OK ) {
83+ HANDLE_NEW_ERROR (joctx , ERROR_PATCH );
9284 }
9385
9486 return SUCCESS ;
@@ -97,37 +89,41 @@ static int base_firmware_stream_reader(const struct bspatch_stream_i* stream, vo
9789// NOTE: uses macros above so may return error immediately, or may just cache it for later return
9890static int ota_stream_writer (const struct bspatch_stream_n * stream , const void * buffer , int length )
9991{
100- bsdiff_ctx_t * bctx = (bsdiff_ctx_t * )stream -> opaque ;
101- JADE_ASSERT (bctx );
92+ jade_ota_ctx_t * joctx = (jade_ota_ctx_t * )stream -> opaque ;
93+ JADE_ASSERT (joctx );
10294
10395 // If currently in error, return immediately without writing anything
104- HANDLE_ANY_CACHED_ERROR (bctx -> joctx );
96+ HANDLE_ANY_CACHED_ERROR (joctx );
10597
106- if (length <= 0 || esp_ota_write (* bctx -> joctx -> ota_handle , buffer , length ) != ESP_OK ) {
107- HANDLE_NEW_ERROR (bctx -> joctx , ERROR_PATCH );
98+ if (length <= 0 || esp_ota_write (* joctx -> ota_handle , buffer , length ) != ESP_OK ) {
99+ HANDLE_NEW_ERROR (joctx , ERROR_PATCH );
108100 }
109101
110- if (!bctx -> header_validated && length >= CUSTOM_HEADER_MIN_WRITE ) {
111- const enum ota_status validation = ota_user_validation (bctx -> joctx , (uint8_t * )buffer );
102+ if (!* joctx -> validated_confirmed && length >= CUSTOM_HEADER_MIN_WRITE ) {
103+ const enum ota_status validation = ota_user_validation (joctx , (uint8_t * )buffer );
112104 if (validation != SUCCESS ) {
113- HANDLE_NEW_ERROR (bctx -> joctx , validation );
105+ HANDLE_NEW_ERROR (joctx , validation );
114106 }
115- bctx -> header_validated = true;
107+ * joctx -> validated_confirmed = true;
116108 }
117109
118- if (bctx -> joctx -> hash_type == HASHTYPE_FULLFWDATA ) {
110+ if (joctx -> hash_type == HASHTYPE_FULLFWDATA ) {
119111 // Add written to hash calculation
120- JADE_ZERO_VERIFY (mbedtls_sha256_update (bctx -> joctx -> sha_ctx , buffer , length ));
112+ JADE_ZERO_VERIFY (mbedtls_sha256_update (joctx -> sha_ctx , buffer , length ));
121113 }
122114
123- bctx -> written += length ;
115+ joctx -> fwwritten += length ;
116+
117+ // For a patch, the amount of patch data uncompressed should always be more than the
118+ // amount of new firmware we have written, because of additional patch meta-data.
119+ JADE_ASSERT (joctx -> uncompressedsize - * joctx -> remaining_uncompressed > joctx -> fwwritten );
124120
125- if (bctx -> written > CUSTOM_HEADER_MIN_WRITE && !bctx -> header_validated ) {
126- HANDLE_NEW_ERROR (bctx -> joctx , ERROR_PATCH );
121+ if (joctx -> fwwritten > CUSTOM_HEADER_MIN_WRITE && !* joctx -> validated_confirmed ) {
122+ HANDLE_NEW_ERROR (joctx , ERROR_PATCH );
127123 }
128124
129- if (bctx -> header_validated ) {
130- update_progress_bar (& bctx -> joctx -> progress_bar , bctx -> joctx -> firmwaresize , bctx -> written );
125+ if (* joctx -> validated_confirmed ) {
126+ update_progress_bar (& joctx -> progress_bar , joctx -> firmwaresize , joctx -> fwwritten );
131127 }
132128
133129 return SUCCESS ;
@@ -137,13 +133,12 @@ static int compressed_stream_reader(void* ctx)
137133{
138134 JADE_ASSERT (ctx );
139135
140- bsdiff_ctx_t * bctx = (bsdiff_ctx_t * )ctx ;
141- JADE_ASSERT (bctx -> joctx );
136+ jade_ota_ctx_t * joctx = (jade_ota_ctx_t * )ctx ;
142137
143138 // NOTE: the ota_return_status can be set via ptr in joctx
144139 // Return any error here as it can be returned to the caller in the message reply
145- jade_process_get_in_message (bctx -> joctx , & handle_in_bin_data , true);
146- return * bctx -> joctx -> ota_return_status ;
140+ jade_process_get_in_message (joctx , & handle_in_bin_data , true);
141+ return * joctx -> ota_return_status ;
147142}
148143
149144void ota_delta_process (void * process_ptr )
@@ -208,10 +203,7 @@ void ota_delta_process(void* process_ptr)
208203 struct deflate_ctx * dctx = JADE_MALLOC_PREFER_SPIRAM (sizeof (struct deflate_ctx ));
209204 jade_process_free_on_exit (process , dctx );
210205
211- bsdiff_ctx_t bctx = {
212- .dctx = dctx ,
213- };
214-
206+ bool validated_confirmed = false;
215207 size_t remaining_uncompressed = uncompressedpatchsize ;
216208
217209 jade_ota_ctx_t joctx = {
@@ -221,6 +213,7 @@ void ota_delta_process(void* process_ptr)
221213 .ota_handle = & ota_handle ,
222214 .dctx = dctx ,
223215 .id = id ,
216+ .validated_confirmed = & validated_confirmed ,
224217 .uncompressedsize = uncompressedpatchsize ,
225218 .remaining_uncompressed = & remaining_uncompressed ,
226219 .ota_return_status = & ota_return_status ,
@@ -232,9 +225,7 @@ void ota_delta_process(void* process_ptr)
232225 .expected_hash = expected_hash ,
233226 };
234227
235- bctx .joctx = & joctx ;
236-
237- int ret = deflate_init_read_uncompressed (dctx , compressedsize , compressed_stream_reader , & bctx );
228+ int ret = deflate_init_read_uncompressed (dctx , compressedsize , compressed_stream_reader , & joctx );
238229 JADE_ASSERT (!ret );
239230
240231 if (!ota_init (& joctx )) {
@@ -251,15 +242,15 @@ void ota_delta_process(void* process_ptr)
251242 struct bspatch_stream_n destination_firmware_stream_writer ;
252243 // new partition
253244 destination_firmware_stream_writer .write = & ota_stream_writer ;
254- destination_firmware_stream_writer .opaque = & bctx ;
245+ destination_firmware_stream_writer .opaque = & joctx ;
255246 // patch
256247 struct bspatch_stream stream ;
257248 stream .read = & patch_stream_reader ;
258- stream .opaque = & bctx ;
249+ stream .opaque = & joctx ;
259250 // old partition / base
260251 struct bspatch_stream_i basestream ;
261252 basestream .read = & base_firmware_stream_reader ;
262- basestream .opaque = & bctx ;
253+ basestream .opaque = & joctx ;
263254
264255 ota_return_status = SUCCESS ;
265256 ret = bspatch (
@@ -275,7 +266,7 @@ void ota_delta_process(void* process_ptr)
275266 // Uploading complete
276267 uploading = false;
277268
278- if (bctx . written != firmwaresize ) {
269+ if (joctx . fwwritten != firmwaresize ) {
279270 ota_return_status = ERROR_PATCH ;
280271 }
281272
0 commit comments