From dd9ced0c370ebc0448fb67d5b66308830ebd3172 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Sat, 12 Feb 2022 16:02:17 +0800 Subject: [PATCH 1/6] 2022021200 Signed-off-by: guduhanyan --- utils/native/include/time_permission.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/native/include/time_permission.h b/utils/native/include/time_permission.h index 16f9ce71..48e742ea 100644 --- a/utils/native/include/time_permission.h +++ b/utils/native/include/time_permission.h @@ -19,7 +19,7 @@ #include #include -#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" #include "time_common.h" #include "mock_permission.h" #include "system_ability_definition.h" -- Gitee From 663dd529f6b9c5c6d906a3073b89b0e10ee4570e Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Sun, 13 Feb 2022 08:58:49 +0800 Subject: [PATCH 2/6] 2022021201 Signed-off-by: guduhanyan --- BUILD.gn | 2 +- etc/init/BUILD.gn | 2 +- etc/init/timeservice.cfg | 1 - utils/native/include/time_permission.h | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 06ad71cd..02b6ef3e 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -18,7 +18,7 @@ import("//build/ohos.gni") group("time_native_packages") { if (is_standard_system) { deps = [ - "etc/init:timeservice.rc", + "etc/init:timeservice.cfg", "interfaces/kits/js/declaration:time", "interfaces/kits/js/napi/system_time:systemtime", "interfaces/kits/js/napi/system_timer:systemtimer", diff --git a/etc/init/BUILD.gn b/etc/init/BUILD.gn index f020e5d5..eccb004e 100755 --- a/etc/init/BUILD.gn +++ b/etc/init/BUILD.gn @@ -15,7 +15,7 @@ import("//build/ohos.gni") ################################################################################ -ohos_prebuilt_etc("timeservice.rc") { +ohos_prebuilt_etc("timeservice.cfg") { source = "timeservice.cfg" relative_install_dir = "init" part_name = "time_native" diff --git a/etc/init/timeservice.cfg b/etc/init/timeservice.cfg index a14e3da5..befefef8 100644 --- a/etc/init/timeservice.cfg +++ b/etc/init/timeservice.cfg @@ -11,7 +11,6 @@ "path" : ["/system/bin/sa_main", "/system/profile/time_service.xml"], "uid" : "system", "gid" : ["system", "shell"], - "secon" : "u:r:time_service:s0", "caps" : ["SYS_TIME", "WAKE_ALARM"] } ] diff --git a/utils/native/include/time_permission.h b/utils/native/include/time_permission.h index 48e742ea..57d65f05 100644 --- a/utils/native/include/time_permission.h +++ b/utils/native/include/time_permission.h @@ -18,7 +18,6 @@ #include #include #include - #include "bundle_mgr_proxy.h" #include "time_common.h" #include "mock_permission.h" -- Gitee From f9ec67ca8084cacf3c8728cc2b77075c42e862ed Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Sun, 13 Feb 2022 23:12:03 +0800 Subject: [PATCH 3/6] 2022021300 Signed-off-by: guduhanyan --- .../innerkits/include/time_service_client.h | 14 +- services/BUILD.gn | 4 + .../time_manager/include/nitz_subscriber.h | 53 +++ .../time_manager/include/ntp_trusted_time.h | 64 +++ .../time_manager/include/ntp_update_time.h | 56 +++ services/time_manager/include/sntp_client.h | 220 +++++++++ services/time_manager/include/time_service.h | 3 +- .../include/time_service_interface.h | 16 +- .../include/time_service_notify.h | 1 - .../time_manager/include/time_service_proxy.h | 3 +- .../time_manager/include/time_service_stub.h | 3 +- services/time_manager/src/nitz_subscriber.cpp | 70 +++ .../time_manager/src/ntp_trusted_time.cpp | 110 +++++ services/time_manager/src/ntp_update_time.cpp | 236 +++++++++ services/time_manager/src/sntp_client.cpp | 447 ++++++++++++++++++ services/time_manager/src/time_service.cpp | 11 + .../time_manager/src/time_service_proxy.cpp | 36 ++ .../time_manager/src/time_service_stub.cpp | 16 + 18 files changed, 1357 insertions(+), 6 deletions(-) create mode 100644 services/time_manager/include/nitz_subscriber.h create mode 100644 services/time_manager/include/ntp_trusted_time.h create mode 100644 services/time_manager/include/ntp_update_time.h create mode 100644 services/time_manager/include/sntp_client.h create mode 100644 services/time_manager/src/nitz_subscriber.cpp create mode 100644 services/time_manager/src/ntp_trusted_time.cpp create mode 100644 services/time_manager/src/ntp_update_time.cpp create mode 100644 services/time_manager/src/sntp_client.cpp diff --git a/interfaces/innerkits/include/time_service_client.h b/interfaces/innerkits/include/time_service_client.h index 6fa0f5a1..ea1776e4 100644 --- a/interfaces/innerkits/include/time_service_client.h +++ b/interfaces/innerkits/include/time_service_client.h @@ -147,7 +147,19 @@ public: * @return bool true on success, false on failure. */ bool DestroyTimer(uint64_t timerId); - + + /** + * NetworkTimeStatusOff + * @return void. + */ + void NetworkTimeStatusOff(); + + /** + * NetworkTimeStatusOn + * @return void. + */ + void NetworkTimeStatusOn(); + void OnRemoteSaDied(const wptr &object); private: diff --git a/services/BUILD.gn b/services/BUILD.gn index 1339bbf0..5bd6fe30 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -49,6 +49,10 @@ ohos_shared_library("time_service") { "time_manager/src/timer_call_back.cpp", "time_manager/src/timer_call_back_proxy.cpp", "time_manager/src/timer_call_back_stub.cpp", + "time_manager/src/sntp_client.cpp", + "time_manager/src/ntp_trusted_time.cpp", + "time_manager/src/ntp_update_time.cpp", + "time_manager/src/nitz_subscriber.cpp", "timer/src/batch.cpp", "timer/src/timer_handler.cpp", "timer/src/timer_info.cpp", diff --git a/services/time_manager/include/nitz_subscriber.h b/services/time_manager/include/nitz_subscriber.h new file mode 100644 index 00000000..73527c23 --- /dev/null +++ b/services/time_manager/include/nitz_subscriber.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NITZ_SUBSCRIBER_H +#define NITZ_SUBSCRIBER_H + +#include +#include +#include + +#include +#include "common_event.h" +#include "common_event_data.h" +#include "common_event_manager.h" +#include "common_event_support.h" + +namespace OHOS { +namespace MiscServices { +using namespace OHOS::EventFwk; +class NITZSubscriber : public CommonEventSubscriber { +public: + explicit NITZSubscriber(const CommonEventSubscribeInfo &subscriberInfo); + ~NITZSubscriber() = default; + virtual void OnReceiveEvent(const CommonEventData &data); + +private: + enum NITZBroadcastEventType { + UNKNOWN_BROADCAST_EVENT = 0, + NITZ_TIME_CHANGED_BROADCAST_EVENT, + NITZ_TIMEZONE_CHANGED_BROADCAST_EVENT + }; + using broadcastSubscriberFunc = void (NITZSubscriber::*)(const CommonEventData &data); + + void UnknownBroadcast(const CommonEventData &data); + void NITZTimeChangeBroadcast(const CommonEventData &data); + void NITZTimezoneChangeBroadcast(const CommonEventData &data); + std::map memberFuncMap_; +}; +} // MiscServices +} // OHOS +#endif //NITZ_SUBSCRIBER_H \ No newline at end of file diff --git a/services/time_manager/include/ntp_trusted_time.h b/services/time_manager/include/ntp_trusted_time.h new file mode 100644 index 00000000..d600382e --- /dev/null +++ b/services/time_manager/include/ntp_trusted_time.h @@ -0,0 +1,64 @@ + +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SNTP_CLIENT_NTP_TRUSTED_TIME_H +#define SNTP_CLIENT_NTP_TRUSTED_TIME_H + +#include +#include +#include +#include +#include +#include "refbase.h" +#include "time.h" +#include "time_common.h" +#include "json/json.h" + +namespace OHOS { +namespace MiscServices { +class NtpTrustedTime : public DelayedSingleton{ + DECLARE_DELAYED_SINGLETON(NtpTrustedTime) +public: + bool ForceRefresh(std::string ntpServer); + bool HasCache(); + int64_t GetCacheAge(); + int64_t CurrentTimeMillis(); + int64_t GetCachedNtpTime(); + int64_t GetCachedNtpTimeReference(); + class TimeResult : std::enable_shared_from_this { + public: + TimeResult(); + TimeResult(int64_t mTimeMillis, int64_t mElapsedRealtimeMills, int64_t mCertaintyMillis); + ~TimeResult(); + int64_t GetTimeMillis(); + int64_t GetElapsedRealtimeMillis(); + int64_t GetCertaintyMillis(); + int64_t CurrentTimeMillis(); + int64_t GetAgeMillis(); + private: + int64_t mTimeMillis; + int64_t mElapsedRealtimeMillis; + int64_t mCertaintyMillis; + + }; + +private: + std::shared_ptr mTimeResult; +}; +} // MiscServices +} // OHOS + +#endif //SNTP_CLIENT_NTP_TRUSTED_TIME_H diff --git a/services/time_manager/include/ntp_update_time.h b/services/time_manager/include/ntp_update_time.h new file mode 100644 index 00000000..5f9038b0 --- /dev/null +++ b/services/time_manager/include/ntp_update_time.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NTP_UPDATE_TIME_H +#define NTP_UPDATE_TIME_H + +#include + +namespace OHOS { +namespace MiscServices { +struct autoTimeInfo +{ + std::string NTP_SERVER; + std::string status; + int64_t lastUpdateTime; +}; + +class NtpUpdateTime : public DelayedSingleton { + DECLARE_DELAYED_SINGLETON(NtpUpdateTime); +public: + DISALLOW_COPY_AND_MOVE(NtpUpdateTime); + void RefreshNetworkTimeByTimer(const uint64_t timerid); + void UpdateStatusOff(); + void UpdateStatusOn(); + void UpdateNITZSetTime(); + void Stop(); + void Init(); +private: + bool GetAutoTimeInfoFromFile(autoTimeInfo &info); + bool SaveAutoTimeInfoToFile(autoTimeInfo &info); + void SubscriberNITZTimeChangeCommonEvent(); + void StartTimer(); + void SetSystemTime(); + void RefreshNextTriggerTime(); + bool CheckStatus(); + bool IsNITZTimeInvalid(); + autoTimeInfo autoTimeInfo_; + uint64_t timerId_; + uint64_t nitzUpdateTimeMili_; + uint64_t nextTriggerTime_; +}; +} // MiscServices +} // OHOS +#endif \ No newline at end of file diff --git a/services/time_manager/include/sntp_client.h b/services/time_manager/include/sntp_client.h new file mode 100644 index 00000000..84664823 --- /dev/null +++ b/services/time_manager/include/sntp_client.h @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SNTP_CLIENT_SNTP_CLIENT_H +#define SNTP_CLIENT_SNTP_CLIENT_H + +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace MiscServices { +class SNTPClient { +public: + SNTPClient(); + ~SNTPClient(); + bool RequestTime(std::string host); + int64_t getNtpTIme(); + int64_t getNtpTimeReference(); + int64_t getRoundTripTime(); + int GetClockOffset(void); +private: + struct ntp_timestamp + { + uint32_t second; + uint32_t fraction; + }; + + struct date_structure + { + int hour; + int minute; + int second; + int millisecond; + }; + + struct SNTPMessage + { + unsigned char _leapIndicator; + unsigned char _versionNumber; + unsigned char _mode; + unsigned char _stratum; + unsigned char _pollInterval; + unsigned char _precision; + unsigned int _rootDelay; + unsigned int _rootDispersion; + unsigned int _referenceIdentifier[4]; + uint64_t _referenceTimestamp; + uint64_t _originateTimestamp; + uint64_t _receiveTimestamp; + uint64_t _transmitTimestamp; + + /** + * Zero all the values. + */ + void clear(); + }; + + enum _LeapIndicatorValues + { + NoWarning, // 0 - No warning + LastMinute61, // 1 - Last minute has 61 seconds + LastMinute59, // 2 - Last minute has 59 seconds + Alarm // 3 - Alarm condition (clock not synchronized) + }; + + //Mode field values + enum _ModeValues + { + SymmetricActive, // 1 - Symmetric active + SymmetricPassive, // 2 - Symmetric passive + Client, // 3 - Client + Server, // 4 - Server + Broadcast, // 5 - Broadcast + Unknown // 0, 6, 7 - Reserved + }; + + // Stratum field values + enum _StratumValues + { + Unspecified, // 0 - unspecified or unavailable + PrimaryReference, // 1 - primary reference (e.g. radio-clock) + SecondaryReference, // 2-15 - secondary reference (via NTP or SNTP) + Reserved // 16-255 - reserved + }; + + unsigned int GetNtpField32(int offset, char* buffer); + /** + * This function returns an array based on the Reference ID + * (converted from NTP message), given the offset provided. + * + * @param offset the offset of the field in the NTP message + * @param buffer the received message + * + * Returns the array of Reference ID + */ + void GetReferenceId(int offset, char* buffer, int* _outArray); + /** + * This function sets the clock offset in ms. + * Negative value means the local clock is ahead, + * positive means the local clock is behind (relative to the NTP server) + * + * @param clockOffset the clock offset in ms + */ + void SetClockOffset(int clockOffset); + + /** + * This function converts the UNIX time to NTP + * + * @param ntpTs the structure NTP where the NTP values are stored + * @param unixTs the structure UNIX (with the already set tv_sec and tv_usec) + */ + void convert_unix_to_ntp(struct ntp_timestamp* ntpTs, struct timeval* unixTs); + /** + * This function converts the NTP time to UNIX + * + * @param ntpTs the structure NTP where the NTP values are already set + * @param unixTs the structure UNIX where the UNIX values are stored + */ + void convert_ntp_to_unix(struct ntp_timestamp* ntpTs, struct timeval* unixTs); + + /** + * This function creates the SNTP message ready for transmission (SNTP Req) + * and returns it back. + * + * @param buffer the message to be sent + */ + void CreateMessage(char* buffer); + + /** + * This function creates the SNTP message ready for transmission (SNTP Req) + * and returns it back. + * + * @param buffer the message to be sent + */ + void WriteTimeStamp(char* buffer, ntp_timestamp *ntp); + + /** + * This function gets the information received from the SNTP response + * and prints the results (e.g. offset, round trip delay etc.) + * + * @param buffer the message received + */ + void ReceivedMessage(char* buffer); + + /** + * This function returns the timestamp (64-bit) from the received + * buffer, given the offset provided. + * + * @param offset the offset of the timestamp in the NTP message + * @param buffer the received message + * + * Returns the ntp timestamp + */ + uint64_t GetNtpTimestamp64(int offset, char* buffer); + + /** + * This function converts the NTP time to timestamp + * + * @param _ntpTs the NTP timestamp to be converted + * Returns the milliseconds + */ + uint64_t convert_ntp_to_stamp(uint64_t _ntpTs); + + /** + * This function converts the NTP time to local time + * + * @param _ntpTs the NTP timestamp to be converted + * @param _outDataTs the structure Date where the [HH, MM, SS, MMMMMM] are stored + */ + uint64_t convert_ntp_to_date(uint64_t _ntpTs, struct date_structure* _outDataTs); + /** + * This function returns the LeapIndicator field in a string format (see _LeapIndicatorValues). + * + * @param _leapIndicator the _leapIndicator from structure SNTPMessage (unsigned char) + * + * Returns the string format of LeapIndicator + */ + std::string GetLeapString(unsigned char _leapIndicator); + /** + * This function returns the Mode field in a string format (see _ModeValues). + * + * @param _mode the _mode from structure SNTPMessage (unsigned char) + * + * Returns the string format of Mode + */ + std::string GetModeString(unsigned char _mode); + /** + * This function returns the Stratum field in a string format (see _StratumValues). + * + * @param _stratum the _stratum from structure SNTPMessage (unsigned char) + * + * Returns the string format of Stratum + */ + std::string GetStratumString(unsigned char _stratum); + + int m_clockOffset; + int64_t m_originateTimestamp; + int64_t mNtpTime; + int64_t mNtpTimeReference; + int64_t mRoundTripTime; +}; +} // MiscServices +} // OHOS +#endif //SNTP_CLIENT_SNTP_CLIENT_H diff --git a/services/time_manager/include/time_service.h b/services/time_manager/include/time_service.h index 070be892..cafe3efd 100644 --- a/services/time_manager/include/time_service.h +++ b/services/time_manager/include/time_service.h @@ -61,7 +61,8 @@ public: bool StartTimer(uint64_t timerId, uint64_t triggerTime) override; bool StopTimer(uint64_t timerId) override; bool DestroyTimer(uint64_t timerId) override; - + void NetworkTimeStatusOff() override; + void NetworkTimeStatusOn() override; protected: void OnStart() override; void OnStop() override; diff --git a/services/time_manager/include/time_service_interface.h b/services/time_manager/include/time_service_interface.h index b43612af..86213b9d 100644 --- a/services/time_manager/include/time_service_interface.h +++ b/services/time_manager/include/time_service_interface.h @@ -39,7 +39,9 @@ public: CREATE_TIMER = 11, START_TIMER = 12, STOP_TIMER = 13, - DESTORY_TIMER = 14 + DESTORY_TIMER = 14, + NETWORK_TIME_ON = 15, + NETWORK_TIME_OFF = 16 }; /** * SetTime @@ -164,6 +166,18 @@ public: */ virtual bool DestroyTimer(uint64_t timerId) = 0; + /** + * NetworkTimeStatusOff + * @return void. + */ + virtual void NetworkTimeStatusOff() = 0; + + /** + * NetworkTimeStatusOn + * @return void. + */ + virtual void NetworkTimeStatusOn() = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimeService"); }; } // namespace MiscServices diff --git a/services/time_manager/include/time_service_notify.h b/services/time_manager/include/time_service_notify.h index 06a2f49e..536e5f8d 100644 --- a/services/time_manager/include/time_service_notify.h +++ b/services/time_manager/include/time_service_notify.h @@ -21,7 +21,6 @@ #include #include "time_common.h" - namespace OHOS { namespace MiscServices { class TimeServiceNotify : public DelayedSingleton { diff --git a/services/time_manager/include/time_service_proxy.h b/services/time_manager/include/time_service_proxy.h index 870a8a24..43b522dc 100644 --- a/services/time_manager/include/time_service_proxy.h +++ b/services/time_manager/include/time_service_proxy.h @@ -42,7 +42,8 @@ public: bool StartTimer(uint64_t timerId, uint64_t treggerTime) override; bool StopTimer(uint64_t timerId) override; bool DestroyTimer(uint64_t timerId) override; - + void NetworkTimeStatusOff() override; + void NetworkTimeStatusOn() override; private: static inline BrokerDelegator delegator_; }; diff --git a/services/time_manager/include/time_service_stub.h b/services/time_manager/include/time_service_stub.h index 207c46cb..aef9cd76 100644 --- a/services/time_manager/include/time_service_stub.h +++ b/services/time_manager/include/time_service_stub.h @@ -48,7 +48,8 @@ private: int32_t OnStartTimer(MessageParcel &data, MessageParcel &reply); int32_t OnStopTimer(MessageParcel &data, MessageParcel &reply); int32_t OnDestoryTimer(MessageParcel &data, MessageParcel &reply); - + int32_t OnNetworkTimeStatusOff(MessageParcel &data, MessageParcel &reply); + int32_t OnNetworkTimeStatusOn(MessageParcel &data, MessageParcel &reply); std::map memberFuncMap_; }; } // namespace MiscServices diff --git a/services/time_manager/src/nitz_subscriber.cpp b/services/time_manager/src/nitz_subscriber.cpp new file mode 100644 index 00000000..cbcf9725 --- /dev/null +++ b/services/time_manager/src/nitz_subscriber.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nitz_subscriber.h" +#include "time_common.h" +#include "ntp_update_time.h" +namespace OHOS { +namespace MiscServices { +using namespace OHOS::EventFwk; +using namespace OHOS::AAFwk; +NITZSubscriber::NITZSubscriber( + const OHOS::EventFwk::CommonEventSubscribeInfo &subscriberInfo) + : CommonEventSubscriber(subscriberInfo) +{ + memberFuncMap_[UNKNOWN_BROADCAST_EVENT] = &NITZSubscriber::UnknownBroadcast; + memberFuncMap_[NITZ_TIME_CHANGED_BROADCAST_EVENT] = &NITZSubscriber::NITZTimeChangeBroadcast; + memberFuncMap_[NITZ_TIMEZONE_CHANGED_BROADCAST_EVENT] = &NITZSubscriber::NITZTimezoneChangeBroadcast; +} + +void NITZSubscriber::OnReceiveEvent(const CommonEventData &data) +{ + uint32_t code = UNKNOWN_BROADCAST_EVENT; + OHOS::EventFwk::Want want = data.GetWant(); + std::string action = data.GetWant().GetAction(); + TIME_HILOGD(TIME_MODULE_SERVICE, "receive one broadcast:%{public}s", action.c_str()); + + if (action == CommonEventSupport::COMMON_EVENT_NITZ_TIME_UPDATED) { + code = NITZ_TIME_CHANGED_BROADCAST_EVENT; + } else { + code = UNKNOWN_BROADCAST_EVENT; + } + + auto itFunc = memberFuncMap_.find(code); + if (itFunc != memberFuncMap_.end()) { + auto memberFunc = itFunc->second; + if (memberFunc != nullptr) { + return (this->*memberFunc)(data); + } + } +} + +void NITZSubscriber::UnknownBroadcast(const CommonEventData &data) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "you receive one unknown broadcast!"); +} + +void NITZSubscriber::NITZTimeChangeBroadcast(const CommonEventData &data) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "NITZ Timezone changed broadcast code:%{public}d", data.GetCode()); + DelayedSingleton::GetInstance()->UpdateNITZSetTime(); +} + +void NITZSubscriber::NITZTimezoneChangeBroadcast(const CommonEventData &data) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "NITZ Time changed broadcast code:%{public}d", data.GetCode()); +} +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/services/time_manager/src/ntp_trusted_time.cpp b/services/time_manager/src/ntp_trusted_time.cpp new file mode 100644 index 00000000..004d64be --- /dev/null +++ b/services/time_manager/src/ntp_trusted_time.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ntp_trusted_time.h" +#include "time_common.h" +#include "sntp_client.h" + +namespace OHOS { +namespace MiscServices { +NtpTrustedTime::NtpTrustedTime(){} +NtpTrustedTime::~NtpTrustedTime(){} + +bool NtpTrustedTime::ForceRefresh(std::string ntpServer) +{ + SNTPClient client; + if (client.RequestTime(ntpServer)) { + int64_t ntpCertainty = client.getRoundTripTime() / 2; + mTimeResult = std::make_shared(client.getNtpTIme(), client.getNtpTimeReference(), ntpCertainty); + TIME_HILOGD(TIME_MODULE_SERVICE, "Get Ntp time result"); + return true; + } else { + return false; + } +} + +int64_t NtpTrustedTime::CurrentTimeMillis() +{ + if (mTimeResult == nullptr) { + TIME_HILOGD(TIME_MODULE_SERVICE, "Missing authoritative time source"); + return -1; + } + return mTimeResult->CurrentTimeMillis(); +} + +bool NtpTrustedTime::HasCache() +{ + return mTimeResult == nullptr; +} + +int64_t NtpTrustedTime::GetCacheAge() +{ + if (mTimeResult != nullptr) { + return std::chrono::duration_cast + (std::chrono::steady_clock::now().time_since_epoch()).count() - mTimeResult->GetElapsedRealtimeMillis(); + } else { + return INT_MAX; + } +} + +int64_t NtpTrustedTime::GetCachedNtpTime() +{ + return mTimeResult == nullptr ? 0 : mTimeResult->GetTimeMillis(); +} + +int64_t NtpTrustedTime::GetCachedNtpTimeReference() +{ + return mTimeResult == nullptr ? 0 : mTimeResult->GetElapsedRealtimeMillis(); +} + +int64_t NtpTrustedTime::TimeResult::GetTimeMillis() +{ + return mTimeMillis; +} + +int64_t NtpTrustedTime::TimeResult::GetElapsedRealtimeMillis() +{ + return mElapsedRealtimeMillis; +} + +int64_t NtpTrustedTime::TimeResult::GetCertaintyMillis() +{ + return mCertaintyMillis; +} + +int64_t NtpTrustedTime::TimeResult::CurrentTimeMillis() +{ + return mTimeMillis + GetAgeMillis(); +} + +int64_t NtpTrustedTime::TimeResult::GetAgeMillis() +{ + return std::chrono::duration_cast + (std::chrono::steady_clock::now().time_since_epoch()).count() - this->mElapsedRealtimeMillis; +} + +NtpTrustedTime::TimeResult::TimeResult() {} +NtpTrustedTime::TimeResult::~TimeResult() {} + +NtpTrustedTime::TimeResult::TimeResult(int64_t mTimeMillis, int64_t mElapsedRealtimeMills, int64_t mCertaintyMillis) +{ + this->mTimeMillis = mTimeMillis; + this->mElapsedRealtimeMillis = mElapsedRealtimeMills; + this->mCertaintyMillis = mCertaintyMillis; +} + +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/services/time_manager/src/ntp_update_time.cpp b/services/time_manager/src/ntp_update_time.cpp new file mode 100644 index 00000000..1a385d7d --- /dev/null +++ b/services/time_manager/src/ntp_update_time.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ntp_trusted_time.h" +#include "time_common.h" +#include "json/json.h" +#include "ntp_update_time.h" +#include "time_service.h" +#include "nitz_subscriber.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace std::chrono; +namespace OHOS { +namespace MiscServices { +namespace { +constexpr uint64_t NANO_TO_MILESECOND = 1000000; +constexpr uint64_t DAY_TO_MILLISECOND = 86400000; +const std::string AUTOTIME_FILE_PATH = "/data/misc/zoneinfo/autotime.json"; +const std::string NETWORK_TIME_STATUS_ON = "ON"; +const std::string NETWORK_TIME_STATUS_OFF = "OFF"; +const std::string NTP_CN_SERVER = "1.cn.pool.ntp.org"; +const int64_t INVALID_NUM = -1; +} + +NtpUpdateTime::NtpUpdateTime(){}; +NtpUpdateTime::~NtpUpdateTime(){}; + +void NtpUpdateTime::Init() +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp Update Time start."); + SubscriberNITZTimeChangeCommonEvent(); + if (!GetAutoTimeInfoFromFile(autoTimeInfo_)) { + autoTimeInfo_.lastUpdateTime = INVALID_NUM; + autoTimeInfo_.NTP_SERVER = NTP_CN_SERVER; + autoTimeInfo_.status = NETWORK_TIME_STATUS_OFF; + if (!SaveAutoTimeInfoToFile(autoTimeInfo_)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "end, SaveAutoTimeInfoToFile failed."); + return; + } + if (!GetAutoTimeInfoFromFile(autoTimeInfo_)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "end, GetAutoTimeInfoFromFile failed."); + return; + } + } + if (autoTimeInfo_.status == NETWORK_TIME_STATUS_ON) { + SetSystemTime(); + } + int32_t timerType = ITimerManager::TimerType::ELAPSED_REALTIME; + auto callback = [this](uint64_t id){ + this->RefreshNetworkTimeByTimer(id); + }; + timerId_ = TimeService::GetInstance()->CreateTimer(timerType, 0, 0, 0, callback); + TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update timerId: %{public}" PRId64 "", timerId_); + RefreshNextTriggerTime(); + TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update triggertime: %{public}" PRId64 "", nextTriggerTime_); + TimeService::GetInstance()->StartTimer(timerId_, nextTriggerTime_); +} + +void NtpUpdateTime::SubscriberNITZTimeChangeCommonEvent() +{ + // Broadcast subscription + MatchingSkills matchingSkills; + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_NITZ_TIME_UPDATED); + CommonEventSubscribeInfo subscriberInfo(matchingSkills); + std::shared_ptr subscriberPtr = + std::make_shared(subscriberInfo); + if (subscriberPtr != nullptr) { + bool subscribeResult = CommonEventManager::SubscribeCommonEvent(subscriberPtr); + if (!subscribeResult) { + TIME_HILOGE(TIME_MODULE_SERVICE, "SubscribeCommonEvent failed"); + } + } +} + +void NtpUpdateTime::RefreshNetworkTimeByTimer(const uint64_t timerId) +{ + if (!(CheckStatus())) { + TIME_HILOGD(TIME_MODULE_SERVICE, "Network time status off."); + return; + } + if (IsNITZTimeInvalid()) { + TIME_HILOGD(TIME_MODULE_SERVICE, "NITZ Time is valid."); + return; + } + SetSystemTime(); + SaveAutoTimeInfoToFile(autoTimeInfo_); + timerId_ = timerId; + RefreshNextTriggerTime(); + auto startFunc = [this](){ + this->StartTimer(); + }; + std::thread startTimerThread(startFunc); + startTimerThread.detach(); + TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update triggertime: %{public}" PRId64 "", nextTriggerTime_); +} + +void NtpUpdateTime::UpdateNITZSetTime() +{ + auto BootTimeNano = steady_clock::now().time_since_epoch().count(); + auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND; + TIME_HILOGD(TIME_MODULE_SERVICE, "nitz time changed: %{public}" PRId64 "", BootTimeMilli); + nitzUpdateTimeMili_ = BootTimeMilli; +} + +void NtpUpdateTime::SetSystemTime() +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + if (!DelayedSingleton::GetInstance()->ForceRefresh(autoTimeInfo_.NTP_SERVER)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "get ntp time failed."); + return; + } + int64_t currentTime = DelayedSingleton::GetInstance()->CurrentTimeMillis(); + TimeService::GetInstance()->SetTime(currentTime); + autoTimeInfo_.lastUpdateTime = currentTime; + TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update currentTime: %{public}" PRId64 "", currentTime); + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); +} + +void NtpUpdateTime::RefreshNextTriggerTime() +{ + auto BootTimeNano = steady_clock::now().time_since_epoch().count(); + auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND; + nextTriggerTime_ = BootTimeMilli + DAY_TO_MILLISECOND; + return; +} + +void NtpUpdateTime::UpdateStatusOff() +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start"); + autoTimeInfo_.lastUpdateTime = INVALID_NUM; + autoTimeInfo_.NTP_SERVER = NTP_CN_SERVER; + autoTimeInfo_.status = NETWORK_TIME_STATUS_OFF; + if (!SaveAutoTimeInfoToFile(autoTimeInfo_)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "end, SaveAutoTimeInfoToFile failed."); + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end"); +} + +void NtpUpdateTime::UpdateStatusOn() +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start"); + if (CheckStatus()) { + TIME_HILOGD(TIME_MODULE_SERVICE, "network update time status is already on."); + return; + } + SetSystemTime(); + autoTimeInfo_.status = NETWORK_TIME_STATUS_ON; + if (!SaveAutoTimeInfoToFile(autoTimeInfo_)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "end, SaveAutoTimeInfoToFile failed."); + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end"); +} + +bool NtpUpdateTime::CheckStatus() +{ + return autoTimeInfo_.status == NETWORK_TIME_STATUS_ON; +} + +bool NtpUpdateTime::IsNITZTimeInvalid() +{ + auto BootTimeNano = steady_clock::now().time_since_epoch().count(); + auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND; + return (BootTimeMilli - nitzUpdateTimeMili_) < DAY_TO_MILLISECOND; +} + +void NtpUpdateTime::StartTimer() +{ + TimeService::GetInstance()->StartTimer(timerId_, nextTriggerTime_); +} + +void NtpUpdateTime::Stop() +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + TimeService::GetInstance()->DestroyTimer(timerId_); +} + +bool NtpUpdateTime::GetAutoTimeInfoFromFile(autoTimeInfo &info) +{ + Json::Value root; + std::ifstream ifs; + ifs.open(AUTOTIME_FILE_PATH); + Json::CharReaderBuilder builder; + builder["collectComments"] = true; + JSONCPP_STRING errs; + if (!parseFromStream(builder, ifs, &root, &errs)) { + ifs.close(); + TIME_HILOGE(TIME_MODULE_SERVICE, "Read file failed %{public}s.", errs.c_str()); + return false; + } + info.status = root["status"].asString(); + info.NTP_SERVER = root["ntpServer"].asString(); + info.lastUpdateTime = root["lastUpdateTime"].asInt64(); + TIME_HILOGD(TIME_MODULE_SERVICE, "Read file %{public}s.", info.status.c_str()); + TIME_HILOGD(TIME_MODULE_SERVICE, "Read file %{public}s.", info.NTP_SERVER.c_str()); + TIME_HILOGD(TIME_MODULE_SERVICE, "Read file %{public}lld.", info.lastUpdateTime); + ifs.close(); + return true; +} + +bool NtpUpdateTime::SaveAutoTimeInfoToFile(autoTimeInfo &info) { + Json::Value root; + std::ofstream ofs; + ofs.open(AUTOTIME_FILE_PATH); + root["status"] = info.status; + root["ntpServer"] = info.NTP_SERVER; + root["lastUpdateTime"] = info.lastUpdateTime; + Json::StreamWriterBuilder builder; + const std::string json_file = Json::writeString(builder, root); + ofs << json_file; + ofs.close(); + TIME_HILOGD(TIME_MODULE_SERVICE, "Write file %{public}s.", info.status.c_str()); + TIME_HILOGD(TIME_MODULE_SERVICE, "Write file %{public}s.", info.NTP_SERVER.c_str()); + TIME_HILOGD(TIME_MODULE_SERVICE, "Write file %{public}lld.", info.lastUpdateTime); + return true; +} +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/services/time_manager/src/sntp_client.cpp b/services/time_manager/src/sntp_client.cpp new file mode 100644 index 00000000..e1844199 --- /dev/null +++ b/services/time_manager/src/sntp_client.cpp @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "sntp_client.h" +#include "time_common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NTP_PORT (123) +#define NTP_MSG_OFFSET_ROOT_DELAY (4) +#define NTP_MSG_OFFSET_ROOT_DISPERSION (8) +#define NTP_MSG_OFFSET_REFERENCE_IDENTIFIER (12) +#define REFERENCE_TIMESTAMP_OFFSET (16) +#define ORIGINATE_TIMESTAMP_OFFSET (24) +#define RECEIVE_TIMESTAMP_OFFSET (32) +#define TRANSMIT_TIMESTAMP_OFFSET (40) +#define NTP_PACKAGE_SIZE (48) // in bytes + +#define SECOND_OF_DAY (86400) +#define SECOND_OF_HOUR (3600) +#define SECOND_OF_MINUTE (60) + +namespace OHOS { +namespace MiscServices { +namespace { + constexpr auto SECONDS_SINCE_FIRST_EPOCH = (2208988800UL); // Seconds from 1/1/1900 00.00 to 1/1/1970 00.00; + constexpr uint64_t MICRO_TO_MILESECOND = 1000; + constexpr uint64_t MILLISECOND_TO_SECOND = 1000; + constexpr uint64_t FRACTION_TO_SECOND = 0x100000000; +} +SNTPClient::SNTPClient() {} +SNTPClient::~SNTPClient() {} + +bool SNTPClient::RequestTime(std::string host) +{ + int iResult; + struct sockaddr_in RecvAddr; + unsigned short Port = NTP_PORT; + int BufLen = NTP_PACKAGE_SIZE; + + // Create a socket for sending data + int SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (SendSocket == 0) { + TIME_HILOGE(TIME_MODULE_SERVICE, "socket failed with error: %{public}d", 0); + return false; + } + + struct hostent* hostV; + if ((hostV = gethostbyname(host.c_str())) == nullptr) + { + //More descriptive error message? + TIME_HILOGE(TIME_MODULE_SERVICE, "Get host by name %{public}s but get nullptr.", host.c_str()); + return false; + } + + memset_s((char*)& RecvAddr, sizeof(RecvAddr), 0, sizeof(RecvAddr)); + RecvAddr.sin_family = AF_INET; + memcpy_s((char*)& RecvAddr.sin_addr.s_addr, hostV->h_length, (char*)hostV->h_addr, hostV->h_length); + RecvAddr.sin_port = htons(Port); + if (connect(SendSocket, (struct sockaddr*) & RecvAddr, sizeof(RecvAddr)) < 0) + { + TIME_HILOGE(TIME_MODULE_SERVICE, "Connect socket failed with host: %{public}s", host.c_str()); + return false; + } + + //--------------------------------------------------------------------- + // Create the NTP tx timestamp and fill the fields in the msg to be tx + char SendBuf[NTP_PACKAGE_SIZE] = {0}; + CreateMessage(SendBuf); + iResult = send(SendSocket, SendBuf, BufLen, 0); + if (iResult == -1) { + TIME_HILOGE(TIME_MODULE_SERVICE, "Send socket message failed. Host: %{public}s", host.c_str()); + close(SendSocket); + return false; + } + + char bufferRx[NTP_PACKAGE_SIZE] = { 0 }; + // Receive until the peer closes the connection + iResult = recv(SendSocket, bufferRx, NTP_PACKAGE_SIZE, 0); + if (iResult == -1) { + TIME_HILOGE(TIME_MODULE_SERVICE, "Recieve socket message failed. Host: %{public}s", host.c_str()); + close(SendSocket); + return false; + } + + ReceivedMessage(bufferRx); + return true; +} + + +void SNTPClient::SetClockOffset(int clockOffset) +{ + m_clockOffset = clockOffset; +} + +int SNTPClient::GetClockOffset(void) +{ + return m_clockOffset; +} + +uint64_t SNTPClient::GetNtpTimestamp64(int offset, char* buffer) +{ + const int _len = sizeof(uint64_t); + char valueRx[_len]; + memset_s(valueRx,_len, 0, _len); + int jj = sizeof(uint64_t) - 1; + for (int ii = offset; ii < offset + _len; ii++) { + valueRx[jj] = buffer[ii]; + jj--; + } + + uint64_t milliseconds; + memcpy_s(&milliseconds,sizeof(uint64_t), valueRx, sizeof(uint64_t)); + + return milliseconds; +} + +void SNTPClient::convert_unix_to_ntp(struct ntp_timestamp *ntpTs, struct timeval *unixTs) +{ + // 0x83AA7E80; the seconds from Jan 1, 1900 to Jan 1, 1970 + ntpTs->second = unixTs->tv_sec + SECONDS_SINCE_FIRST_EPOCH;//0x83AA7E80; + ntpTs->fraction = (uint32_t)((double)(unixTs->tv_usec + 1) * (double)(1LL << 32) * 1.0e-6); +} + +void SNTPClient::convert_ntp_to_unix(struct ntp_timestamp *ntpTs, struct timeval *unixTs) +{ + // 0x83AA7E80; the seconds from Jan 1, 1900 to Jan 1, 1970 + unixTs->tv_sec = ntpTs->second - SECONDS_SINCE_FIRST_EPOCH; + unixTs->tv_usec = (uint32_t)((double)ntpTs->fraction * 1.0e6 / (double)(1LL << 32)); +} + +uint64_t SNTPClient::convert_ntp_to_date(uint64_t _ntpTs, struct date_structure *_outDataTs) +{ + uint32_t second = (uint32_t)((_ntpTs >> 32) & 0xFFFFFFFF); + uint32_t fraction = (uint32_t)(_ntpTs & 0xFFFFFFFF); + + struct timeval unix; + struct ntp_timestamp ntpTs; + ntpTs.second = second; + ntpTs.fraction = fraction; + + convert_ntp_to_unix(&ntpTs, &unix); + _outDataTs->hour = (unix.tv_sec % SECOND_OF_DAY) / SECOND_OF_HOUR; + _outDataTs->minute = (unix.tv_sec % SECOND_OF_HOUR) / SECOND_OF_MINUTE; + _outDataTs->second = (unix.tv_sec % SECOND_OF_MINUTE); + _outDataTs->millisecond = unix.tv_usec; + + std::ostringstream _ss; + _ss << std::internal + << std::setfill('0') + << std::setw(2) + << _outDataTs->hour + << std::internal + << std::setfill('0') + << std::setw(2) + << _outDataTs->minute + << std::internal + << std::setfill('0') + << std::setw(2) << _outDataTs->second + << std::internal + << std::setfill('0') + << std::setw(6) + << _outDataTs->millisecond; + + std::string _s = _ss.str(); + return (stoull(_s)); + + +} +/* + * /// SNTP Timestamp Format (as described in RFC 2030) + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Seconds | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Seconds Fraction (0-padded) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +uint64_t SNTPClient::convert_ntp_to_stamp(uint64_t _ntpTs) { + uint32_t second = (uint32_t)((_ntpTs >> 32) & 0xFFFFFFFF); + uint32_t fraction = (uint32_t)(_ntpTs & 0xFFFFFFFF); + if (second == 0 && fraction == 0) { + return 0; + } + return ((second - SECONDS_SINCE_FIRST_EPOCH) * MILLISECOND_TO_SECOND) + + ((fraction * MILLISECOND_TO_SECOND) / FRACTION_TO_SECOND); +} + +void SNTPClient::CreateMessage(char* buffer) +{ + struct ntp_timestamp ntp; + struct timeval unix; + + gettimeofday(&unix, NULL); + // convert unix time to ntp time + convert_unix_to_ntp(&ntp, &unix); + convert_ntp_to_unix(&ntp, &unix); + uint64_t _ntpTs = ntp.second; + _ntpTs = (_ntpTs << 32) | ntp.fraction; + m_originateTimestamp = _ntpTs; + + SNTPMessage _sntpMsg; + // Important, if you don't set the version/mode, the server will ignore you. + _sntpMsg.clear(); + _sntpMsg._leapIndicator = 0; + _sntpMsg._versionNumber = 3; + _sntpMsg._mode = 3; + //optional (?) + _sntpMsg._originateTimestamp = _ntpTs; + char value[sizeof(uint64_t)]; + memcpy_s(value,sizeof(uint64_t), &_sntpMsg._originateTimestamp, sizeof(uint64_t)); + int jj = sizeof(uint64_t) - 1; + int ofssetEnd = ORIGINATE_TIMESTAMP_OFFSET + sizeof(uint64_t); + for (int ii = ORIGINATE_TIMESTAMP_OFFSET; ii < ofssetEnd; ii++) + { + buffer[ii] = value[jj]; + jj--; + } + // create the 1-byte info in one go... the result should be 27 :) + buffer[0] = (_sntpMsg._leapIndicator << 6) | (_sntpMsg._versionNumber << 3) | _sntpMsg._mode; +} + +void SNTPClient::WriteTimeStamp(char* buffer,ntp_timestamp *ntp) +{ + uint64_t _ntpTs = ntp->second; + _ntpTs = (_ntpTs << 32) | ntp->fraction; + m_originateTimestamp = _ntpTs; + + SNTPMessage _sntpMsg; + // Important, if you don't set the version/mode, the server will ignore you. + _sntpMsg.clear(); + _sntpMsg._leapIndicator = 0; + _sntpMsg._versionNumber = 3; + _sntpMsg._mode = 3; + _sntpMsg._originateTimestamp = _ntpTs; + char value[sizeof(uint64_t)]; + memcpy_s(value, sizeof(uint64_t),&_sntpMsg._originateTimestamp, sizeof(uint64_t)); + int jj = sizeof(uint64_t) - 1; + int ofssetEnd = ORIGINATE_TIMESTAMP_OFFSET + sizeof(uint64_t); + for (int ii = ORIGINATE_TIMESTAMP_OFFSET; ii < ofssetEnd; ii++) + { + buffer[ii] = value[jj]; + jj--; + } + // create the 1-byte info in one go... the result should be 27 :) + buffer[0] = (_sntpMsg._leapIndicator << 6) | (_sntpMsg._versionNumber << 3) | _sntpMsg._mode; +} + +void SNTPClient::ReceivedMessage(char* buffer) +{ + struct ntp_timestamp ntp; + struct timeval unix; + + gettimeofday(&unix, NULL); + convert_unix_to_ntp(&ntp, &unix); + uint64_t _ntpTs = ntp.second; + _ntpTs = (_ntpTs << 32) | ntp.fraction; + + SNTPMessage _sntpMsg; + _sntpMsg.clear(); + _sntpMsg._leapIndicator = buffer[0] >> 6; + _sntpMsg._versionNumber = (buffer[0] & 0x38) >> 3; + _sntpMsg._mode = (buffer[0] & 0x7); + _sntpMsg._stratum = buffer[1]; + _sntpMsg._pollInterval = buffer[2]; + _sntpMsg._precision = buffer[3]; + _sntpMsg._rootDelay = GetNtpField32(NTP_MSG_OFFSET_ROOT_DELAY, buffer); + _sntpMsg._rootDispersion = GetNtpField32(NTP_MSG_OFFSET_ROOT_DISPERSION, buffer); + int _refId[4]; + GetReferenceId(NTP_MSG_OFFSET_REFERENCE_IDENTIFIER, buffer, _refId); + _sntpMsg._referenceIdentifier[0] = _refId[0]; + _sntpMsg._referenceIdentifier[1] = _refId[1]; + _sntpMsg._referenceIdentifier[2] = _refId[2]; + _sntpMsg._referenceIdentifier[3] = _refId[3]; + _sntpMsg._referenceTimestamp = GetNtpTimestamp64(REFERENCE_TIMESTAMP_OFFSET, buffer); + _sntpMsg._originateTimestamp = GetNtpTimestamp64(ORIGINATE_TIMESTAMP_OFFSET, buffer); + _sntpMsg._receiveTimestamp = GetNtpTimestamp64(RECEIVE_TIMESTAMP_OFFSET, buffer); + _sntpMsg._transmitTimestamp = GetNtpTimestamp64(TRANSMIT_TIMESTAMP_OFFSET, buffer); + + uint64_t _tempOriginate = m_originateTimestamp; + if (_sntpMsg._originateTimestamp > 0) + _tempOriginate = _sntpMsg._originateTimestamp; + + struct date_structure dataTs; + uint64_t _originClient = convert_ntp_to_date(_tempOriginate, &dataTs); + uint64_t _receiveServer = convert_ntp_to_date(_sntpMsg._receiveTimestamp, &dataTs); + uint64_t _transmitServer = convert_ntp_to_date(_sntpMsg._transmitTimestamp, &dataTs); + uint64_t _receiveClient = convert_ntp_to_date(_ntpTs, &dataTs); + + int _clockOffset = (((_receiveServer - _originClient) + (_transmitServer - _receiveClient)) / 2); + _clockOffset = _clockOffset / MICRO_TO_MILESECOND; + int _roundTripDelay = (_receiveClient - _originClient) - (_receiveServer - _transmitServer); + _roundTripDelay = _roundTripDelay / MICRO_TO_MILESECOND; + mRoundTripTime = _roundTripDelay; + mNtpTime = convert_ntp_to_stamp(_ntpTs) + _clockOffset; + mNtpTimeReference = std::chrono::duration_cast + (std::chrono::steady_clock::now().time_since_epoch()).count(); + SetClockOffset(_clockOffset); +} + +unsigned int SNTPClient::GetNtpField32(int offset, char* buffer) +{ + const int _len = sizeof(int); + char valueRx[_len]; + memset_s(valueRx,_len, 0, _len); + int jj = sizeof(int) - 1; + for (int ii = offset; ii < offset + _len; ii++) + { + valueRx[jj] = buffer[ii]; + jj--; + } + + unsigned int milliseconds; + memcpy_s(&milliseconds,sizeof(int), valueRx, sizeof(int)); + + return milliseconds; +} + +void SNTPClient::GetReferenceId(int offset, char* buffer, int* _outArray) +{ + const int _len = sizeof(int); + int jj = 0; + for (int ii = offset; ii < offset + _len; ii++) + { + _outArray[jj] = buffer[ii]; + jj++; + } +} + +std::string SNTPClient::GetLeapString(unsigned char _leapIndicator) +{ + std::string var = ""; + switch (_leapIndicator) + { + case 0: + var = "NoWarning"; + break; + case 1: + var = "LastMinute61"; + break; + case 2: + var = "LastMinute59"; + break; + case 3: + var = "Alarm"; + break; + } + + return var; +} + +std::string SNTPClient::GetModeString(unsigned char _mode) +{ + std::string var = ""; + switch (_mode) + { + case 1: + var = "SymmetricActive"; + break; + case 2: + var = "SymmetricPassive"; + break; + case 3: + var = "Client"; + break; + case 4: + var = "Server"; + break; + case 5: + var = "Broadcast"; + break; + default: + var = "Reserved"; + break; + } + + return var; +} + +std::string SNTPClient::GetStratumString(unsigned char _stratum) +{ + std::string var = ""; + if (_stratum == 0) + { + var = "Unspecified"; + } + else if (_stratum == 1) + { + var = "PrimaryReference"; + } + else if (_stratum > 1 && _stratum < 16) + { + var = "SecondaryReference"; + } + else + var = "Reserved"; + + return var; +} + +void SNTPClient::SNTPMessage::clear() +{ + memset_s(this,sizeof(*this), 0, sizeof(*this)); +} + +int64_t SNTPClient::getNtpTIme() +{ + return mNtpTime; +} + +int64_t SNTPClient::getNtpTimeReference() +{ + return mNtpTimeReference; +} + +int64_t SNTPClient::getRoundTripTime() +{ + return mRoundTripTime; +} + +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index 75131144..9f369702 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -31,6 +31,7 @@ #include #include #include "pthread.h" +#include "ntp_update_time.h" #include "time_zone_info.h" #include "time_common.h" #include "time_tick_notify.h" @@ -102,6 +103,7 @@ void TimeService::OnStart() InitNotifyHandler(); DelayedSingleton::GetInstance()->Init(); DelayedSingleton::GetInstance()->Init(); + DelayedSingleton::GetInstance()->Init(); if (Init() != ERR_OK) { auto callback = [=]() { Init(); }; serviceHandler_->PostTask(callback, INIT_INTERVAL); @@ -569,5 +571,14 @@ bool TimeService::GetTimeByClockid(clockid_t clk_id, struct timespec &tv) } return true; } +void TimeService::NetworkTimeStatusOff() +{ + DelayedSingleton::GetInstance()->UpdateStatusOff(); +} + +void TimeService::NetworkTimeStatusOn() +{ + DelayedSingleton::GetInstance()->UpdateStatusOn(); +} } // namespace MiscServices } // namespace OHOS diff --git a/services/time_manager/src/time_service_proxy.cpp b/services/time_manager/src/time_service_proxy.cpp index 1d69de8b..34be7495 100644 --- a/services/time_manager/src/time_service_proxy.cpp +++ b/services/time_manager/src/time_service_proxy.cpp @@ -352,5 +352,41 @@ int32_t TimeServiceProxy::GetThreadTimeNs(int64_t ×) times = reply.ReadInt64(); return result; } + +void TimeServiceProxy::NetworkTimeStatusOn() +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return; + } + + int32_t result = Remote()->SendRequest(NETWORK_TIME_ON, data, reply, option); + if (result != ERR_NONE) { + TIME_HILOGE(TIME_MODULE_CLIENT, "NetworkTimeStatusOn failed, error code is: %{public}d", result); + return; + } + return; +} +void TimeServiceProxy::NetworkTimeStatusOff() +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return; + } + + int32_t result = Remote()->SendRequest(NETWORK_TIME_OFF, data, reply, option); + if (result != ERR_NONE) { + TIME_HILOGE(TIME_MODULE_CLIENT, "NetworkTimeStatusOff failed, error code is: %{public}d", result); + return; + } + + return; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/time_manager/src/time_service_stub.cpp b/services/time_manager/src/time_service_stub.cpp index 3d8bde61..4674291c 100644 --- a/services/time_manager/src/time_service_stub.cpp +++ b/services/time_manager/src/time_service_stub.cpp @@ -289,5 +289,21 @@ int32_t TimeServiceStub::OnDestoryTimer(MessageParcel &data, MessageParcel &repl TIME_HILOGI(TIME_MODULE_SERVICE, "end."); return ERR_OK; } + +int32_t TimeServiceStub::OnNetworkTimeStatusOff(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start."); + NetworkTimeStatusOff(); + TIME_HILOGI(TIME_MODULE_SERVICE, "end."); + return ERR_OK; +} + +int32_t TimeServiceStub::OnNetworkTimeStatusOn(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start."); + NetworkTimeStatusOn(); + TIME_HILOGI(TIME_MODULE_SERVICE, "end."); + return ERR_OK; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file -- Gitee From 1e500ca3e07ac38b502227da35f3a4c93cdb01de Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Mon, 14 Feb 2022 00:20:58 +0800 Subject: [PATCH 4/6] 2022021201 Signed-off-by: guduhanyan --- services/BUILD.gn | 8 ++++---- services/time_manager/src/ntp_update_time.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services/BUILD.gn b/services/BUILD.gn index 5bd6fe30..56463e8c 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -39,6 +39,10 @@ ohos_shared_library("time_service") { sources = [ "time_manager/src/itimer_info.cpp", + "time_manager/src/nitz_subscriber.cpp", + "time_manager/src/ntp_trusted_time.cpp", + "time_manager/src/ntp_update_time.cpp", + "time_manager/src/sntp_client.cpp", "time_manager/src/time_service.cpp", "time_manager/src/time_service_client.cpp", "time_manager/src/time_service_notify.cpp", @@ -49,10 +53,6 @@ ohos_shared_library("time_service") { "time_manager/src/timer_call_back.cpp", "time_manager/src/timer_call_back_proxy.cpp", "time_manager/src/timer_call_back_stub.cpp", - "time_manager/src/sntp_client.cpp", - "time_manager/src/ntp_trusted_time.cpp", - "time_manager/src/ntp_update_time.cpp", - "time_manager/src/nitz_subscriber.cpp", "timer/src/batch.cpp", "timer/src/timer_handler.cpp", "timer/src/timer_info.cpp", diff --git a/services/time_manager/src/ntp_update_time.cpp b/services/time_manager/src/ntp_update_time.cpp index 1a385d7d..f27e833d 100644 --- a/services/time_manager/src/ntp_update_time.cpp +++ b/services/time_manager/src/ntp_update_time.cpp @@ -211,7 +211,7 @@ bool NtpUpdateTime::GetAutoTimeInfoFromFile(autoTimeInfo &info) info.lastUpdateTime = root["lastUpdateTime"].asInt64(); TIME_HILOGD(TIME_MODULE_SERVICE, "Read file %{public}s.", info.status.c_str()); TIME_HILOGD(TIME_MODULE_SERVICE, "Read file %{public}s.", info.NTP_SERVER.c_str()); - TIME_HILOGD(TIME_MODULE_SERVICE, "Read file %{public}lld.", info.lastUpdateTime); + TIME_HILOGD(TIME_MODULE_SERVICE, "Read file %{public}" PRId64 "", info.lastUpdateTime); ifs.close(); return true; } @@ -229,7 +229,7 @@ bool NtpUpdateTime::SaveAutoTimeInfoToFile(autoTimeInfo &info) { ofs.close(); TIME_HILOGD(TIME_MODULE_SERVICE, "Write file %{public}s.", info.status.c_str()); TIME_HILOGD(TIME_MODULE_SERVICE, "Write file %{public}s.", info.NTP_SERVER.c_str()); - TIME_HILOGD(TIME_MODULE_SERVICE, "Write file %{public}lld.", info.lastUpdateTime); + TIME_HILOGD(TIME_MODULE_SERVICE, "Write file %{public}" PRId64 "", info.lastUpdateTime); return true; } } // MiscServices -- Gitee From 30c1f5f9e8613d9fca92ddc3b47511093df17879 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Mon, 14 Feb 2022 07:03:09 +0800 Subject: [PATCH 5/6] 2022021401 Signed-off-by: guduhanyan --- services/time_manager/src/ntp_update_time.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/services/time_manager/src/ntp_update_time.cpp b/services/time_manager/src/ntp_update_time.cpp index f27e833d..ae375c2a 100644 --- a/services/time_manager/src/ntp_update_time.cpp +++ b/services/time_manager/src/ntp_update_time.cpp @@ -12,14 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "ntp_trusted_time.h" -#include "time_common.h" -#include "json/json.h" -#include "ntp_update_time.h" -#include "time_service.h" -#include "nitz_subscriber.h" - #include #include #include @@ -28,6 +20,13 @@ #include #include +#include "ntp_trusted_time.h" +#include "time_common.h" +#include "json/json.h" +#include "time_service.h" +#include "nitz_subscriber.h" +#include "ntp_update_time.h" + using namespace std::chrono; namespace OHOS { namespace MiscServices { -- Gitee From 6b1d8f521b600ceac69ca2c73f24ed9bc340f1ab Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Mon, 14 Feb 2022 07:48:58 +0800 Subject: [PATCH 6/6] 2022021401 Signed-off-by: guduhanyan --- services/time_manager/src/ntp_update_time.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/time_manager/src/ntp_update_time.cpp b/services/time_manager/src/ntp_update_time.cpp index ae375c2a..aedd0fca 100644 --- a/services/time_manager/src/ntp_update_time.cpp +++ b/services/time_manager/src/ntp_update_time.cpp @@ -116,7 +116,7 @@ void NtpUpdateTime::UpdateNITZSetTime() { auto BootTimeNano = steady_clock::now().time_since_epoch().count(); auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND; - TIME_HILOGD(TIME_MODULE_SERVICE, "nitz time changed: %{public}" PRId64 "", BootTimeMilli); + TIME_HILOGD(TIME_MODULE_SERVICE, "nitz time changed."); nitzUpdateTimeMili_ = BootTimeMilli; } -- Gitee