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.
Dependencies: FXAS21002 FXOS8700Q
pal_plat_time.c
00001 /******************************************************************************* 00002 * Copyright 2016-2018 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 //! This module implements the Time platform API using the storage_rbp as storage backend 00018 // and optionally setting the system RTC to match the "secure time". Generic idea 00019 // is to prevent attack by setting clock backwards and to have some idea of current 00020 // time across system power cycle, even if the system does not have a battery backed RTC. 00021 00022 #include "pal.h" 00023 #include "pal_time.h" 00024 #include "pal_plat_time.h" 00025 #include "storage.h" 00026 #include <stdlib.h> 00027 00028 00029 #define TRACE_GROUP "PAL" 00030 00031 PAL_PRIVATE palStatus_t pal_plat_setWeakTimeForward(uint64_t setNewTimeInSeconds, uint64_t currentOsTime); 00032 PAL_PRIVATE palStatus_t pal_plat_setWeakTimeBackward(uint64_t setNewTimeInSeconds, uint64_t currentOsTime); 00033 00034 static uint64_t g_palDeviceBootTimeInSec = 0; 00035 00036 palStatus_t pal_plat_initTime(void) 00037 { 00038 uint64_t rtcTime = 0; 00039 uint64_t getTime = 0, lastTimeBack = 0; 00040 palStatus_t ret = PAL_SUCCESS; 00041 palStatus_t pal_status = PAL_SUCCESS; 00042 size_t actualLenBytes = 0; 00043 00044 ret = storage_rbp_read(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&getTime, sizeof(uint64_t), &actualLenBytes); 00045 //In case the weak time corrupted (could be due to power failure) : 00046 // 1. Set 0 getTime 00047 // 2. Rewrite STORAGE_RBP_SAVED_TIME_NAME with 0, to avoid an error in pal_plat_osSetStrongTime later, when the function tries first to read the weak time. 00048 // 3. Avoid error status and continue. 00049 if ((ret != PAL_SUCCESS) && (ret != PAL_ERR_ITEM_NOT_EXIST )) 00050 { 00051 getTime = 0; 00052 //Rewrite weak time to avoid error in pal_plat_osSetStrongTime 00053 ret = storage_rbp_write(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&getTime, sizeof(uint64_t), false); 00054 pal_status = ret; 00055 } 00056 00057 ret = storage_rbp_read(STORAGE_RBP_LAST_TIME_BACK_NAME, (uint8_t *)&lastTimeBack, sizeof(uint64_t),&actualLenBytes); 00058 //Strong time : avoid error, reset device time and continue 00059 //In case the strong time corrupted (could be due to power failure) : 00060 //1. Set device time to 0,to enforce the device to update the time against trusted server later. 00061 //2. Set 0 lastTimeBack 00062 //3. Rewrite STORAGE_RBP_LAST_TIME_BACK_NAME with 0, to avoid an error in pal_plat_osSetWeak later, when the functions could try first to read the strong time. 00063 //4. Set weak time value getTime to 0 , to avoid setting of the value to device time with pal_status = pal_osSetTime(PAL_MAX(rtcTime, getTime)) , 00064 // that called in this function later. In case of strong time corruption, we need to keep the device time value - 0. 00065 if ((ret != PAL_SUCCESS) && (ret != PAL_ERR_ITEM_NOT_EXIST )) 00066 { 00067 pal_plat_osSetTime(0); //Set device time to 0 00068 lastTimeBack = 0; 00069 //Rewrite strong time to avoid error in pal_plat_osSetWeak functions 00070 ret = storage_rbp_write(STORAGE_RBP_LAST_TIME_BACK_NAME, (uint8_t *)&lastTimeBack, sizeof(uint64_t), false); 00071 pal_status = ret; 00072 getTime = 0; //to avoid setting of the value to device time with pal_status = pal_osSetTime(PAL_MAX(rtcTime, getTime)) 00073 } 00074 00075 if (lastTimeBack > getTime) 00076 {//Enter here only when reset occurs during set weak or strong time 00077 ret = storage_rbp_write(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&lastTimeBack, sizeof(uint64_t), false); 00078 if (PAL_SUCCESS != ret) 00079 { 00080 pal_status = ret; 00081 } 00082 getTime = lastTimeBack; 00083 } 00084 00085 #if (PAL_USE_HW_RTC) 00086 if (PAL_SUCCESS == pal_status) 00087 { 00088 pal_status = pal_plat_osGetRtcTime(&rtcTime); 00089 } 00090 #endif 00091 00092 if (PAL_SUCCESS == pal_status) 00093 {//set the max time as boot time of the device 00094 pal_status = pal_osSetTime(PAL_MAX(rtcTime, getTime)); 00095 } 00096 00097 return pal_status; 00098 } 00099 00100 PAL_PRIVATE uint64_t pal_plat_sysTickTimeToSec() 00101 { 00102 uint64_t sysTicksFromBoot = pal_osKernelSysTick(); 00103 uint64_t secFromBoot = pal_osKernelSysMilliSecTick(sysTicksFromBoot) / PAL_MILLI_PER_SECOND; 00104 00105 return secFromBoot; 00106 } 00107 00108 uint64_t pal_plat_osGetTime(void) 00109 { 00110 uint64_t curSysTimeInSec = 0; 00111 if (0 < g_palDeviceBootTimeInSec) //time was previously set 00112 { 00113 uint64_t secFromBoot = pal_plat_sysTickTimeToSec(); 00114 curSysTimeInSec = g_palDeviceBootTimeInSec + secFromBoot; //boot time in sec + sec passed since boot 00115 } 00116 00117 return curSysTimeInSec; 00118 } 00119 00120 palStatus_t pal_plat_osSetTime(uint64_t seconds) 00121 { 00122 palStatus_t status = PAL_SUCCESS; 00123 if(0 == seconds) 00124 { 00125 g_palDeviceBootTimeInSec = 0; 00126 } 00127 else if (seconds < (uint64_t)PAL_MIN_SEC_FROM_EPOCH) 00128 { 00129 status = PAL_ERR_INVALID_TIME ; 00130 } 00131 else 00132 { 00133 uint64_t secFromBoot = pal_plat_sysTickTimeToSec(); 00134 g_palDeviceBootTimeInSec = seconds - secFromBoot; //update device boot time 00135 } 00136 00137 return status; 00138 } 00139 00140 palStatus_t pal_plat_osSetStrongTime(uint64_t setNewTimeInSeconds) 00141 { 00142 palStatus_t ret = PAL_SUCCESS; 00143 palStatus_t pal_status = PAL_SUCCESS; 00144 00145 uint64_t getTimeValue = 0; 00146 size_t actualLenBytes = 0; 00147 00148 #if (PAL_USE_HW_RTC) 00149 //RTC Time Latency 00150 if (PAL_SUCCESS == ret) 00151 { 00152 uint64_t getRtcTimeValue = 0; 00153 ret = pal_plat_osGetRtcTime(&getRtcTimeValue); 00154 if (PAL_SUCCESS == ret) 00155 { 00156 if(llabs(setNewTimeInSeconds - getRtcTimeValue) > PAL_MINIMUM_RTC_LATENCY_SEC) 00157 { 00158 ret = pal_plat_osSetRtcTime(setNewTimeInSeconds); 00159 } 00160 } 00161 } 00162 #endif 00163 00164 ret = storage_rbp_read(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&getTimeValue, sizeof(uint64_t), &actualLenBytes); 00165 if ((PAL_SUCCESS != ret) && (PAL_ERR_ITEM_NOT_EXIST != ret)) 00166 { 00167 pal_status = ret; 00168 } 00169 00170 else if (((setNewTimeInSeconds > getTimeValue) && (setNewTimeInSeconds - getTimeValue > PAL_MINIMUM_FORWARD_LATENCY_SEC)) //Forward Time 00171 || ((setNewTimeInSeconds < getTimeValue) && (getTimeValue - setNewTimeInSeconds > PAL_MINIMUM_BACKWARD_LATENCY_SEC))) //Backward Time 00172 { 00173 ret = storage_rbp_write(STORAGE_RBP_LAST_TIME_BACK_NAME, (uint8_t *)&setNewTimeInSeconds, sizeof(uint64_t), false); 00174 if (PAL_SUCCESS != ret) 00175 { 00176 pal_status = ret; 00177 } 00178 else 00179 { 00180 pal_status = storage_rbp_write(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&setNewTimeInSeconds, sizeof(uint64_t), false); 00181 } 00182 } 00183 00184 if(PAL_SUCCESS == pal_status) 00185 { 00186 pal_status = pal_osSetTime(setNewTimeInSeconds); //Save new time to RAM 00187 } 00188 00189 return pal_status; 00190 } 00191 00192 PAL_PRIVATE palStatus_t pal_plat_setWeakTimeForward(uint64_t setNewTimeInSeconds, uint64_t currentOsTime) 00193 { 00194 palStatus_t ret = PAL_SUCCESS; 00195 00196 ret = pal_osSetTime(setNewTimeInSeconds); //Save new time to RAM 00197 #if (PAL_USE_HW_RTC) 00198 //RTC Time Forward 00199 if (PAL_SUCCESS == ret) 00200 { 00201 uint64_t getRtcTimeValue = 0; 00202 ret = pal_plat_osGetRtcTime(&getRtcTimeValue); 00203 if (PAL_SUCCESS == ret) 00204 { 00205 if((setNewTimeInSeconds > getRtcTimeValue) && (setNewTimeInSeconds - getRtcTimeValue > PAL_MINIMUM_RTC_LATENCY_SEC)) 00206 { 00207 ret = pal_plat_osSetRtcTime(setNewTimeInSeconds); 00208 } 00209 } 00210 } 00211 #endif// (PAL_USE_HW_RTC) 00212 00213 if ((setNewTimeInSeconds - currentOsTime > PAL_MINIMUM_FORWARD_LATENCY_SEC) && (PAL_SUCCESS == ret)) 00214 { //time forward 00215 ret = storage_rbp_write(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&setNewTimeInSeconds, sizeof(uint64_t), false); 00216 } 00217 00218 return ret; 00219 } 00220 00221 PAL_PRIVATE palStatus_t pal_plat_setWeakTimeBackward(uint64_t setNewTimeInSeconds, uint64_t currentOsTime) 00222 { 00223 uint64_t getTimeValue = 0; 00224 size_t actualLenBytes = 0; 00225 palStatus_t ret = PAL_SUCCESS; 00226 palStatus_t pal_status = PAL_SUCCESS; 00227 00228 ret = storage_rbp_read(STORAGE_RBP_LAST_TIME_BACK_NAME, (uint8_t *)&getTimeValue, sizeof(uint64_t), &actualLenBytes); 00229 if ((PAL_SUCCESS != ret) && (PAL_ERR_ITEM_NOT_EXIST != ret)) 00230 { 00231 pal_status = ret; 00232 } 00233 00234 else if (setNewTimeInSeconds > getTimeValue) 00235 { 00236 if ((setNewTimeInSeconds - getTimeValue) / PAL_RATIO_SECONDS_PER_DAY > (currentOsTime - setNewTimeInSeconds)) 00237 { 00238 ret = storage_rbp_write(STORAGE_RBP_LAST_TIME_BACK_NAME, (uint8_t *)&setNewTimeInSeconds, sizeof(uint64_t), false); 00239 if (PAL_SUCCESS != ret) 00240 { 00241 pal_status = ret; 00242 } 00243 else 00244 { 00245 ret = storage_rbp_write(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&setNewTimeInSeconds, sizeof(uint64_t), false); 00246 if (PAL_SUCCESS == ret) 00247 { 00248 pal_status = pal_osSetTime(setNewTimeInSeconds); //Save new time to RAM 00249 } 00250 } 00251 } 00252 } 00253 00254 return pal_status; 00255 } 00256 00257 palStatus_t pal_plat_osSetWeakTime(uint64_t setNewTimeInSeconds) 00258 { 00259 uint64_t getTimeValue = 0; 00260 size_t actualLenBytes = 0; 00261 palStatus_t ret = PAL_SUCCESS; 00262 palStatus_t pal_status = PAL_SUCCESS; 00263 uint64_t getOsTimeValue = 0; 00264 00265 getOsTimeValue = pal_osGetTime(); //get current system time 00266 00267 if (setNewTimeInSeconds > getOsTimeValue) 00268 {//Time Forward 00269 ret = pal_plat_setWeakTimeForward(setNewTimeInSeconds, getOsTimeValue); 00270 } 00271 else if (getOsTimeValue > setNewTimeInSeconds) 00272 {//Time Backward 00273 ret = pal_plat_setWeakTimeBackward(setNewTimeInSeconds, getOsTimeValue); 00274 } 00275 00276 if(PAL_SUCCESS == ret) 00277 { 00278 getTimeValue = 0; 00279 ret = storage_rbp_read(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&getTimeValue, sizeof(uint64_t), &actualLenBytes); 00280 if ((PAL_SUCCESS != ret) && (PAL_ERR_ITEM_NOT_EXIST != ret)) 00281 { 00282 pal_status = ret; 00283 } 00284 else if ((setNewTimeInSeconds > getTimeValue) && (setNewTimeInSeconds - getTimeValue > PAL_MINIMUM_STORAGE_LATENCY_SEC)) 00285 { 00286 pal_status = storage_rbp_write(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t *)&setNewTimeInSeconds, sizeof(uint64_t), false); 00287 } 00288 } 00289 00290 return pal_status; 00291 } 00292
Generated on Tue Jul 12 2022 20:21:02 by
