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