• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ntp_trusted_time.h"
17 
18 #include <cinttypes>
19 
20 #include "sntp_client.h"
21 
22 namespace OHOS {
23 namespace MiscServices {
24 namespace {
25 constexpr int64_t TIME_RESULT_UNINITED = -1;
26 constexpr int64_t HALF = 2;
27 constexpr int NANO_TO_SECOND =  1000000000;
28 constexpr int64_t ONE_DAY = 86400000;
29 } // namespace
30 
31 std::mutex NtpTrustedTime::mTimeResultMutex_;
32 
GetInstance()33 NtpTrustedTime &NtpTrustedTime::GetInstance()
34 {
35     static NtpTrustedTime instance;
36     return instance;
37 }
38 
ForceRefresh(const std::string & ntpServer)39 bool NtpTrustedTime::ForceRefresh(const std::string &ntpServer)
40 {
41     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
42     SNTPClient client;
43     if (client.RequestTime(ntpServer)) {
44         std::lock_guard<std::mutex> lock(mTimeResultMutex_);
45         if (mTimeResult != nullptr) {
46             mTimeResult->Clear();
47         }
48         int64_t ntpCertainty = client.getRoundTripTime() / HALF;
49         mTimeResult = std::make_shared<TimeResult>(client.getNtpTime(), client.getNtpTimeReference(), ntpCertainty);
50         TIME_HILOGD(TIME_MODULE_SERVICE, "Get Ntp time result");
51         return true;
52     }
53     TIME_HILOGD(TIME_MODULE_SERVICE, "false end");
54     return false;
55 }
56 
CurrentTimeMillis()57 int64_t NtpTrustedTime::CurrentTimeMillis()
58 {
59     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
60     std::lock_guard<std::mutex> lock(mTimeResultMutex_);
61     if (mTimeResult == nullptr) {
62         TIME_HILOGE(TIME_MODULE_SERVICE, "Missing authoritative time source");
63         return TIME_RESULT_UNINITED;
64     }
65     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
66     return mTimeResult->CurrentTimeMillis();
67 }
68 
ElapsedRealtimeMillis()69 int64_t NtpTrustedTime::ElapsedRealtimeMillis()
70 {
71     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
72     std::lock_guard<std::mutex> lock(mTimeResultMutex_);
73     if (mTimeResult == nullptr) {
74         TIME_HILOGE(TIME_MODULE_SERVICE, "Missing authoritative time source");
75         return TIME_RESULT_UNINITED;
76     }
77     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
78     return mTimeResult->GetElapsedRealtimeMillis();
79 }
80 
GetCacheAge()81 int64_t NtpTrustedTime::GetCacheAge()
82 {
83     std::lock_guard<std::mutex> lock(mTimeResultMutex_);
84     if (mTimeResult != nullptr) {
85         return std::chrono::duration_cast<std::chrono::milliseconds>(
86                    std::chrono::steady_clock::now().time_since_epoch())
87                    .count() -
88                mTimeResult->GetElapsedRealtimeMillis();
89     } else {
90         return INT_MAX;
91     }
92 }
93 
GetBootTimeNs()94 std::chrono::steady_clock::time_point NtpTrustedTime::GetBootTimeNs()
95 {
96     int64_t timeNow = -1;
97     struct timespec tv {};
98     if (clock_gettime(CLOCK_BOOTTIME, &tv) < 0) {
99         return std::chrono::steady_clock::now();
100     }
101     timeNow = tv.tv_sec * NANO_TO_SECOND + tv.tv_nsec;
102     std::chrono::steady_clock::time_point tp_epoch ((std::chrono::nanoseconds(timeNow)));
103     return tp_epoch;
104 }
105 
GetTimeMillis()106 int64_t NtpTrustedTime::TimeResult::GetTimeMillis()
107 {
108     return mTimeMillis;
109 }
110 
GetElapsedRealtimeMillis()111 int64_t NtpTrustedTime::TimeResult::GetElapsedRealtimeMillis()
112 {
113     return mElapsedRealtimeMillis;
114 }
115 
CurrentTimeMillis()116 int64_t NtpTrustedTime::TimeResult::CurrentTimeMillis()
117 {
118     if (mTimeMillis == 0 || mElapsedRealtimeMillis == 0) {
119         TIME_HILOGD(TIME_MODULE_SERVICE, "Missing authoritative time source");
120         return TIME_RESULT_UNINITED;
121     }
122     int64_t bootTime = 0;
123     int res = TimeUtils::GetBootTimeMs(bootTime);
124     if (res != E_TIME_OK) {
125         return TIME_RESULT_UNINITED;
126     }
127     if (bootTime - mElapsedRealtimeMillis > ONE_DAY) {
128         Clear();
129         return TIME_RESULT_UNINITED;
130     }
131     return mTimeMillis + GetAgeMillis();
132 }
133 
GetAgeMillis()134 int64_t NtpTrustedTime::TimeResult::GetAgeMillis()
135 {
136     int64_t bootTime = 0;
137     TimeUtils::GetBootTimeMs(bootTime);
138     return bootTime - this->mElapsedRealtimeMillis;
139 }
140 
TimeResult()141 NtpTrustedTime::TimeResult::TimeResult()
142 {
143 }
~TimeResult()144 NtpTrustedTime::TimeResult::~TimeResult()
145 {
146 }
147 
TimeResult(int64_t mTimeMillis,int64_t mElapsedRealtimeMills,int64_t mCertaintyMillis)148 NtpTrustedTime::TimeResult::TimeResult(int64_t mTimeMillis, int64_t mElapsedRealtimeMills, int64_t mCertaintyMillis)
149 {
150     this->mTimeMillis = mTimeMillis;
151     this->mElapsedRealtimeMillis = mElapsedRealtimeMills;
152     this->mCertaintyMillis = mCertaintyMillis;
153     TIME_HILOGD(TIME_MODULE_SERVICE, "mTimeMillis %{public}" PRId64 "", mTimeMillis);
154     TIME_HILOGD(TIME_MODULE_SERVICE, "mElapsedRealtimeMills %{public}" PRId64 "", mElapsedRealtimeMills);
155     TIME_HILOGD(TIME_MODULE_SERVICE, "mCertaintyMillis %{public}" PRId64 "", mCertaintyMillis);
156 }
157 
Clear()158 void NtpTrustedTime::TimeResult::Clear()
159 {
160     mTimeMillis = 0;
161     mElapsedRealtimeMillis = 0;
162     mCertaintyMillis = 0;
163 }
164 } // namespace MiscServices
165 } // namespace OHOS