Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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 if (ctx->is_file_size_checked == false) { 00428 kcm_status = storage_file_size_get_with_ctx(ctx, buffer_actual_size_out); 00429 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed getting file data size (kcm_status %d)", kcm_status); 00430 } 00431 00432 SA_PV_ERR_RECOVERABLE_RETURN_IF((buffer_size < ctx->file_size), KCM_STATUS_INSUFFICIENT_BUFFER, "Buffer too small"); 00433 00434 if (ctx->file_size != 0) { 00435 esfs_status = esfs_read(&ctx->esfs_file_h, buffer_out, buffer_size, buffer_actual_size_out); 00436 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed reading file data (esfs_status %d)", esfs_status); 00437 } 00438 00439 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00440 00441 return KCM_STATUS_SUCCESS; 00442 } 00443 00444 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) 00445 { 00446 esfs_result_e esfs_status; 00447 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00448 esfs_tlv_properties_t *meta_data_properties = NULL; 00449 uint32_t index = 0; 00450 00451 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00452 00453 SA_PV_ERR_RECOVERABLE_RETURN_IF((ctx == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid context"); 00454 SA_PV_ERR_RECOVERABLE_RETURN_IF((meta_data_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to meta_data_size_out"); 00455 SA_PV_ERR_RECOVERABLE_RETURN_IF((meta_data_index_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to meta_data_index_out"); 00456 SA_PV_ERR_RECOVERABLE_RETURN_IF((type >= KCM_MD_TYPE_MAX_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid meta data type"); 00457 00458 esfs_status = esfs_get_meta_data_properties(&ctx->esfs_file_h, &meta_data_properties); 00459 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed reading meta data properties (esfs_status %d)", esfs_status); 00460 00461 for (index = 0; index < meta_data_properties->number_of_items; index++) { 00462 if (type == meta_data_properties->tlv_items[index].type) { 00463 00464 *meta_data_size_out = (size_t)meta_data_properties->tlv_items[index].length_in_bytes; 00465 *meta_data_index_out = index; 00466 kcm_status = KCM_STATUS_SUCCESS; 00467 break; 00468 } 00469 } 00470 00471 if (index >= meta_data_properties->number_of_items) { 00472 return KCM_STATUS_META_DATA_NOT_FOUND; 00473 } 00474 00475 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00476 return kcm_status; 00477 } 00478 00479 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) 00480 { 00481 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00482 uint32_t index = 0; 00483 00484 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00485 00486 kcm_status = storage_file_get_meta_data_size_and_index(ctx, type, meta_data_size_out, &index); 00487 00488 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00489 return kcm_status; 00490 } 00491 00492 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) 00493 { 00494 esfs_result_e esfs_status; 00495 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00496 esfs_tlv_item_t meta_data_item; 00497 uint32_t index = 0; 00498 00499 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00500 00501 SA_PV_ERR_RECOVERABLE_RETURN_IF(buffer_out == NULL, KCM_STATUS_INVALID_PARAMETER, "Invalid pointer to kcm_meta_data"); 00502 00503 kcm_status = storage_file_get_meta_data_size_and_index(ctx, type, buffer_actual_size_out, &index); 00504 if (kcm_status == KCM_STATUS_META_DATA_NOT_FOUND) { 00505 return kcm_status; 00506 } 00507 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed reading meta data size and index"); 00508 00509 // return error in case the data buffer to read is too small 00510 SA_PV_ERR_RECOVERABLE_RETURN_IF((buffer_size < *buffer_actual_size_out), KCM_STATUS_INSUFFICIENT_BUFFER, "Data buffer to read is too small"); 00511 00512 meta_data_item.value = buffer_out; 00513 esfs_status = esfs_read_meta_data(&ctx->esfs_file_h, index, &meta_data_item); 00514 SA_PV_ERR_RECOVERABLE_RETURN_IF((esfs_status != ESFS_SUCCESS), error_handler(esfs_status), "Failed reading meta data (esfs_status %d)", esfs_status); 00515 00516 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00517 00518 return kcm_status; 00519 } 00520
Generated on Tue Jul 12 2022 19:01:37 by 1.7.2