Simple interface for Mbed Cloud Client

Dependents:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fcc_sotp.c Source File

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