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