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