3 * Copyright (c) 2018 Nest Labs, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * Provides implementations of the CHIP System Layer platform
22 * time/clock functions that are suitable for use on the Posix platform.
25 #include <platform/internal/CHIPDeviceLayerInternal.h>
27 #include <support/TimeUtils.h>
28 #include <support/logging/CHIPLogging.h>
40 uint64_t GetClock_Monotonic()
42 std::chrono::microseconds epoch =
43 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch());
44 // count() is nominally signed, but for a monotonic clock it cannot be
46 return static_cast<uint64_t>(epoch.count());
49 uint64_t GetClock_MonotonicMS()
51 std::chrono::milliseconds epoch =
52 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch());
53 // count() is nominally signed, but for a monotonic clock it cannot be
55 return static_cast<uint64_t>(epoch.count());
58 uint64_t GetClock_MonotonicHiRes()
60 std::chrono::microseconds epoch =
61 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch());
62 // count() is nominally signed, but for a monotonic clock it cannot be
64 return static_cast<uint64_t>(epoch.count());
67 System::Error GetClock_RealTime(uint64_t & curTime)
70 int res = gettimeofday(&tv, nullptr);
73 return MapErrorPOSIX(errno);
75 if (tv.tv_sec < CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD)
77 return CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED;
81 return CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED;
83 static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!");
84 curTime = (static_cast<uint64_t>(tv.tv_sec) * UINT64_C(1000000)) + static_cast<uint64_t>(tv.tv_usec);
85 return CHIP_SYSTEM_NO_ERROR;
88 System::Error GetClock_RealTimeMS(uint64_t & curTime)
91 int res = gettimeofday(&tv, nullptr);
94 return MapErrorPOSIX(errno);
96 if (tv.tv_sec < CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD)
98 return CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED;
102 return CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED;
104 static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!");
105 curTime = (static_cast<uint64_t>(tv.tv_sec) * UINT64_C(1000)) + (static_cast<uint64_t>(tv.tv_usec) / 1000);
106 return CHIP_SYSTEM_NO_ERROR;
109 System::Error SetClock_RealTime(uint64_t newCurTime)
112 tv.tv_sec = static_cast<time_t>(newCurTime / UINT64_C(1000000));
113 tv.tv_usec = static_cast<long>(newCurTime % UINT64_C(1000000));
114 int res = settimeofday(&tv, nullptr);
117 return (errno == EPERM) ? CHIP_SYSTEM_ERROR_ACCESS_DENIED : MapErrorPOSIX(errno);
119 #if CHIP_PROGRESS_LOGGING
121 const time_t timep = tv.tv_sec;
123 localtime_r(&timep, &calendar);
126 "Real time clock set to %ld (%04" PRId16 "/%02" PRId8 "/%02" PRId8 " %02" PRId8 ":%02" PRId8 ":%02" PRId8 " UTC)",
127 tv.tv_sec, calendar.tm_year, calendar.tm_mon, calendar.tm_mday, calendar.tm_hour, calendar.tm_min, calendar.tm_sec);
129 #endif // CHIP_PROGRESS_LOGGING
130 return CHIP_SYSTEM_NO_ERROR;
134 } // namespace Platform
135 } // namespace System