1 /*
2 * Copyright (C) 2023 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 "mdns_client.h"
17
18 #include <condition_variable>
19 #include <mutex>
20 #include <unistd.h>
21 #include <thread>
22
23 #include "if_system_ability_manager.h"
24 #include "iservice_registry.h"
25 #include "netmgr_ext_log_wrapper.h"
26 #include "system_ability_definition.h"
27
28 #include "mdns_common.h"
29 #include "mdns_client_resume.h"
30
31 namespace OHOS {
32 namespace NetManagerStandard {
33
34 std::mutex g_loadMutex;
35 std::condition_variable g_cv;
36
OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)37 void OnDemandLoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
38 {
39 NETMGR_EXT_LOG_D("OnLoadSystemAbilitySuccess systemAbilityId: [%{public}d]", systemAbilityId);
40 g_loadMutex.lock();
41 remoteObject_ = remoteObject;
42 g_loadMutex.unlock();
43 g_cv.notify_one();
44 }
45
OnLoadSystemAbilityFail(int32_t systemAbilityId)46 void OnDemandLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
47 {
48 NETMGR_EXT_LOG_D("OnLoadSystemAbilityFail: [%{public}d]", systemAbilityId);
49 g_cv.notify_one();
50 }
51
GetRemoteObject() const52 const sptr<IRemoteObject> &OnDemandLoadCallback::GetRemoteObject() const
53 {
54 return remoteObject_;
55 }
56
MDnsClient()57 MDnsClient::MDnsClient() : mdnsService_(nullptr), loadCallback_(nullptr) {}
58
59 MDnsClient::~MDnsClient() = default;
60
RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)61 int32_t MDnsClient::RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)
62 {
63 if (!(IsNameValid(serviceInfo.name) && IsTypeValid(serviceInfo.type) && IsPortValid(serviceInfo.port))) {
64 NETMGR_EXT_LOG_E("RegisterService arguments are not valid");
65 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
66 }
67 if (cb == nullptr) {
68 NETMGR_EXT_LOG_E("callback is null");
69 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
70 }
71
72 sptr<IMDnsService> proxy = GetProxy();
73 if (proxy == nullptr) {
74 NETMGR_EXT_LOG_E("proxy is nullptr");
75 return NETMANAGER_EXT_ERR_LOCAL_PTR_NULL;
76 }
77 int32_t ret = proxy->RegisterService(serviceInfo, cb);
78 if (ret != NETMANAGER_EXT_SUCCESS) {
79 NETMGR_EXT_LOG_E("RegisterService return code: [%{public}d]", ret);
80 } else {
81 MDnsClientResume::GetInstance().SaveRegisterService(serviceInfo, cb);
82 }
83 return ret;
84 }
85
UnRegisterService(const sptr<IRegistrationCallback> &cb)86 int32_t MDnsClient::UnRegisterService(const sptr<IRegistrationCallback> &cb)
87 {
88 if (cb == nullptr) {
89 NETMGR_EXT_LOG_E("callback is null");
90 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
91 }
92
93 sptr<IMDnsService> proxy = GetProxy();
94 if (proxy == nullptr) {
95 NETMGR_EXT_LOG_E("MDnsClient::RemoveLocalService proxy is nullptr");
96 return IPC_PROXY_ERR;
97 }
98 int32_t ret = proxy->UnRegisterService(cb);
99 if (ret != NETMANAGER_EXT_SUCCESS) {
100 NETMGR_EXT_LOG_E("UnRegisterService return code: [%{public}d]", ret);
101 } else {
102 MDnsClientResume::GetInstance().RemoveRegisterService(cb);
103 }
104 return ret;
105 }
106
StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)107 int32_t MDnsClient::StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)
108 {
109 if (!IsTypeValid(serviceType)) {
110 NETMGR_EXT_LOG_E("arguments are not valid, [%{public}s]", serviceType.c_str());
111 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
112 }
113 if (cb == nullptr) {
114 NETMGR_EXT_LOG_E("callback is null");
115 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
116 }
117
118 sptr<IMDnsService> proxy = GetProxy();
119 if (proxy == nullptr) {
120 NETMGR_EXT_LOG_E("MDnsClient::StartDiscoverService proxy is nullptr");
121 return IPC_PROXY_ERR;
122 }
123 int32_t ret = proxy->StartDiscoverService(serviceType, cb);
124 if (ret != NETMANAGER_EXT_SUCCESS) {
125 NETMGR_EXT_LOG_E("StartDiscoverService return code: [%{public}d]", ret);
126 } else {
127 MDnsClientResume::GetInstance().SaveStartDiscoverService(serviceType, cb);
128 }
129 return ret;
130 }
131
StopDiscoverService(const sptr<IDiscoveryCallback> &cb)132 int32_t MDnsClient::StopDiscoverService(const sptr<IDiscoveryCallback> &cb)
133 {
134 if (cb == nullptr) {
135 NETMGR_EXT_LOG_E("callback is null");
136 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
137 }
138
139 sptr<IMDnsService> proxy = GetProxy();
140 if (proxy == nullptr) {
141 NETMGR_EXT_LOG_E("MDnsClient::StopSearchingMDNS proxy is nullptr");
142 return IPC_PROXY_ERR;
143 }
144 int32_t ret = proxy->StopDiscoverService(cb);
145 if (ret != NETMANAGER_EXT_SUCCESS) {
146 NETMGR_EXT_LOG_E("StopDiscoverService return code: [%{public}d]", ret);
147 } else {
148 MDnsClientResume::GetInstance().RemoveStopDiscoverService(cb);
149 }
150 return ret;
151 }
152
ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)153 int32_t MDnsClient::ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)
154 {
155 if (!(IsNameValid(serviceInfo.name) && IsTypeValid(serviceInfo.type))) {
156 NETMGR_EXT_LOG_E("arguments are not valid");
157 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
158 }
159 if (cb == nullptr) {
160 NETMGR_EXT_LOG_E("callback is null");
161 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
162 }
163
164 sptr<IMDnsService> proxy = GetProxy();
165 if (proxy == nullptr) {
166 NETMGR_EXT_LOG_E("MDnsClient::ResolveService proxy is nullptr");
167 return IPC_PROXY_ERR;
168 }
169
170 int32_t ret = proxy->ResolveService(serviceInfo, cb);
171 if (ret != NETMANAGER_EXT_SUCCESS) {
172 NETMGR_EXT_LOG_E("ResolveService return code: [%{public}d]", ret);
173 }
174 return ret;
175 }
176
LoadSaOnDemand()177 sptr<IRemoteObject> MDnsClient::LoadSaOnDemand()
178 {
179 if (loadCallback_->GetRemoteObject() == nullptr) {
180 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
181 if (sam == nullptr) {
182 NETMGR_EXT_LOG_E("GetSystemAbilityManager failed");
183 return nullptr;
184 }
185 int32_t result = sam->LoadSystemAbility(COMM_MDNS_MANAGER_SYS_ABILITY_ID, loadCallback_);
186 if (result != ERR_OK) {
187 NETMGR_EXT_LOG_E("LoadSystemAbility failed : [%{public}d]", result);
188 return nullptr;
189 }
190 std::unique_lock<std::mutex> lk(g_loadMutex);
191 if (!g_cv.wait_for(lk, std::chrono::seconds(LOAD_SA_TIMEOUT),
192 [this]() { return loadCallback_->GetRemoteObject() != nullptr; })) {
193 NETMGR_EXT_LOG_E("LoadSystemAbility timeout");
194 lk.unlock();
195 return nullptr;
196 }
197 lk.unlock();
198 }
199 return loadCallback_->GetRemoteObject();
200 }
201
GetProxy()202 sptr<IMDnsService> MDnsClient::GetProxy()
203 {
204 std::lock_guard lock(mutex_);
205 if (mdnsService_ != nullptr) {
206 NETMGR_EXT_LOG_D("get proxy is ok");
207 return mdnsService_;
208 }
209 loadCallback_ = new (std::nothrow) OnDemandLoadCallback();
210 if (loadCallback_ == nullptr) {
211 NETMGR_EXT_LOG_E("loadCallback_ is nullptr");
212 return nullptr;
213 }
214 sptr<IRemoteObject> remote = LoadSaOnDemand();
215 if (remote == nullptr) {
216 NETMGR_EXT_LOG_E("get Remote service failed");
217 return nullptr;
218 }
219 deathRecipient_ = new (std::nothrow) MDnsDeathRecipient(*this);
220 if (deathRecipient_ == nullptr) {
221 NETMGR_EXT_LOG_E("deathRecipient_ is nullptr");
222 return nullptr;
223 }
224 if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(deathRecipient_))) {
225 NETMGR_EXT_LOG_E("add death recipient failed");
226 return nullptr;
227 }
228 mdnsService_ = iface_cast<IMDnsService>(remote);
229 if (mdnsService_ == nullptr) {
230 NETMGR_EXT_LOG_E("get Remote service proxy failed");
231 return nullptr;
232 }
233 return mdnsService_;
234 }
235
RestartResume()236 void MDnsClient::RestartResume()
237 {
238 NETMGR_EXT_LOG_I("MDnsClient::RestartResume");
239 std::thread t([this]() {
240 MDnsClientResume::GetInstance().ReRegisterService();
241 MDnsClientResume::GetInstance().RestartDiscoverService();
242 });
243 std::string threadName = "mdnsGetProxy";
244 pthread_setname_np(t.native_handle(), threadName.c_str());
245 t.detach();
246 }
247
OnRemoteDied(const wptr<IRemoteObject> &remote)248 void MDnsClient::OnRemoteDied(const wptr<IRemoteObject> &remote)
249 {
250 NETMGR_EXT_LOG_D("on remote died");
251 if (remote == nullptr) {
252 NETMGR_EXT_LOG_E("remote object is nullptr");
253 return;
254 }
255 std::lock_guard lock(mutex_);
256 if (mdnsService_ == nullptr) {
257 NETMGR_EXT_LOG_E("mdnsService_ is nullptr");
258 return;
259 }
260 sptr<IRemoteObject> local = mdnsService_->AsObject();
261 if (local != remote.promote()) {
262 NETMGR_EXT_LOG_E("proxy and stub is not same remote object");
263 return;
264 }
265 local->RemoveDeathRecipient(deathRecipient_);
266 mdnsService_ = nullptr;
267
268 RestartResume();
269 }
270 } // namespace NetManagerStandard
271 } // namespace OHOS