Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
fcc_sotp.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,get 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 <string.h> 00018 #include "fcc_sotp.h" 00019 #include "pv_error_handling.h" 00020 #include "kcm_internal.h" 00021 00022 static bool get_sotp_type_size(sotp_type_e sotp_type, uint16_t *required_size_out) 00023 { 00024 size_t required_size; 00025 00026 switch (sotp_type) { 00027 case SOTP_TYPE_ROT: 00028 required_size = FCC_ROT_SIZE; 00029 break; 00030 case SOTP_TYPE_FACTORY_DONE: 00031 required_size = FCC_FACTORY_DISABLE_FLAG_SIZE; 00032 break; 00033 case SOTP_TYPE_RANDOM_SEED: 00034 required_size = FCC_ENTROPY_SIZE; 00035 break; 00036 case SOTP_TYPE_SAVED_TIME: 00037 required_size = sizeof(uint64_t); 00038 break; 00039 case SOTP_TYPE_TRUSTED_TIME_SRV_ID: 00040 required_size = FCC_CA_IDENTIFICATION_SIZE; 00041 break; 00042 default: 00043 SA_PV_LOG_ERR("Wrong sotp_type"); 00044 return false; 00045 } 00046 00047 // Success 00048 *required_size_out = (uint16_t)required_size; 00049 00050 return true; 00051 } 00052 00053 static fcc_status_e sotp_to_fcc_error_translation(sotp_result_e err) 00054 { 00055 fcc_status_e fcc_result; 00056 switch(err) 00057 { 00058 case SOTP_SUCCESS: 00059 fcc_result = FCC_STATUS_SUCCESS; 00060 break; 00061 case SOTP_NOT_FOUND: 00062 fcc_result = FCC_STATUS_ITEM_NOT_EXIST; 00063 break; 00064 case SOTP_ALREADY_EXISTS: 00065 fcc_result = FCC_STATUS_INTERNAL_ITEM_ALREADY_EXIST; 00066 break; 00067 case SOTP_READ_ERROR: 00068 case SOTP_WRITE_ERROR: 00069 case SOTP_DATA_CORRUPT: 00070 case SOTP_BAD_VALUE: 00071 case SOTP_BUFF_TOO_SMALL: 00072 case SOTP_FLASH_AREA_TOO_SMALL: 00073 case SOTP_OS_ERROR: 00074 case SOTP_BUFF_NOT_ALIGNED: 00075 default: 00076 fcc_result = FCC_STATUS_STORE_ERROR; 00077 break; 00078 } 00079 return fcc_result; 00080 } 00081 00082 00083 fcc_status_e fcc_sotp_data_store(const uint8_t *data, size_t data_size, sotp_type_e sotp_type) 00084 { 00085 bool success; 00086 sotp_result_e sotp_result; 00087 uint16_t required_size = 0; 00088 int64_t aligned_8_bytes_buffer[MAX_SOTP_BUFFER_SIZE / 8]; 00089 uint16_t sotp_buffer_size = 0; 00090 00091 SA_PV_LOG_INFO_FUNC_ENTER("data_size = %" PRIu32 " sotp_type = %d", (uint32_t)data_size, (int)sotp_type); 00092 00093 SA_PV_ERR_RECOVERABLE_RETURN_IF((data == NULL), FCC_STATUS_INVALID_PARAMETER, "Invalid param data"); 00094 00095 success = get_sotp_type_size(sotp_type, &required_size); 00096 SA_PV_ERR_RECOVERABLE_RETURN_IF((!success), FCC_STATUS_INVALID_PARAMETER, "Failed for get_sotp_type_size()"); 00097 00098 if (sotp_type != SOTP_TYPE_SAVED_TIME) { 00099 //Check if current type was already written to sotp by triyng to get the data 00100 sotp_result = sotp_get_item_size(sotp_type, &sotp_buffer_size); 00101 SA_PV_ERR_RECOVERABLE_RETURN_IF((sotp_result == SOTP_SUCCESS), FCC_STATUS_INTERNAL_ITEM_ALREADY_EXIST, "The item was already written to sotp"); 00102 } 00103 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_size != required_size), FCC_STATUS_INVALID_PARAMETER, "Wrong buf_size provided. Must be size of exactly %" PRIu32 " bytes", (uint32_t)required_size); 00104 00105 // Write buf to SOTP. Cast is OK since size must be divisible by 8 00106 00107 /* 00108 * Copy from data (uint8_t*) to aligned_8_bytes_buffer (uint64_t*) to make sure that data is 8 byte aligned. 00109 * Since sotp_set() gets a pointer to int64_t, if it is not aligned, and we just cast it to uint8_t*, 00110 * ARMCC functions like memcpy will assume 8 byte alignment resulting in possible access of unallocated memory. 00111 */ 00112 memcpy(aligned_8_bytes_buffer, data, data_size); 00113 00114 sotp_result = sotp_set(sotp_type, (uint16_t)(data_size), (const uint32_t*)aligned_8_bytes_buffer); 00115 SA_PV_ERR_RECOVERABLE_RETURN_IF((sotp_result != SOTP_SUCCESS) , sotp_to_fcc_error_translation(sotp_result), "SOTP set failed"); 00116 00117 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00118 00119 return FCC_STATUS_SUCCESS; 00120 } 00121 00122 00123 fcc_status_e fcc_sotp_data_retrieve(uint8_t *data_out, size_t data_size_max, size_t *data_actual_size_out, sotp_type_e sotp_type) 00124 { 00125 bool success; 00126 sotp_result_e sotp_result; 00127 uint16_t required_size = 0; 00128 int64_t aligned_8_bytes_buffer[MAX_SOTP_BUFFER_SIZE / 8] = {0}; 00129 uint16_t actual_data_size = 0; 00130 00131 SA_PV_LOG_INFO_FUNC_ENTER("data_out = %" PRIu32 " sotp_type = %d", (uint32_t)data_size_max, (int)sotp_type); 00132 00133 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_out == NULL), FCC_STATUS_INVALID_PARAMETER, "invalid param data_out"); 00134 00135 success = get_sotp_type_size(sotp_type, &required_size); 00136 SA_PV_ERR_RECOVERABLE_RETURN_IF((!success), FCC_STATUS_INVALID_PARAMETER, "Failed for get_sotp_type_size()"); 00137 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_size_max < required_size), FCC_STATUS_ERROR, "Wrong buf_size provided. Must be size of exactly %" PRIu32 " bytes", (uint32_t)required_size); 00138 00139 // Retrieve buf from SOTP. Cast is OK since size must be multiple of 8 00140 sotp_result = sotp_get(sotp_type, (uint16_t)data_size_max, (uint32_t*)aligned_8_bytes_buffer, &actual_data_size); 00141 if (sotp_result == SOTP_NOT_FOUND) { //To prevent error log for positive flows 00142 return sotp_to_fcc_error_translation(sotp_result); 00143 } 00144 SA_PV_ERR_RECOVERABLE_RETURN_IF((sotp_result != SOTP_SUCCESS), sotp_to_fcc_error_translation(sotp_result), "SOTP_Get failed"); 00145 00146 // Copy from aligned buffer to callers uint8_t* buffer 00147 memcpy(data_out, aligned_8_bytes_buffer, actual_data_size); 00148 00149 *data_actual_size_out = (size_t)(actual_data_size); 00150 00151 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00152 00153 return FCC_STATUS_SUCCESS; 00154 } 00155
Generated on Tue Jul 12 2022 19:01:34 by 1.7.2