1 /*
2 * Copyright (c) 2021 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 "adapter/dnetwork_adapter.h"
17
18 #include <chrono>
19 #include <mutex>
20 #include <thread>
21 #include <unistd.h>
22
23 #include "datetime_ex.h"
24 #include "dtbschedmgr_log.h"
25
26 namespace OHOS {
27 namespace DistributedSchedule {
28 using namespace std::chrono_literals;
29
30 namespace {
31 constexpr int32_t DEVICE_ID_SIZE = 65;
32 constexpr int32_t RETRY_REGISTER_CALLBACK_TIMES = 5;
33 const std::string PKG_NAME = "DBinderBus_" + std::to_string(getpid());
34
35 constexpr int32_t NON_ANONYMIZED_LENGTH = 6;
36 const std::string EMPTY_DEVICE_ID = "";
37 const std::string TAG = "DnetworkAdapter";
38 }
39
40 std::shared_ptr<AppExecFwk::EventHandler> DnetworkAdapter::dnetworkHandler_;
41 std::mutex DnetworkAdapter::listenerSetMutex_;
42 std::set<std::shared_ptr<DeviceListener>> DnetworkAdapter::listenerSet_;
43
GetInstance()44 std::shared_ptr<DnetworkAdapter> DnetworkAdapter::GetInstance()
45 {
46 static auto instance = std::make_shared<DnetworkAdapter>();
47 return instance;
48 }
49
Init()50 void DnetworkAdapter::Init()
51 {
52 nodeStateCb_.events = EVENT_NODE_STATE_MASK;
53 nodeStateCb_.onNodeOnline = OnNodeOnline;
54 nodeStateCb_.onNodeOffline = OnNodeOffline;
55 nodeStateCb_.onNodeBasicInfoChanged = OnNodeBasicInfoChanged;
56
57 auto runner = AppExecFwk::EventRunner::Create("dmsDnetwork");
58 dnetworkHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
59 }
60
OnNodeOnline(NodeBasicInfo * info)61 void DnetworkAdapter::OnNodeOnline(NodeBasicInfo* info)
62 {
63 if (info == nullptr) {
64 HILOGE("OnNodeOnline invalid parameter");
65 return;
66 }
67
68 HILOGI("OnNodeOnline netwokId = %{public}s", AnonymizeDeviceId(info->networkId).c_str());
69 auto onlineNotifyTask = [info = *info]() {
70 std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
71 for (auto& listener : listenerSet_) {
72 listener->OnDeviceOnline(&info);
73 }
74 };
75 if (!dnetworkHandler_->PostTask(onlineNotifyTask)) {
76 HILOGE("OnNodeOnline post task failed");
77 return;
78 }
79 }
80
OnNodeOffline(NodeBasicInfo * info)81 void DnetworkAdapter::OnNodeOffline(NodeBasicInfo* info)
82 {
83 if (info == nullptr) {
84 HILOGE("OnNodeOffline invalid parameter");
85 return;
86 }
87
88 HILOGI("OnNodeOffline networkId = %{public}s", AnonymizeDeviceId(info->networkId).c_str());
89 auto offlineNotifyTask = [info = *info]() {
90 std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
91 for (auto& listener : listenerSet_) {
92 listener->OnDeviceOffline(&info);
93 }
94 };
95 if (!dnetworkHandler_->PostTask(offlineNotifyTask)) {
96 HILOGE("OnNodeOffline post task failed");
97 return;
98 }
99 }
100
OnNodeBasicInfoChanged(NodeBasicInfoType type,NodeBasicInfo * info)101 void DnetworkAdapter::OnNodeBasicInfoChanged(NodeBasicInfoType type, NodeBasicInfo* info)
102 {
103 HILOGD("OnNodeBasicInfoChanged called");
104 }
105
AddDeviceChangeListener(const std::shared_ptr<DeviceListener> & listener)106 bool DnetworkAdapter::AddDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)
107 {
108 HILOGD("AddDeviceChangeListener called");
109 if (dnetworkHandler_ == nullptr) {
110 HILOGE("handler is null");
111 return false;
112 }
113
114 {
115 std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
116 if (listenerSet_.find(listener) == listenerSet_.end()) {
117 listenerSet_.insert(listener);
118 }
119 if (listenerSet_.size() > 1) {
120 return true;
121 }
122 }
123
124 auto registerTask = [this]() {
125 HILOGD("AddDeviceChangeListener register mission...");
126 int32_t retryTimes = 0;
127 int32_t errCode = ERR_OK;
128 while (retryTimes++ < RETRY_REGISTER_CALLBACK_TIMES) {
129 errCode = RegNodeDeviceStateCb(PKG_NAME.c_str(), &nodeStateCb_);
130 if (errCode == ERR_OK) {
131 break;
132 }
133
134 HILOGD("AddDeviceChangeListener Reg errCode = %{public}d, retrying...", errCode);
135 errCode = UnregNodeDeviceStateCb(&nodeStateCb_);
136 HILOGD("AddDeviceChangeListener Unreg errCode = %{public}d", errCode);
137 std::this_thread::sleep_for(1s);
138 }
139 HILOGI("AddDeviceChangeListener %{public}s", (errCode == ERR_OK) ? "success" : "timeout");
140 };
141 if (!dnetworkHandler_->PostTask(registerTask)) {
142 HILOGE("AddDeviceChangeListener post task failed");
143 return false;
144 }
145 return true;
146 }
147
RemoveDeviceChangeListener(const std::shared_ptr<DeviceListener> & listener)148 void DnetworkAdapter::RemoveDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)
149 {
150 HILOGD("RemoveDeviceChangeListener called");
151 {
152 std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
153 listenerSet_.erase(listener);
154 if (listenerSet_.size() > 0) {
155 return;
156 }
157 }
158
159 int32_t errCode = UnregNodeDeviceStateCb(&nodeStateCb_);
160 if (errCode != ERR_OK) {
161 HILOGE("RemoveDeviceChangeListener remove failed, errCode = %{public}d", errCode);
162 }
163 HILOGE("RemoveDeviceChangeListener remove ok");
164 }
165
GetLocalBasicInfo()166 std::shared_ptr<NodeBasicInfo> DnetworkAdapter::GetLocalBasicInfo()
167 {
168 auto info = std::make_shared<NodeBasicInfo>();
169 int32_t errCode = GetLocalNodeDeviceInfo(PKG_NAME.c_str(), info.get());
170 if (errCode != ERR_OK) {
171 HILOGE("GetLocalBasicInfo errCode = %{public}d", errCode);
172 return nullptr;
173 }
174 return info;
175 }
176
GetUdidByNetworkId(const std::string & networkId)177 std::string DnetworkAdapter::GetUdidByNetworkId(const std::string& networkId)
178 {
179 return GetUuidOrUdidByNetworkId(networkId, NodeDeviceInfoKey::NODE_KEY_UDID);
180 }
181
GetUuidByNetworkId(const std::string & networkId)182 std::string DnetworkAdapter::GetUuidByNetworkId(const std::string& networkId)
183 {
184 return GetUuidOrUdidByNetworkId(networkId, NodeDeviceInfoKey::NODE_KEY_UUID);
185 }
186
GetUuidOrUdidByNetworkId(const std::string & networkId,NodeDeviceInfoKey keyType)187 std::string DnetworkAdapter::GetUuidOrUdidByNetworkId(const std::string& networkId, NodeDeviceInfoKey keyType)
188 {
189 if (networkId.empty()) {
190 return std::string();
191 }
192
193 char uuidOrUdid[DEVICE_ID_SIZE] = {0};
194 int32_t ret = GetNodeKeyInfo(PKG_NAME.c_str(), networkId.c_str(), keyType,
195 reinterpret_cast<uint8_t*>(uuidOrUdid), DEVICE_ID_SIZE);
196 return (ret == ERR_OK) ? std::string(uuidOrUdid) : std::string();
197 }
198
AnonymizeDeviceId(const std::string & deviceId)199 std::string DnetworkAdapter::AnonymizeDeviceId(const std::string& deviceId)
200 {
201 if (deviceId.length() < NON_ANONYMIZED_LENGTH) {
202 return EMPTY_DEVICE_ID;
203 }
204 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZED_LENGTH);
205 anonDeviceId.append("******");
206 return anonDeviceId;
207 }
208 } // namespace DistributedSchedule
209 } // namespace OHOS
210