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_service.h"
17 #include "net_conn_client.h"
18
19 #include <sys/time.h>
20
21 #include "errorcode_convertor.h"
22 #include "hisysevent.h"
23 #include "netmgr_ext_log_wrapper.h"
24 #include "system_ability_definition.h"
25 #include "iservice_registry.h"
26
27 namespace OHOS {
28 namespace NetManagerStandard {
29
30 namespace {
31 constexpr const char *NET_MDNS_REQUEST_FAULT = "NET_MDNS_REQUEST_FAULT";
32 constexpr const char *NET_MDNS_REQUEST_BEHAVIOR = "NET_MDNS_REQUEST_BEHAVIOR";
33
34 constexpr const char *EVENT_KEY_REQUEST_TYPE = "TYPE";
35 constexpr const char *EVENT_KEY_REQUEST_DATA = "DATA";
36 constexpr const char *EVENT_KEY_ERROR_TYPE = "ERROR_TYPE";
37 constexpr const char *EVENT_KEY_ERROR_MSG = "ERROR_MSG";
38
39 constexpr const char *EVENT_DATA_CALLBACK = "callback";
40 constexpr int32_t UNLOAD_IMMEDIATELY = 0;
41
42 using HiSysEvent = OHOS::HiviewDFX::HiSysEvent;
43
44 struct EventInfo {
45 int32_t type = 0;
46 std::string data;
47 int32_t errorType = 0;
48 };
49
SendRequestEvent(const EventInfo & eventInfo)50 void SendRequestEvent(const EventInfo &eventInfo)
51 {
52 static NetBaseErrorCodeConvertor convertor;
53 auto code = eventInfo.errorType;
54 if (code == NETMANAGER_EXT_SUCCESS) {
55 HiSysEventWrite(HiSysEvent::Domain::NETMANAGER_STANDARD, NET_MDNS_REQUEST_BEHAVIOR,
56 HiSysEvent::EventType::BEHAVIOR, EVENT_KEY_REQUEST_TYPE, eventInfo.type, EVENT_KEY_REQUEST_DATA,
57 eventInfo.data);
58 } else {
59 HiSysEventWrite(HiSysEvent::Domain::NETMANAGER_STANDARD, NET_MDNS_REQUEST_FAULT, HiSysEvent::EventType::FAULT,
60 EVENT_KEY_REQUEST_TYPE, eventInfo.type, EVENT_KEY_REQUEST_DATA, eventInfo.data,
61 EVENT_KEY_ERROR_TYPE, eventInfo.errorType, EVENT_KEY_ERROR_MSG,
62 convertor.ConvertErrorCode(code));
63 }
64 }
65
66 } // namespace
67
68 const bool REGISTER_LOCAL_RESULT_MDNS =
69 SystemAbility::MakeAndRegisterAbility(DelayedSingleton<MDnsService>::GetInstance().get());
70
MDnsService()71 MDnsService::MDnsService()
72 : SystemAbility(COMM_MDNS_MANAGER_SYS_ABILITY_ID, true), isRegistered_(false), state_(STATE_STOPPED)
73 {
74 }
75
~MDnsService()76 MDnsService::~MDnsService()
77 {
78 RemoveALLClientDeathRecipient();
79 }
80
OnStart()81 void MDnsService::OnStart()
82 {
83 if (state_ == STATE_RUNNING) {
84 NETMGR_EXT_LOG_D("mdns_log MDnsService the state is already running");
85 return;
86 }
87 if (!Init()) {
88 NETMGR_EXT_LOG_E("mdns_log MDnsService init failed");
89 return;
90 }
91 state_ = STATE_RUNNING;
92 }
93
OnIdle(const SystemAbilityOnDemandReason & idleReason)94 int32_t MDnsService::OnIdle(const SystemAbilityOnDemandReason &idleReason)
95 {
96 std::lock_guard<std::mutex> autoLock(remoteMutex_);
97 if (!remoteCallback_.empty()) {
98 return NETMANAGER_ERROR;
99 }
100 return UNLOAD_IMMEDIATELY;
101 }
102
OnStop()103 void MDnsService::OnStop()
104 {
105 state_ = STATE_STOPPED;
106 isRegistered_ = false;
107 }
108
Init()109 bool MDnsService::Init()
110 {
111 if (!REGISTER_LOCAL_RESULT_MDNS) {
112 NETMGR_EXT_LOG_E("mdns_log mDnsService Register to local sa manager failed");
113 return false;
114 }
115 if (!isRegistered_) {
116 if (!Publish(DelayedSingleton<MDnsService>::GetInstance().get())) {
117 NETMGR_EXT_LOG_E("mdns_log mDnsService Register to sa manager failed");
118 return false;
119 }
120 isRegistered_ = true;
121 }
122 netStateCallback_ = new (std::nothrow) NetInterfaceStateCallback();
123 int32_t err = NetConnClient::GetInstance().RegisterNetInterfaceCallback(netStateCallback_);
124 if (err != NETMANAGER_EXT_SUCCESS) {
125 NETMGR_EXT_LOG_E("mdns_log Failed to register the NetInterfaceCallback, error code: [%{public}d]", err);
126 return err;
127 }
128
129 if (deathRecipient_ == nullptr) {
130 deathRecipient_ = new (std::nothrow) MdnsCallbackDeathRecipient(*this);
131 }
132 NETMGR_EXT_LOG_D("mdns_log Init mdns service OK");
133 return true;
134 }
135
RegisterService(const MDnsServiceInfo & serviceInfo,const sptr<IRegistrationCallback> & cb)136 int32_t MDnsService::RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)
137 {
138 int32_t err = MDnsManager::GetInstance().RegisterService(serviceInfo, cb);
139 if (err != NETMANAGER_EXT_SUCCESS) {
140 NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err);
141 }
142 EventInfo eventInfo;
143 eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_REGISTER);
144 eventInfo.data = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type + MDNS_HOSTPORT_SPLITER_STR +
145 std::to_string(serviceInfo.port);
146 eventInfo.errorType = err;
147 SendRequestEvent(eventInfo);
148 return err;
149 }
150
UnRegisterService(const sptr<IRegistrationCallback> & cb)151 int32_t MDnsService::UnRegisterService(const sptr<IRegistrationCallback> &cb)
152 {
153 int32_t err = MDnsManager::GetInstance().UnRegisterService(cb);
154 if (err != NETMANAGER_EXT_SUCCESS) {
155 NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err);
156 }
157 EventInfo eventInfo;
158 eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_STOP_REGISTER);
159 eventInfo.data = EVENT_DATA_CALLBACK;
160 eventInfo.errorType = err;
161 SendRequestEvent(eventInfo);
162 return err;
163 }
164
UnloadSystemAbility()165 void MDnsService::UnloadSystemAbility()
166 {
167 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
168 if (systemAbilityMgr == nullptr) {
169 return;
170 }
171 int32_t ret = systemAbilityMgr->UnloadSystemAbility(COMM_MDNS_MANAGER_SYS_ABILITY_ID);
172 if (ret != NETMANAGER_EXT_SUCCESS) {
173 return;
174 }
175 }
176
OnRemoteDied(const wptr<IRemoteObject> & remoteObject)177 void MDnsService::OnRemoteDied(const wptr<IRemoteObject> &remoteObject)
178 {
179 sptr<IRemoteObject> diedRemoted = remoteObject.promote();
180 if (diedRemoted == nullptr) {
181 NETMGR_EXT_LOG_E("mdns_log diedRemoted is null");
182 return;
183 }
184 sptr<IDiscoveryCallback> cb = iface_cast<IDiscoveryCallback>(diedRemoted);
185 RemoveClientDeathRecipient(cb);
186 }
187
AddClientDeathRecipient(const sptr<IDiscoveryCallback> & cb)188 void MDnsService::AddClientDeathRecipient(const sptr<IDiscoveryCallback> &cb)
189 {
190 if (deathRecipient_ == nullptr) {
191 NETMGR_EXT_LOG_E("mdns_log deathRecipient is null");
192 return;
193 }
194 if (!cb->AsObject()->AddDeathRecipient(deathRecipient_)) {
195 NETMGR_EXT_LOG_E("mdns_log AddClientDeathRecipient failed");
196 return;
197 }
198 std::lock_guard<std::mutex> autoLock(remoteMutex_);
199 auto iter =
200 std::find_if(remoteCallback_.cbegin(), remoteCallback_.cend(), [&cb](const sptr<IDiscoveryCallback> &item) {
201 return item->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
202 });
203 if (iter == remoteCallback_.cend()) {
204 remoteCallback_.emplace_back(cb);
205 }
206 }
207
RemoveClientDeathRecipient(const sptr<IDiscoveryCallback> & cb)208 void MDnsService::RemoveClientDeathRecipient(const sptr<IDiscoveryCallback> &cb)
209 {
210 {
211 std::lock_guard<std::mutex> autoLock(remoteMutex_);
212 auto iter =
213 std::find_if(remoteCallback_.cbegin(), remoteCallback_.cend(), [&cb](const sptr<IDiscoveryCallback> &item) {
214 return item->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
215 });
216 if (iter == remoteCallback_.cend()) {
217 return;
218 }
219 cb->AsObject()->RemoveDeathRecipient(deathRecipient_);
220 remoteCallback_.erase(iter);
221 if (!remoteCallback_.empty()) {
222 return;
223 }
224 }
225 UnloadSystemAbility();
226 }
227
RemoveALLClientDeathRecipient()228 void MDnsService::RemoveALLClientDeathRecipient()
229 {
230 std::lock_guard<std::mutex> autoLock(remoteMutex_);
231 for (auto &item : remoteCallback_) {
232 item->AsObject()->RemoveDeathRecipient(deathRecipient_);
233 }
234 remoteCallback_.clear();
235 deathRecipient_ = nullptr;
236 }
237
StartDiscoverService(const std::string & serviceType,const sptr<IDiscoveryCallback> & cb)238 int32_t MDnsService::StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)
239 {
240 int32_t err = MDnsManager::GetInstance().StartDiscoverService(serviceType, cb);
241 if (err != NETMANAGER_EXT_SUCCESS) {
242 NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err);
243 }
244 EventInfo eventInfo;
245 eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_DISCOVER);
246 eventInfo.data = serviceType;
247 eventInfo.errorType = err;
248 SendRequestEvent(eventInfo);
249 AddClientDeathRecipient(cb);
250 return err;
251 }
252
StopDiscoverService(const sptr<IDiscoveryCallback> & cb)253 int32_t MDnsService::StopDiscoverService(const sptr<IDiscoveryCallback> &cb)
254 {
255 int32_t err = MDnsManager::GetInstance().StopDiscoverService(cb);
256 if (err != NETMANAGER_EXT_SUCCESS) {
257 NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err);
258 }
259 EventInfo eventInfo;
260 eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_STOP_DISCOVER);
261 eventInfo.data = EVENT_DATA_CALLBACK;
262 eventInfo.errorType = err;
263 SendRequestEvent(eventInfo);
264 RemoveClientDeathRecipient(cb);
265 return err;
266 }
267
ResolveService(const MDnsServiceInfo & serviceInfo,const sptr<IResolveCallback> & cb)268 int32_t MDnsService::ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)
269 {
270 int32_t err = MDnsManager::GetInstance().ResolveService(serviceInfo, cb);
271 if (err != NETMANAGER_EXT_SUCCESS) {
272 NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err);
273 }
274 EventInfo eventInfo;
275 eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_RESOLVE);
276 eventInfo.data = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type;
277 eventInfo.errorType = err;
278 SendRequestEvent(eventInfo);
279 return err;
280 }
281
Dump(int32_t fd,const std::vector<std::u16string> & args)282 int32_t MDnsService::Dump(int32_t fd, const std::vector<std::u16string> &args)
283 {
284 NETMGR_EXT_LOG_D("mdns_log Start Dump, fd: %{public}d", fd);
285 std::string result;
286 MDnsManager::GetInstance().GetDumpMessage(result);
287 int32_t ret = dprintf(fd, "%s\n", result.c_str());
288 return ret < 0 ? NET_MDNS_ERR_WRITE_DUMP : NETMANAGER_EXT_SUCCESS;
289 }
290
291 } // namespace NetManagerStandard
292 } // namespace OHOS