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