• 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_manager.h"
17 
18 #include <unistd.h>
19 
20 #include "mdns_event_proxy.h"
21 #include "netmgr_ext_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace NetManagerStandard {
25 
MDnsManager()26 MDnsManager::MDnsManager()
27 {
28     InitHandler();
29 }
30 
RegisterService(const MDnsServiceInfo & serviceInfo,const sptr<IRegistrationCallback> & cb)31 int32_t MDnsManager::RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)
32 {
33     if (cb == nullptr || cb->AsObject() == nullptr) {
34         NETMGR_EXT_LOG_E("callback is nullptr");
35         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
36     }
37     std::lock_guard<std::mutex> guard(mutex_);
38     if (std::find_if(registerMap_.begin(), registerMap_.end(), [cb](const auto &elem) {
39             return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
40         }) != registerMap_.end()) {
41         return NET_MDNS_ERR_CALLBACK_DUPLICATED;
42     }
43     MDnsProtocolImpl::Result result{.serviceName = serviceInfo.name,
44                                     .serviceType = serviceInfo.type,
45                                     .port = serviceInfo.port,
46                                     .txt = serviceInfo.txtRecord};
47     int32_t err = impl.Register(result);
48     impl.RunTaskLater([this, cb, serviceInfo, err]() {
49         cb->HandleRegisterResult(serviceInfo, err);
50         return true;
51     });
52     if (err == NETMANAGER_EXT_SUCCESS) {
53         registerMap_.emplace_back(cb, serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type);
54     }
55     return err;
56 }
57 
UnRegisterService(const sptr<IRegistrationCallback> & cb)58 int32_t MDnsManager::UnRegisterService(const sptr<IRegistrationCallback> &cb)
59 {
60     if (cb == nullptr || cb->AsObject() == nullptr) {
61         NETMGR_EXT_LOG_E("callback is nullptr");
62         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
63     }
64     std::lock_guard<std::mutex> guard(mutex_);
65     auto local = std::find_if(registerMap_.begin(), registerMap_.end(), [cb](const auto &elem) {
66         return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
67     });
68     if (local == registerMap_.end()) {
69         return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
70     }
71     int32_t err = impl.UnRegister(local->second);
72     if (err == NETMANAGER_EXT_SUCCESS) {
73         registerMap_.erase(local);
74     }
75     return err;
76 }
77 
StartDiscoverService(const std::string & serviceType,const sptr<IDiscoveryCallback> & cb)78 int32_t MDnsManager::StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)
79 {
80     if (cb == nullptr || cb->AsObject() == nullptr) {
81         NETMGR_EXT_LOG_E("callback is nullptr");
82         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
83     }
84     std::lock_guard<std::mutex> guard(mutex_);
85     if (std::find_if(discoveryMap_.begin(), discoveryMap_.end(), [cb](const auto &elem) {
86             return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
87         }) != discoveryMap_.end()) {
88         return NET_MDNS_ERR_CALLBACK_DUPLICATED;
89     }
90     int32_t err = impl.Discovery(serviceType);
91     if (err == NETMANAGER_EXT_SUCCESS) {
92         discoveryMap_.emplace_back(cb, serviceType);
93     }
94     return err;
95 }
96 
StopDiscoverService(const sptr<IDiscoveryCallback> & cb)97 int32_t MDnsManager::StopDiscoverService(const sptr<IDiscoveryCallback> &cb)
98 {
99     if (cb == nullptr || cb->AsObject() == nullptr) {
100         NETMGR_EXT_LOG_E("callback is nullptr");
101         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
102     }
103     std::lock_guard<std::mutex> guard(mutex_);
104     auto local = std::find_if(discoveryMap_.begin(), discoveryMap_.end(), [cb](const auto &elem) {
105         return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
106     });
107     if (local == discoveryMap_.end()) {
108         return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
109     }
110     int32_t err = impl.StopDiscovery(local->second);
111     if (err == NETMANAGER_EXT_SUCCESS) {
112         discoveryMap_.erase(local);
113     }
114     return err;
115 }
116 
ResolveService(const MDnsServiceInfo & serviceInfo,const sptr<IResolveCallback> & cb)117 int32_t MDnsManager::ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)
118 {
119     if (cb == nullptr || cb->AsObject() == nullptr) {
120         NETMGR_EXT_LOG_E("callback is nullptr");
121         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
122     }
123     std::lock_guard<std::mutex> guard(mutex_);
124     if (std::find_if(resolveMap_.begin(), resolveMap_.end(), [cb](const auto &elem) {
125             return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
126         }) != resolveMap_.end()) {
127         return NET_MDNS_ERR_CALLBACK_DUPLICATED;
128     }
129     std::string instance = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type;
130     int32_t err = impl.ResolveInstance(instance);
131     if (err == NETMANAGER_EXT_SUCCESS) {
132         resolveMap_.emplace_back(cb, instance);
133     }
134     cb->HandleResolveResult(serviceInfo, err);
135     return err;
136 }
137 
InitHandler()138 void MDnsManager::InitHandler()
139 {
140     static auto handle = [this](const MDnsProtocolImpl::Result &result, int32_t error) {
141         ReceiveResult(result, error);
142     };
143     impl.SetHandler(handle);
144 }
145 
ReceiveResult(const MDnsProtocolImpl::Result & result,int32_t error)146 void MDnsManager::ReceiveResult(const MDnsProtocolImpl::Result &result, int32_t error)
147 {
148     NETMGR_EXT_LOG_D("ReceiveResult: %{public}d, error: %{public}d", result.type, error);
149     switch (result.type) {
150         case MDnsProtocolImpl::SERVICE_STARTED:
151             [[fallthrough]];
152         case MDnsProtocolImpl::SERVICE_STOPED:
153             return ReceiveRegister(result, error);
154         case MDnsProtocolImpl::SERVICE_FOUND:
155             [[fallthrough]];
156         case MDnsProtocolImpl::SERVICE_LOST:
157             return ReceiveDiscover(result, error);
158         case MDnsProtocolImpl::INSTANCE_RESOLVED:
159             return ReceiveInstanceResolve(result, error);
160         case MDnsProtocolImpl::DOMAIN_RESOLVED:
161             [[fallthrough]];
162         case MDnsProtocolImpl::UNKNOWN:
163             [[fallthrough]];
164         default:
165             return;
166     }
167 }
168 
ReceiveRegister(const MDnsProtocolImpl::Result & result,int32_t error)169 void MDnsManager::ReceiveRegister(const MDnsProtocolImpl::Result &result, int32_t error) {}
170 
ReceiveDiscover(const MDnsProtocolImpl::Result & result,int32_t error)171 void MDnsManager::ReceiveDiscover(const MDnsProtocolImpl::Result &result, int32_t error)
172 {
173     NETMGR_EXT_LOG_D("discoveryMap_ size: [%{public}zu]", discoveryMap_.size());
174     std::lock_guard<std::mutex> guard(mutex_);
175     for (auto iter = discoveryMap_.begin(); iter != discoveryMap_.end(); ++iter) {
176         if (iter->second != result.serviceType) {
177             continue;
178         }
179         auto cb = iter->first;
180         MDnsServiceInfo info;
181         info.name = result.serviceName;
182         info.type = result.serviceType;
183         if (result.type == MDnsProtocolImpl::SERVICE_FOUND) {
184             cb->HandleServiceFound(info, error);
185         }
186         if (result.type == MDnsProtocolImpl::SERVICE_LOST) {
187             cb->HandleServiceLost(info, error);
188         }
189     }
190 }
191 
ReceiveInstanceResolve(const MDnsProtocolImpl::Result & result,int32_t error)192 void MDnsManager::ReceiveInstanceResolve(const MDnsProtocolImpl::Result &result, int32_t error)
193 {
194     NETMGR_EXT_LOG_D("resolveMap_ size: [%{public}zu]", resolveMap_.size());
195     std::lock_guard<std::mutex> guard(mutex_);
196     for (auto iter = resolveMap_.begin(); iter != resolveMap_.end();) {
197         if (iter->second != result.serviceName + MDNS_DOMAIN_SPLITER_STR + result.serviceType) {
198             ++iter;
199             continue;
200         }
201 
202         if (result.addr.empty()|| result.domain.empty()) {
203             ++iter;
204             continue;
205         }
206 
207         auto cb = iter->first;
208         impl.StopResolveInstance(result.serviceName + MDNS_DOMAIN_SPLITER_STR + result.serviceType);
209         cb->HandleResolveResult(ConvertResultToInfo(result), error);
210         iter = resolveMap_.erase(iter);
211     }
212 }
213 
ConvertResultToInfo(const MDnsProtocolImpl::Result & result)214 MDnsServiceInfo MDnsManager::ConvertResultToInfo(const MDnsProtocolImpl::Result &result)
215 {
216     MDnsServiceInfo info;
217     info.name = result.serviceName;
218     info.type = result.serviceType;
219     if (!result.addr.empty()) {
220         info.family = result.ipv6 ? MDnsServiceInfo::IPV6 : MDnsServiceInfo::IPV4;
221     }
222     info.addr = result.addr;
223     info.port = result.port;
224     info.txtRecord = result.txt;
225     return info;
226 }
227 
GetDumpMessage(std::string & message)228 void MDnsManager::GetDumpMessage(std::string &message)
229 {
230     message.append("mDNS Info:\n");
231     const auto &config = impl.GetConfig();
232     message.append("\tIPv6 Support: " + std::to_string(config.ipv6Support) + "\n");
233     message.append("\tAll Iface: " + std::to_string(config.configAllIface) + "\n");
234     message.append("\tTop Domain: " + config.topDomain + "\n");
235     message.append("\tHostname: " + config.hostname + "\n");
236     message.append("\tService Count: " + std::to_string(registerMap_.size()) + "\n");
237 }
238 } // namespace NetManagerStandard
239 } // namespace OHOS