Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
storage.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // Licensed under the Apache License, Version 2.0 (the "License"); 00005 // you may not use this file except in compliance with the License. 00006 // You may obtain a copy of the License at 00007 // 00008 // http://www.apache.org/licenses/LICENSE-2.0 00009 // 00010 // Unless required by applicable law or agreed to in writing, software 00011 // distributed under the License is distributed on an "AS IS" BASIS, 00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 // See the License for the specific language governing permissions and 00014 // limitations under the License. 00015 // ---------------------------------------------------------------------------- 00016 00017 #include <stdbool.h> 00018 #include "pv_error_handling.h" 00019 #include "storage.h" 00020 #include "esfs.h" 00021 00022 static kcm_status_e error_handler(esfs_result_e esfs_status) 00023 { 00024 switch (esfs_status) { 00025 case ESFS_SUCCESS: 00026 return KCM_STATUS_SUCCESS; 00027 case ESFS_INVALID_PARAMETER: 00028 return KCM_STATUS_INVALID_PARAMETER; 00029 case ESFS_BUFFER_TOO_SMALL: 00030 return KCM_STATUS_INSUFFICIENT_BUFFER; 00031 case ESFS_EXISTS: 00032 return KCM_STATUS_FILE_EXIST; 00033 case ESFS_NOT_EXISTS: 00034 return KCM_STATUS_ITEM_NOT_FOUND; 00035 case ESFS_INVALID_FILE_VERSION: 00036 return KCM_STATUS_INVALID_FILE_VERSION; 00037 case ESFS_CMAC_DOES_NOT_MATCH: 00038 return KCM_STATUS_FILE_CORRUPTED; 00039 case ESFS_ERROR: 00040 return KCM_STATUS_STORAGE_ERROR; 00041 case ESFS_HASH_CONFLICT: 00042 return KCM_STATUS_FILE_NAME_CORRUPTED; 00043 case ESFS_FILE_OPEN_FOR_READ: 00044 case ESFS_FILE_OPEN_FOR_WRITE: 00045 return KCM_STATUS_INVALID_FILE_ACCESS_MODE; 00046 default: 00047 return KCM_STATUS_UNKNOWN_STORAGE_ERROR; 00048 } 00049 } 00050 00051 00052 static bool is_file_accessible(const kcm_ctx_s *ctx) 00053 { 00054 // FIXME - We need to check file access availability by comparing KCM context TLVs vs the target file header stored in ESFS that contains 00055 // TLVs and access rights. In order to retrieve ESFS file TLVs and access rights we should use the following methods 00056 // that are currently not implemented: 00057 // - esfs_get_meta_data_qty 00058 // - esfs_get_meta_data_types 00059 // - esfs_get_meta_data_buffer_size 00060 // - esfs_read_meta_data 00061 // - esfs_get_meta_data_qty 00062 00063 ctx = ctx; // currently unused 00064 00065 return true; 00066 } 00067 00068 kcm_status_e storage_init() 00069 { 00070 esfs_result_e esfs_status; 00071 00072 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00073 00074 esfs_status = esfs_init(); 00075 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed initializing ESFS (esfs_status %d)", esfs_status); 00076 00077 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00078 00079 return KCM_STATUS_SUCCESS; 00080 } 00081 00082 kcm_status_e storage_finalize() 00083 { 00084 esfs_result_e esfs_status; 00085 00086 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00087 00088 esfs_status = esfs_finalize(); 00089 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed finalizing ESFS (esfs_status %d)", esfs_status); 00090 00091 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00092 00093 return KCM_STATUS_SUCCESS; 00094 } 00095 00096 kcm_status_e storage_reset() 00097 { 00098 esfs_result_e esfs_status; 00099 00100 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00101 00102 esfs_status = esfs_reset(); 00103 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed reset ESFS (esfs_status %d)", esfs_status); 00104 00105 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00106 00107 return KCM_STATUS_SUCCESS; 00108 } 00109 00110 00111 kcm_status_e storage_factory_reset() 00112 { 00113 esfs_result_e esfs_status; 00114 00115 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00116 00117 esfs_status = esfs_factory_reset(); 00118 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed factory reset ESFS (esfs_status %d)", esfs_status); 00119 00120 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00121 00122 return KCM_STATUS_SUCCESS; 00123 } 00124 00125 kcm_status_e storage_file_write(kcm_ctx_s *ctx, const uint8_t *file_name, size_t file_name_length, const uint8_t *data, size_t data_length, const kcm_meta_data_list_s *kcm_meta_data_list, bool is_factory, bool is_encrypted) 00126 { 00127 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00128 kcm_status_e close_file_status = KCM_STATUS_SUCCESS; 00129 00130 kcm_status = storage_file_create(ctx, file_name, file_name_length, kcm_meta_data_list, is_factory, is_encrypted); 00131 SA_PV_ERR_RECOVERABLE_RETURN_IF(kcm_status != KCM_STATUS_SUCCESS, kcm_status, "Failed to create new file"); 00132 00133 kcm_status = storage_file_write_with_ctx(ctx, data, data_length);// we don't check error because we need to close the file in any case 00134 00135 // Data is only guaranteed to be flushed to the media on efs_close. 00136 close_file_status = storage_file_close(ctx); 00137 00138 if (kcm_status != KCM_STATUS_SUCCESS) { // delete the file if didn't succeed to write 00139 (void)storage_file_delete(ctx, file_name, file_name_length); 00140 SA_PV_ERR_RECOVERABLE_RETURN(kcm_status, "Failed to write data"); 00141 } 00142 00143 SA_PV_ERR_RECOVERABLE_RETURN_IF(close_file_status != KCM_STATUS_SUCCESS, close_file_status, "Failed to close file"); 00144 00145 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00146 00147 return kcm_status; 00148 } 00149 00150 kcm_status_e storage_file_size_get(kcm_ctx_s *ctx, const uint8_t *file_name, size_t file_name_length, size_t *file_size_out) 00151 { 00152 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00153 kcm_status_e close_staus = KCM_STATUS_SUCCESS; 00154 00155 SA_PV_LOG_TRACE_FUNC_ENTER("file_name_length=%" PRIu32 "", (uint32_t)file_name_length); 00156 00157 kcm_status = storage_file_open(ctx, file_name, file_name_length); 00158 if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) { 00159 goto exit; 00160 } 00161 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to open the given file"); 00162 00163 kcm_status = storage_file_size_get_with_ctx(ctx, file_size_out); 00164 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed getting file size"); 00165 00166 exit: 00167 if (kcm_status != KCM_STATUS_ITEM_NOT_FOUND) { 00168 close_staus = storage_file_close(ctx); 00169 } 00170 if (kcm_status == KCM_STATUS_SUCCESS) { 00171 kcm_status = close_staus; 00172 } 00173 00174 return kcm_status; 00175 } 00176 00177 kcm_status_e storage_file_read(kcm_ctx_s *ctx, const uint8_t *file_name, size_t file_name_length, uint8_t *buffer_out, size_t buffer_size, size_t *buffer_actual_size_out) 00178 { 00179 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00180 kcm_status_e close_status = KCM_STATUS_SUCCESS; 00181 00182 kcm_status = storage_file_open(ctx, file_name, file_name_length); 00183 if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) { 00184 goto exit; 00185 } 00186 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to open the given file"); 00187 00188 kcm_status = storage_file_read_with_ctx(ctx, buffer_out, buffer_size, buffer_actual_size_out); 00189 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed ti read file"); 00190 00191 exit: 00192 if (kcm_status != KCM_STATUS_ITEM_NOT_FOUND) { 00193 close_status = storage_file_close(ctx); 00194 } 00195 if (kcm_status == KCM_STATUS_SUCCESS) { 00196 kcm_status = close_status; 00197 } 00198 00199 return kcm_status; 00200 } 00201 00202 kcm_status_e storage_file_delete(kcm_ctx_s *ctx, const uint8_t *file_name, size_t file_name_length) 00203 { 00204 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00205 esfs_result_e esfs_status; 00206 uint16_t esfs_mode = 0; // FIXME - Unused, yet implemented 00207 bool success; 00208 00209 SA_PV_LOG_TRACE_FUNC_ENTER("file_name_length=%" PRIu32 "", (uint32_t)file_name_length); 00210 00211 SA_PV_ERR_RECOVERABLE_RETURN_IF((file_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid file name context"); 00212 SA_PV_ERR_RECOVERABLE_RETURN_IF((file_name_length == 0), KCM_STATUS_INVALID_PARAMETER, "Got empty file name"); 00213 00214 esfs_status = esfs_open(file_name, file_name_length, &esfs_mode, &ctx->esfs_file_h); 00215 00216 //file does not exists, exit from delete function 00217 if (esfs_status == ESFS_NOT_EXISTS) { 00218 return error_handler(esfs_status); 00219 } 00220 00221 if (esfs_status != ESFS_SUCCESS) { //file exists but there is some corruption. We will delete the file without checking it's permissions 00222 SA_PV_LOG_ERR("The file exists but corrupted. Delete it without checking permissions"); 00223 esfs_status = ESFS_SUCCESS; 00224 00225 } else { // check permissions 00226 success = is_file_accessible(ctx); 00227 if (!success) { 00228 SA_PV_LOG_ERR("Caller has no access rights to the given file"); 00229 kcm_status = KCM_STATUS_NOT_PERMITTED; 00230 } 00231 00232 esfs_status = esfs_close(&ctx->esfs_file_h); 00233 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed closing file (esfs_status %d)", esfs_status); 00234 00235 if (kcm_status == KCM_STATUS_NOT_PERMITTED) { 00236 return kcm_status; 00237 } 00238 } 00239 00240 // Delete the file 00241 esfs_status = esfs_delete(file_name, file_name_length); 00242 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed deleting file (esfs_status %d)", esfs_status); 00243 00244 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00245 00246 return kcm_status; 00247 } 00248 00249 00250 kcm_status_e storage_file_create(kcm_ctx_s *ctx, const uint8_t *file_name, size_t file_name_length, const kcm_meta_data_list_s *kcm_meta_data_list, bool is_factory, bool is_encrypted) 00251 { 00252 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00253 esfs_result_e esfs_status; 00254 esfs_tlv_item_t meta_data_items[KCM_MD_TYPE_MAX_SIZE]; 00255 size_t meta_data_count = 0; 00256 uint16_t access_flags = 0; // owner, signed, encrypted, factory, extended ACL bit mask 00257 00258 SA_PV_LOG_TRACE_FUNC_ENTER("file_name_length=%" PRIu32 " ", (uint32_t)file_name_length); 00259 00260 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00261 SA_PV_ERR_RECOVERABLE_RETURN_IF((file_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid file name context"); 00262 SA_PV_ERR_RECOVERABLE_RETURN_IF((file_name_length == 0), KCM_STATUS_INVALID_PARAMETER, "Got empty file name"); 00263 00264 memset(ctx, 0, sizeof(kcm_ctx_s)); 00265 00266 if (is_factory) { 00267 access_flags |= ESFS_FACTORY_VAL; 00268 } 00269 if (is_encrypted) { 00270 access_flags |= ESFS_ENCRYPTED; 00271 } 00272 00273 // Convert kcm_meta_data_list to array of esfs_tlv_item 00274 if (kcm_meta_data_list != NULL) { 00275 for (meta_data_count = 0; meta_data_count < kcm_meta_data_list->meta_data_count; meta_data_count++) { 00276 meta_data_items[meta_data_count].type = kcm_meta_data_list->meta_data[meta_data_count].type; 00277 meta_data_items[meta_data_count].length_in_bytes = (uint16_t)kcm_meta_data_list->meta_data[meta_data_count].data_size; 00278 meta_data_items[meta_data_count].value = (void*)kcm_meta_data_list->meta_data[meta_data_count].data; 00279 } 00280 } 00281 00282 esfs_status = esfs_create(file_name, file_name_length, meta_data_items, meta_data_count, access_flags, &ctx->esfs_file_h); 00283 SA_PV_ERR_RECOVERABLE_GOTO_IF((esfs_status == ESFS_EXISTS), kcm_status = KCM_STATUS_FILE_EXIST, Exit, "File already exist in ESFS (esfs_status %" PRIu32 ")", (uint32_t)esfs_status); 00284 SA_PV_ERR_RECOVERABLE_GOTO_IF((esfs_status != ESFS_SUCCESS), kcm_status = error_handler(esfs_status), Exit, "Failed creating file (esfs_status %" PRIu32 ")", (uint32_t)esfs_status); 00285 00286 Exit: 00287 if (kcm_status != KCM_STATUS_SUCCESS) { 00288 memset(ctx, 0, sizeof(kcm_ctx_s)); 00289 } 00290 00291 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00292 00293 return kcm_status; 00294 } 00295 00296 /** Open existing file 00297 * 00298 * @param ctx KCM operation context. 00299 * @param file_name A binary blob that uniquely identifies the file 00300 * @param file_name_length The binary blob length in bytes. 00301 @param is_factory True if KCM item is factory item, or false otherwise 00302 @param is_encrypted True if KCM item should be encrypted, or false otherwise 00303 * 00304 * @returns 00305 * KCM_STATUS_SUCCESS in case of success otherwise one of kcm_status_e errors 00306 */ 00307 kcm_status_e storage_file_open(kcm_ctx_s *ctx, const uint8_t *file_name, size_t file_name_length) 00308 { 00309 00310 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00311 esfs_result_e esfs_status; 00312 uint16_t esfs_mode = 0; // FIXME - Unused, yet implemented 00313 bool success; 00314 00315 SA_PV_LOG_TRACE_FUNC_ENTER("file_name_length=%" PRIu32 "", (uint32_t)file_name_length); 00316 00317 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00318 SA_PV_ERR_RECOVERABLE_RETURN_IF((file_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid file name context"); 00319 SA_PV_ERR_RECOVERABLE_RETURN_IF((file_name_length == 0), KCM_STATUS_INVALID_PARAMETER, "Got empty file name"); 00320 00321 memset(ctx, 0, sizeof(kcm_ctx_s)); 00322 00323 esfs_status = esfs_open(file_name, file_name_length, &esfs_mode, &ctx->esfs_file_h); 00324 if (esfs_status == ESFS_NOT_EXISTS) { 00325 kcm_status = error_handler(esfs_status); 00326 goto Exit; 00327 } 00328 SA_PV_ERR_RECOVERABLE_GOTO_IF((esfs_status != ESFS_SUCCESS), kcm_status = error_handler(esfs_status), Exit, "Failed opening file (esfs_status %d)", esfs_status); 00329 00330 success = is_file_accessible(ctx); 00331 if (!success) { 00332 kcm_status = KCM_STATUS_NOT_PERMITTED; 00333 esfs_close(&ctx->esfs_file_h); 00334 memset(ctx, 0, sizeof(kcm_ctx_s)); 00335 } 00336 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, Exit, "Caller has no access rights to the given file"); 00337 00338 Exit: 00339 if (kcm_status != KCM_STATUS_SUCCESS) { 00340 memset(ctx, 0, sizeof(kcm_ctx_s)); 00341 } 00342 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00343 00344 return kcm_status; 00345 } 00346 00347 /** Close file in storage 00348 * 00349 * @param ctx KCM operation context. 00350 @param is_factory True if KCM item is factory item, or false otherwise 00351 @param is_encrypted True if KCM item should be encrypted, or false otherwise 00352 * 00353 * @returns 00354 * KCM_STATUS_SUCCESS in case of success otherwise one of kcm_status_e errors 00355 */ 00356 kcm_status_e storage_file_close(kcm_ctx_s *ctx) 00357 { 00358 esfs_result_e esfs_status; 00359 00360 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00361 00362 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00363 00364 // Data is only guaranteed to be flushed to the media on efs_close. 00365 esfs_status = esfs_close(&ctx->esfs_file_h); 00366 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed closing file (esfs_status %d)", esfs_status); 00367 00368 memset(ctx, 0, sizeof(kcm_ctx_s)); 00369 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00370 00371 return KCM_STATUS_SUCCESS; 00372 } 00373 00374 00375 kcm_status_e storage_file_write_with_ctx(kcm_ctx_s *ctx, const uint8_t *data, size_t data_length) 00376 { 00377 esfs_result_e esfs_status; 00378 00379 SA_PV_LOG_TRACE_FUNC_ENTER("data_length=%" PRIu32 "", (uint32_t)data_length); 00380 00381 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00382 SA_PV_ERR_RECOVERABLE_RETURN_IF(((data == NULL) && (data_length > 0)), KCM_STATUS_INVALID_PARAMETER, "Provided NULL data buffer and data_length greater than 0"); 00383 00384 if (data_length != 0) { 00385 esfs_status = esfs_write(&ctx->esfs_file_h, data, data_length); 00386 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed writing (%" PRIu32 " B) size to file (esfs_status %" PRIu32 ")", (uint32_t)data_length, (uint32_t)esfs_status); 00387 } 00388 00389 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00390 00391 return KCM_STATUS_SUCCESS; 00392 00393 } 00394 00395 kcm_status_e storage_file_size_get_with_ctx(kcm_ctx_s *ctx, size_t *file_size_out) 00396 { 00397 esfs_result_e esfs_status; 00398 00399 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00400 00401 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00402 SA_PV_ERR_RECOVERABLE_RETURN_IF((file_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to file size"); 00403 00404 esfs_status = esfs_file_size(&ctx->esfs_file_h, file_size_out); 00405 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed getting file size (esfs_status %d)", esfs_status); 00406 00407 ctx->is_file_size_checked = true; 00408 ctx->file_size = *file_size_out; 00409 00410 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00411 00412 return KCM_STATUS_SUCCESS; 00413 } 00414 00415 00416 kcm_status_e storage_file_read_with_ctx(kcm_ctx_s *ctx, uint8_t *buffer_out, size_t buffer_size, size_t *buffer_actual_size_out) 00417 { 00418 esfs_result_e esfs_status; 00419 kcm_status_e kcm_status; 00420 00421 SA_PV_LOG_TRACE_FUNC_ENTER("buffer_size=%" PRIu32 "", (uint32_t)buffer_size); 00422 00423 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00424 SA_PV_ERR_RECOVERABLE_RETURN_IF((buffer_out == NULL && buffer_size != 0), KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to read buffer"); 00425 SA_PV_ERR_RECOVERABLE_RETURN_IF((buffer_actual_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to output size"); 00426 00427 *buffer_actual_size_out = 0; 00428 00429 if (ctx->is_file_size_checked == false) { 00430 kcm_status = storage_file_size_get_with_ctx(ctx, buffer_actual_size_out); 00431 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed getting file data size (kcm_status %d)", kcm_status); 00432 } 00433 00434 SA_PV_ERR_RECOVERABLE_RETURN_IF((buffer_size < ctx->file_size), KCM_STATUS_INSUFFICIENT_BUFFER, "Buffer too small"); 00435 00436 if (ctx->file_size != 0) { 00437 esfs_status = esfs_read(&ctx->esfs_file_h, buffer_out, buffer_size, buffer_actual_size_out); 00438 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed reading file data (esfs_status %d)", esfs_status); 00439 } 00440 00441 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00442 00443 return KCM_STATUS_SUCCESS; 00444 } 00445 00446 static kcm_status_e storage_file_get_meta_data_size_and_index(kcm_ctx_s *ctx, kcm_meta_data_type_e type, size_t *meta_data_size_out, uint32_t *meta_data_index_out) 00447 { 00448 esfs_result_e esfs_status; 00449 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00450 esfs_tlv_properties_t *meta_data_properties = NULL; 00451 uint32_t index = 0; 00452 00453 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00454 00455 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00456 SA_PV_ERR_RECOVERABLE_RETURN_IF((meta_data_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to meta_data_size_out"); 00457 SA_PV_ERR_RECOVERABLE_RETURN_IF((meta_data_index_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to meta_data_index_out"); 00458 SA_PV_ERR_RECOVERABLE_RETURN_IF((type >= KCM_MD_TYPE_MAX_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid meta data type"); 00459 00460 esfs_status = esfs_get_meta_data_properties(&ctx->esfs_file_h, &meta_data_properties); 00461 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed reading meta data properties (esfs_status %d)", esfs_status); 00462 00463 for (index = 0; index < meta_data_properties->number_of_items; index++) { 00464 if (type == meta_data_properties->tlv_items[index].type) { 00465 00466 *meta_data_size_out = (size_t)meta_data_properties->tlv_items[index].length_in_bytes; 00467 *meta_data_index_out = index; 00468 kcm_status = KCM_STATUS_SUCCESS; 00469 break; 00470 } 00471 } 00472 00473 if (index >= meta_data_properties->number_of_items) { 00474 return KCM_STATUS_META_DATA_NOT_FOUND; 00475 } 00476 00477 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00478 return kcm_status; 00479 } 00480 00481 kcm_status_e storage_file_get_meta_data_size(kcm_ctx_s *ctx, kcm_meta_data_type_e type, size_t *meta_data_size_out) 00482 { 00483 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00484 uint32_t index = 0; 00485 00486 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00487 00488 kcm_status = storage_file_get_meta_data_size_and_index(ctx, type, meta_data_size_out, &index); 00489 00490 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00491 return kcm_status; 00492 } 00493 00494 kcm_status_e storage_file_read_meta_data_by_type(kcm_ctx_s *ctx, kcm_meta_data_type_e type, uint8_t *buffer_out, size_t buffer_size, size_t *buffer_actual_size_out) 00495 { 00496 esfs_result_e esfs_status; 00497 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00498 esfs_tlv_item_t meta_data_item; 00499 uint32_t index = 0; 00500 00501 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00502 00503 SA_PV_ERR_RECOVERABLE_RETURN_IF(buffer_out == NULL, KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to kcm_meta_data"); 00504 00505 kcm_status = storage_file_get_meta_data_size_and_index(ctx, type, buffer_actual_size_out, &index); 00506 if (kcm_status == KCM_STATUS_META_DATA_NOT_FOUND) { 00507 return kcm_status; 00508 } 00509 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed reading meta data size and index"); 00510 00511 // return error in case the data buffer to read is too small 00512 SA_PV_ERR_RECOVERABLE_RETURN_IF((buffer_size < *buffer_actual_size_out), KCM_STATUS_INSUFFICIENT_BUFFER, "Data buffer to read is too small"); 00513 00514 meta_data_item.value = buffer_out; 00515 esfs_status = esfs_read_meta_data(&ctx->esfs_file_h, index, &meta_data_item); 00516 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed reading meta data (esfs_status %d)", esfs_status); 00517 00518 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00519 00520 return kcm_status; 00521 } 00522
Generated on Tue Jul 12 2022 16:24:21 by
1.7.2