• 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 
GetInstance()31 NtpTrustedTime &NtpTrustedTime::GetInstance()
32 {
33     static NtpTrustedTime instance;
34     return instance;
35 }
36 
ForceRefresh(const std::string & ntpServer)37 bool NtpTrustedTime::ForceRefresh(const std::string &ntpServer)
38 {
39     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
40     SNTPClient client;
41     if (client.RequestTime(ntpServer)) {
42         if (mTimeResult != nullptr) {
43             mTimeResult->Clear();
44         }
45         int64_t ntpCertainty = client.getRoundTripTime() / HALF;
46         mTimeResult = std::make_shared<TimeResult>(client.getNtpTime(), client.getNtpTimeReference(), ntpCertainty);
47         TIME_HILOGD(TIME_MODULE_SERVICE, "Get Ntp time result");
48         return true;
49     }
50     TIME_HILOGD(TIME_MODULE_SERVICE, "false end");
51     return false;
52 }
53 
CurrentTimeMillis()54 int64_t NtpTrustedTime::CurrentTimeMillis()
55 {
56     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
57     if (mTimeResult == nullptr) {
58         TIME_HILOGD(TIME_MODULE_SERVICE, "Missing authoritative time source");
59         return TIME_RESULT_UNINITED;
60     }
61     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
62     return mTimeResult->CurrentTimeMillis();
63 }
64 
ElapsedRealtimeMillis()65 int64_t NtpTrustedTime::ElapsedRealtimeMillis()
66 {
67     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
68     if (mTimeResult == nullptr) {
69         TIME_HILOGD(TIME_MODULE_SERVICE, "Missing authoritative time source");
70         return TIME_RESULT_UNINITED;
71     }
72     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
73     return mTimeResult->GetElapsedRealtimeMillis();
74 }
75 
GetCacheAge()76 int64_t NtpTrustedTime::GetCacheAge()
77 {
78     if (mTimeResult != nullptr) {
79         return std::chrono::duration_cast<std::chrono::milliseconds>(
80                    std::chrono::steady_clock::now().time_since_epoch())
81                    .count() -
82                mTimeResult->GetElapsedRealtimeMillis();
83     } else {
84         return INT_MAX;
85     }
86 }
87 
GetBootTimeNs()88 std::chrono::steady_clock::time_point NtpTrustedTime::GetBootTimeNs()
89 {
90     int64_t timeNow = -1;
91     struct timespec tv {};
92     if (clock_gettime(CLOCK_BOOTTIME, &tv) < 0) {
93         return std::chrono::steady_clock::now();
94     }
95     timeNow = tv.tv_sec * NANO_TO_SECOND + tv.tv_nsec;
96     std::chrono::steady_clock::time_point tp_epoch ((std::chrono::nanoseconds(timeNow)));
97     return tp_epoch;
98 }
99 
GetTimeMillis()100 int64_t NtpTrustedTime::TimeResult::GetTimeMillis()
101 {
102     return mTimeMillis;
103 }
104 
GetElapsedRealtimeMillis()105 int64_t NtpTrustedTime::TimeResult::GetElapsedRealtimeMillis()
106 {
107     return mElapsedRealtimeMillis;
108 }
109 
CurrentTimeMillis()110 int64_t NtpTrustedTime::TimeResult::CurrentTimeMillis()
111 {
112     if (mTimeMillis == 0 || mElapsedRealtimeMillis == 0) {
113         TIME_HILOGD(TIME_MODULE_SERVICE, "Missing authoritative time source");
114         return TIME_RESULT_UNINITED;
115     }
116     auto bootTime = std::chrono::duration_cast<std::chrono::milliseconds>(
117         NtpTrustedTime::GetInstance().GetBootTimeNs().time_since_epoch()).count();
118     if (static_cast<int64_t>(bootTime) - mElapsedRealtimeMillis > ONE_DAY) {
119         Clear();
120         return TIME_RESULT_UNINITED;
121     }
122     return mTimeMillis + GetAgeMillis();
123 }
124 
GetAgeMillis()125 int64_t NtpTrustedTime::TimeResult::GetAgeMillis()
126 {
127     return std::chrono::duration_cast<std::chrono::milliseconds>(
128         NtpTrustedTime::GetInstance().GetBootTimeNs().time_since_epoch()).count() - this->mElapsedRealtimeMillis;
129 }
130 
TimeResult()131 NtpTrustedTime::TimeResult::TimeResult()
132 {
133 }
~TimeResult()134 NtpTrustedTime::TimeResult::~TimeResult()
135 {
136 }
137 
TimeResult(int64_t mTimeMillis,int64_t mElapsedRealtimeMills,int64_t mCertaintyMillis)138 NtpTrustedTime::TimeResult::TimeResult(int64_t mTimeMillis, int64_t mElapsedRealtimeMills, int64_t mCertaintyMillis)
139 {
140     this->mTimeMillis = mTimeMillis;
141     this->mElapsedRealtimeMillis = mElapsedRealtimeMills;
142     this->mCertaintyMillis = mCertaintyMillis;
143     TIME_HILOGD(TIME_MODULE_SERVICE, "mTimeMillis %{public}" PRId64 "", mTimeMillis);
144     TIME_HILOGD(TIME_MODULE_SERVICE, "mElapsedRealtimeMills %{public}" PRId64 "", mElapsedRealtimeMills);
145     TIME_HILOGD(TIME_MODULE_SERVICE, "mCertaintyMillis %{public}" PRId64 "", mCertaintyMillis);
146 }
147 
Clear()148 void NtpTrustedTime::TimeResult::Clear()
149 {
150     mTimeMillis = 0;
151     mElapsedRealtimeMillis = 0;
152     mCertaintyMillis = 0;
153 }
154 } // namespace MiscServices
155 } // namespace OHOS