@@ -44,6 +44,7 @@ LOG_MODULE_REGISTER(hawkbit, CONFIG_HAWKBIT_LOG_LEVEL);
44
44
#define SHA256_HASH_SIZE 32
45
45
#define RESPONSE_BUFFER_SIZE 1100
46
46
#define DDI_SECURITY_TOKEN_SIZE 32
47
+ #define RANGE_HEADER_SIZE 50
47
48
#define HAWKBIT_RECV_TIMEOUT (300 * MSEC_PER_SEC)
48
49
#define HAWKBIT_SET_SERVER_TIMEOUT K_MSEC(300)
49
50
@@ -115,8 +116,6 @@ static struct hawkbit_config {
115
116
#endif /* CONFIG_HAWKBIT_USE_DYNAMIC_CERT_TAG */
116
117
117
118
struct hawkbit_download {
118
- int download_status ;
119
- int download_progress ;
120
119
size_t downloaded_size ;
121
120
size_t http_content_size ;
122
121
uint8_t file_hash [SHA256_HASH_SIZE ];
@@ -343,6 +342,13 @@ static int hawkbit_settings_set(const char *name, size_t len, settings_read_cb r
343
342
return 0 ;
344
343
}
345
344
#endif /* CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME */
345
+ /* This is to omit the error message, as that is fetched in stream_flash_progress_load()
346
+ * and we don't need to get it here.
347
+ */
348
+ if (IS_ENABLED (CONFIG_HAWKBIT_SAVE_PROGRESS ) &&
349
+ settings_name_steq (name , "flash_progress" , NULL )) {
350
+ return 0 ;
351
+ }
346
352
347
353
return - ENOENT ;
348
354
}
@@ -864,123 +870,146 @@ int hawkbit_init(void)
864
870
return ret ;
865
871
}
866
872
867
- static void response_cb (struct http_response * rsp , enum http_final_call final_data , void * userdata )
873
+ static void response_json_cb (struct http_response * rsp , enum http_final_call final_data ,
874
+ struct hawkbit_context * hb_context )
868
875
{
869
- struct hawkbit_context * hb_context = userdata ;
870
876
size_t body_len ;
871
- int ret , downloaded ;
877
+ int ret ;
872
878
uint8_t * body_data = NULL , * rsp_tmp = NULL ;
873
879
874
- if (rsp -> http_status_code != 200 ) {
875
- LOG_ERR ("HTTP request denied: %d" , rsp -> http_status_code );
876
- if (rsp -> http_status_code == 401 || rsp -> http_status_code == 403 ) {
877
- hb_context -> code_status = HAWKBIT_PERMISSION_ERROR ;
878
- } else {
879
- hb_context -> code_status = HAWKBIT_METADATA_ERROR ;
880
- }
881
- return ;
880
+ if (hb_context -> dl .http_content_size == 0 ) {
881
+ hb_context -> dl .http_content_size = rsp -> content_length ;
882
882
}
883
883
884
- switch (hb_context -> type ) {
885
- case HAWKBIT_PROBE :
886
- case HAWKBIT_PROBE_DEPLOYMENT_BASE :
887
- if (hb_context -> dl .http_content_size == 0 ) {
888
- hb_context -> dl .http_content_size = rsp -> content_length ;
889
- }
884
+ if (rsp -> body_found ) {
885
+ body_data = rsp -> body_frag_start ;
886
+ body_len = rsp -> body_frag_len ;
890
887
891
- if (rsp -> body_found ) {
892
- body_data = rsp -> body_frag_start ;
893
- body_len = rsp -> body_frag_len ;
894
-
895
- if ((hb_context -> dl .downloaded_size + body_len ) >
896
- hb_context -> response_data_size ) {
897
- hb_context -> response_data_size =
898
- hb_context -> dl .downloaded_size + body_len ;
899
- rsp_tmp = k_realloc (hb_context -> response_data ,
900
- hb_context -> response_data_size );
901
- if (rsp_tmp == NULL ) {
902
- LOG_ERR ("Failed to realloc memory" );
903
- hb_context -> code_status = HAWKBIT_ALLOC_ERROR ;
904
- break ;
905
- }
906
-
907
- hb_context -> response_data = rsp_tmp ;
888
+ if ((hb_context -> dl .downloaded_size + body_len ) >
889
+ hb_context -> response_data_size ) {
890
+ hb_context -> response_data_size =
891
+ hb_context -> dl .downloaded_size + body_len ;
892
+ rsp_tmp = k_realloc (hb_context -> response_data ,
893
+ hb_context -> response_data_size );
894
+ if (rsp_tmp == NULL ) {
895
+ LOG_ERR ("Failed to realloc memory" );
896
+ hb_context -> code_status = HAWKBIT_ALLOC_ERROR ;
897
+ return ;
908
898
}
909
- strncpy (hb_context -> response_data + hb_context -> dl .downloaded_size ,
910
- body_data , body_len );
911
- hb_context -> dl .downloaded_size += body_len ;
899
+
900
+ hb_context -> response_data = rsp_tmp ;
912
901
}
902
+ strncpy (hb_context -> response_data + hb_context -> dl .downloaded_size ,
903
+ body_data , body_len );
904
+ hb_context -> dl .downloaded_size += body_len ;
905
+ }
913
906
914
- if (final_data == HTTP_DATA_FINAL ) {
915
- if (hb_context -> dl .http_content_size != hb_context -> dl .downloaded_size ) {
916
- LOG_ERR ("HTTP response len mismatch, expected %d, got %d" ,
917
- hb_context -> dl .http_content_size ,
918
- hb_context -> dl .downloaded_size );
907
+ if (final_data == HTTP_DATA_FINAL ) {
908
+ if (hb_context -> dl .http_content_size != hb_context -> dl .downloaded_size ) {
909
+ LOG_ERR ("HTTP response len mismatch, expected %d, got %d" ,
910
+ hb_context -> dl .http_content_size ,
911
+ hb_context -> dl .downloaded_size );
912
+ hb_context -> code_status = HAWKBIT_METADATA_ERROR ;
913
+ return ;
914
+ }
915
+
916
+ hb_context -> response_data [hb_context -> dl .downloaded_size ] = '\0' ;
917
+ memset (& hb_context -> results , 0 , sizeof (hb_context -> results ));
918
+ if (hb_context -> type == HAWKBIT_PROBE ) {
919
+ ret = json_obj_parse (
920
+ hb_context -> response_data , hb_context -> dl .downloaded_size ,
921
+ json_ctl_res_descr , ARRAY_SIZE (json_ctl_res_descr ),
922
+ & hb_context -> results .base );
923
+ if (ret < 0 ) {
924
+ LOG_ERR ("JSON parse error (%s): %d" , "HAWKBIT_PROBE" , ret );
919
925
hb_context -> code_status = HAWKBIT_METADATA_ERROR ;
920
- break ;
921
926
}
922
-
923
- hb_context -> response_data [hb_context -> dl .downloaded_size ] = '\0' ;
924
- memset (& hb_context -> results , 0 , sizeof (hb_context -> results ));
925
- if (hb_context -> type == HAWKBIT_PROBE ) {
926
- ret = json_obj_parse (
927
- hb_context -> response_data , hb_context -> dl .downloaded_size ,
928
- json_ctl_res_descr , ARRAY_SIZE (json_ctl_res_descr ),
929
- & hb_context -> results .base );
930
- if (ret < 0 ) {
931
- LOG_ERR ("JSON parse error (%s): %d" , "HAWKBIT_PROBE" , ret );
932
- hb_context -> code_status = HAWKBIT_METADATA_ERROR ;
933
- }
934
- } else {
935
- ret = json_obj_parse (
936
- hb_context -> response_data , hb_context -> dl .downloaded_size ,
937
- json_dep_res_descr , ARRAY_SIZE (json_dep_res_descr ),
938
- & hb_context -> results .dep );
939
- if (ret < 0 ) {
940
- LOG_ERR ("JSON parse error (%s): %d" , "deploymentBase" , ret );
941
- hb_context -> code_status = HAWKBIT_METADATA_ERROR ;
942
- }
927
+ } else {
928
+ ret = json_obj_parse (
929
+ hb_context -> response_data , hb_context -> dl .downloaded_size ,
930
+ json_dep_res_descr , ARRAY_SIZE (json_dep_res_descr ),
931
+ & hb_context -> results .dep );
932
+ if (ret < 0 ) {
933
+ LOG_ERR ("JSON parse error (%s): %d" , "deploymentBase" , ret );
934
+ hb_context -> code_status = HAWKBIT_METADATA_ERROR ;
943
935
}
944
936
}
937
+ }
938
+ }
945
939
946
- break ;
947
-
948
- case HAWKBIT_DOWNLOAD :
949
- if (hb_context -> dl .http_content_size == 0 ) {
950
- hb_context -> dl .http_content_size = rsp -> content_length ;
940
+ static void response_download_cb (struct http_response * rsp , enum http_final_call final_data ,
941
+ struct hawkbit_context * hb_context )
942
+ {
943
+ size_t body_len ;
944
+ int ret , downloaded ;
945
+ uint8_t * body_data = NULL ;
946
+ static uint8_t download_progress ;
947
+
948
+ if (hb_context -> dl .http_content_size == 0 ) {
949
+ hb_context -> dl .http_content_size = rsp -> content_length ;
950
+ download_progress = 0 ;
951
+ if (IS_ENABLED (CONFIG_HAWKBIT_SAVE_PROGRESS ) && rsp -> http_status_code != 206 ) {
952
+ hb_context -> flash_ctx .stream .bytes_written = 0 ;
951
953
}
954
+ }
952
955
953
- if (rsp -> body_found ) {
954
- body_data = rsp -> body_frag_start ;
955
- body_len = rsp -> body_frag_len ;
956
+ if (rsp -> body_found ) {
957
+ body_data = rsp -> body_frag_start ;
958
+ body_len = rsp -> body_frag_len ;
956
959
957
- ret = flash_img_buffered_write (& hb_context -> flash_ctx , body_data , body_len ,
958
- final_data == HTTP_DATA_FINAL );
959
- if (ret < 0 ) {
960
- LOG_ERR ("Failed to write flash: %d" , ret );
961
- hb_context -> code_status = HAWKBIT_DOWNLOAD_ERROR ;
962
- break ;
963
- }
960
+ ret = flash_img_buffered_write (& hb_context -> flash_ctx , body_data , body_len ,
961
+ final_data == HTTP_DATA_FINAL );
962
+ if (ret < 0 ) {
963
+ LOG_ERR ("Failed to write flash: %d" , ret );
964
+ hb_context -> code_status = HAWKBIT_DOWNLOAD_ERROR ;
965
+ return ;
964
966
}
965
967
966
- hb_context -> dl .downloaded_size = flash_img_bytes_written (& hb_context -> flash_ctx );
968
+ #ifdef CONFIG_HAWKBIT_SAVE_PROGRESS
969
+ stream_flash_progress_save (& hb_context -> flash_ctx .stream , "hawkbit/flash_progress" );
970
+ #endif
971
+ }
967
972
968
- downloaded =
969
- hb_context -> dl .downloaded_size * 100 / hb_context -> dl .http_content_size ;
973
+ hb_context -> dl .downloaded_size = flash_img_bytes_written (& hb_context -> flash_ctx );
970
974
971
- if (downloaded > hb_context -> dl .download_progress ) {
972
- hb_context -> dl .download_progress = downloaded ;
973
- LOG_DBG ("Downloaded: %d%% " , hb_context -> dl .download_progress );
974
- }
975
+ downloaded = hb_context -> dl .downloaded_size * 100 / hb_context -> dl .file_size ;
976
+
977
+ if (downloaded != download_progress ) {
978
+ download_progress = downloaded ;
979
+ LOG_DBG ("Downloaded: %u%% (%u / %u)" , download_progress ,
980
+ hb_context -> dl .downloaded_size , hb_context -> dl .file_size );
981
+ }
982
+
983
+ if (final_data == HTTP_DATA_FINAL ) {
984
+ hb_context -> final_data_received = true;
985
+ }
986
+ }
975
987
976
- if (final_data == HTTP_DATA_FINAL ) {
977
- hb_context -> final_data_received = true;
988
+ static void response_cb (struct http_response * rsp , enum http_final_call final_data , void * userdata )
989
+ {
990
+ struct hawkbit_context * hb_context = userdata ;
991
+
992
+ if (!IN_RANGE (rsp -> http_status_code , 200 , 299 )) {
993
+ LOG_ERR ("HTTP request denied: %d" , rsp -> http_status_code );
994
+ if (rsp -> http_status_code == 401 || rsp -> http_status_code == 403 ) {
995
+ hb_context -> code_status = HAWKBIT_PERMISSION_ERROR ;
996
+ } else {
997
+ hb_context -> code_status = HAWKBIT_METADATA_ERROR ;
978
998
}
999
+ return ;
1000
+ }
979
1001
1002
+ switch (hb_context -> type ) {
1003
+ case HAWKBIT_PROBE :
1004
+ case HAWKBIT_PROBE_DEPLOYMENT_BASE :
1005
+ response_json_cb (rsp , final_data , hb_context );
980
1006
break ;
981
1007
982
- default :
1008
+ case HAWKBIT_DOWNLOAD :
1009
+ response_download_cb (rsp , final_data , hb_context );
1010
+ break ;
983
1011
1012
+ default :
984
1013
break ;
985
1014
}
986
1015
}
@@ -1055,6 +1084,13 @@ static bool send_request(struct hawkbit_context *hb_context, enum hawkbit_http_r
1055
1084
* Resource for software module (Deployment Base)
1056
1085
* GET: /{tenant}/controller/v1/{controllerId}/deploymentBase/{actionId}
1057
1086
*/
1087
+
1088
+ http_req .method = HTTP_GET ;
1089
+ hb_context -> dl .http_content_size = 0 ;
1090
+ hb_context -> dl .downloaded_size = 0 ;
1091
+
1092
+ break ;
1093
+
1058
1094
case HAWKBIT_DOWNLOAD :
1059
1095
/*
1060
1096
* Resource for software module (Deployment Base)
@@ -1063,7 +1099,23 @@ static bool send_request(struct hawkbit_context *hb_context, enum hawkbit_http_r
1063
1099
*/
1064
1100
http_req .method = HTTP_GET ;
1065
1101
hb_context -> dl .http_content_size = 0 ;
1102
+
1103
+ #ifdef CONFIG_HAWKBIT_SAVE_PROGRESS
1104
+ hb_context -> dl .downloaded_size = flash_img_bytes_written (& hb_context -> flash_ctx );
1105
+ if (IN_RANGE (hb_context -> dl .downloaded_size , 1 , hb_context -> dl .file_size )) {
1106
+ char header_range [RANGE_HEADER_SIZE ] = {0 };
1107
+
1108
+ snprintf (header_range , sizeof (header_range ), "Range: bytes=%u-" HTTP_CRLF ,
1109
+ hb_context -> dl .downloaded_size );
1110
+ const char * const headers_range [] = {header_range , NULL };
1111
+
1112
+ http_req .optional_headers = (const char * * )headers_range ;
1113
+ LOG_DBG ("optional header: %s" , header_range );
1114
+ LOG_INF ("Resuming download from %d bytes" , hb_context -> dl .downloaded_size );
1115
+ }
1116
+ #else
1066
1117
hb_context -> dl .downloaded_size = 0 ;
1118
+ #endif
1067
1119
1068
1120
break ;
1069
1121
@@ -1459,6 +1511,10 @@ static void s_download(void *o)
1459
1511
*/
1460
1512
flash_area_ptr = s -> hb_context .flash_ctx .flash_area ;
1461
1513
1514
+ #ifdef CONFIG_HAWKBIT_SAVE_PROGRESS
1515
+ stream_flash_progress_load (& s -> hb_context .flash_ctx .stream , "hawkbit/flash_progress" );
1516
+ #endif
1517
+
1462
1518
if (!send_request (& s -> hb_context , HAWKBIT_DOWNLOAD , url_buffer , NULL )) {
1463
1519
LOG_ERR ("Send request failed (%s)" , "HAWKBIT_DOWNLOAD" );
1464
1520
smf_set_state (SMF_CTX (s ), & hawkbit_states [S_HAWKBIT_TERMINATE ]);
@@ -1473,6 +1529,10 @@ static void s_download(void *o)
1473
1529
return ;
1474
1530
}
1475
1531
1532
+ #ifdef CONFIG_HAWKBIT_SAVE_PROGRESS
1533
+ stream_flash_progress_clear (& s -> hb_context .flash_ctx .stream , "hawkbit/flash_progress" );
1534
+ #endif
1535
+
1476
1536
/* Verify the hash of the stored firmware */
1477
1537
fic .match = s -> hb_context .dl .file_hash ;
1478
1538
fic .clen = s -> hb_context .dl .downloaded_size ;
0 commit comments