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 "discovery_callback_proxy.h"
21 #include "registration_callback_proxy.h"
22 #include "resolve_callback_proxy.h"
23 #include "netmgr_ext_log_wrapper.h"
24
25 namespace OHOS {
26 namespace NetManagerStandard {
27
GetInstance()28 MDnsManager &MDnsManager::GetInstance()
29 {
30 static MDnsManager sInstance;
31 return sInstance;
32 }
33
MDnsManager()34 MDnsManager::MDnsManager() {}
35
RestartMDnsProtocolImpl()36 void MDnsManager::RestartMDnsProtocolImpl()
37 {
38 NETMGR_EXT_LOG_D("mdns_log Network switching");
39 impl.Init();
40 RestartDiscoverService();
41 }
42
IsSupportIpV6()43 bool MDnsManager::IsSupportIpV6()
44 {
45 return impl.GetConfig().ipv6Support;
46 }
47
RegisterService(const MDnsServiceInfo & serviceInfo,const sptr<IRegistrationCallback> & cb)48 int32_t MDnsManager::RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)
49 {
50 NETMGR_EXT_LOG_D("mdns_log RegisterService");
51 if (cb == nullptr || cb->AsObject() == nullptr) {
52 NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
53 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
54 }
55
56 MDnsProtocolImpl::Result result{.serviceName = serviceInfo.name,
57 .serviceType = serviceInfo.type,
58 .port = serviceInfo.port,
59 .txt = serviceInfo.txtRecord};
60
61 int32_t err = impl.Register(result);
62 impl.AddTask([this, cb, serviceInfo, err]() {
63 cb->HandleRegisterResult(serviceInfo, err);
64 return true;
65 });
66
67 if (err == NETMANAGER_EXT_SUCCESS) {
68 std::lock_guard<std::recursive_mutex> guard(registerMutex_);
69 registerMap_.emplace(cb, serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type);
70 }
71 return err;
72 }
73
UnRegisterService(const sptr<IRegistrationCallback> & cb)74 int32_t MDnsManager::UnRegisterService(const sptr<IRegistrationCallback> &cb)
75 {
76 NETMGR_EXT_LOG_D("mdns_log UnRegisterService");
77 if (cb == nullptr || cb->AsObject() == nullptr) {
78 NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
79 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
80 }
81
82 std::lock_guard<std::recursive_mutex> guard(registerMutex_);
83 auto itr = registerMap_.find(cb);
84 if (registerMap_.end() == itr) {
85 NETMGR_EXT_LOG_W("mdns_log find registrer map failed");
86 return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
87 }
88
89 int32_t err = impl.UnRegister(itr->second);
90 if (err == NETMANAGER_EXT_SUCCESS) {
91 registerMap_.erase(itr);
92 }
93 return err;
94 }
95
StartDiscoverService(const std::string & serviceType,const sptr<IDiscoveryCallback> & cb)96 int32_t MDnsManager::StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)
97 {
98 NETMGR_EXT_LOG_D("mdns_log StartDiscoverService");
99 if (cb == nullptr || cb->AsObject() == nullptr) {
100 NETMGR_EXT_LOG_E("callback is nullptr");
101 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
102 }
103
104 if (!IsTypeValid(serviceType)) {
105 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
106 }
107 std::string name = impl.Decorated(serviceType);
108 if (!IsDomainValid(name)) {
109 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
110 }
111
112 {
113 std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
114 if (discoveryMap_.find(cb) != discoveryMap_.end()) {
115 return NET_MDNS_ERR_CALLBACK_DUPLICATED;
116 }
117 discoveryMap_.emplace(cb, serviceType);
118 }
119 return impl.Discovery(serviceType, cb);
120 }
121
StopDiscoverService(const sptr<IDiscoveryCallback> & cb)122 int32_t MDnsManager::StopDiscoverService(const sptr<IDiscoveryCallback> &cb)
123 {
124 NETMGR_EXT_LOG_D("mdns_log StopDiscoverService");
125 if (cb == nullptr || cb->AsObject() == nullptr) {
126 NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
127 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
128 }
129 std::string key;
130 {
131 std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
132 auto local = discoveryMap_.find(cb);
133 if (local == discoveryMap_.end()) {
134 return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
135 }
136 key = local->second;
137 discoveryMap_.erase(local);
138 }
139 return impl.StopCbMap(key);
140 }
141
RestartDiscoverService()142 void MDnsManager::RestartDiscoverService()
143 {
144 NETMGR_EXT_LOG_D("mdns_log RestartDiscoverService");
145 std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
146 for (const auto &it : discoveryMap_) {
147 auto cb = it.first;
148 if (cb == nullptr || cb->AsObject() == nullptr) {
149 NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
150 continue;
151 }
152 auto serviceType = it.second;
153 impl.StopCbMap(serviceType);
154 impl.Discovery(serviceType, cb);
155 }
156 }
157
ResolveService(const MDnsServiceInfo & serviceInfo,const sptr<IResolveCallback> & cb)158 int32_t MDnsManager::ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)
159 {
160 NETMGR_EXT_LOG_D("mdns_log ResolveService");
161 if (cb == nullptr || cb->AsObject() == nullptr) {
162 NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
163 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
164 }
165
166 std::string instance = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type;
167 return impl.ResolveInstance(instance, cb);
168 }
169
GetDumpMessage(std::string & message)170 void MDnsManager::GetDumpMessage(std::string &message)
171 {
172 message.append("mDNS Info:\n");
173 const auto &config = impl.GetConfig();
174 message.append("\tIPv6 Support: " + std::to_string(config.ipv6Support) + "\n");
175 message.append("\tAll Iface: " + std::to_string(config.configAllIface) + "\n");
176 message.append("\tTop Domain: " + config.topDomain + "\n");
177 message.append("\tHostname: " + config.hostname + "\n");
178 message.append("\tImpl Service Count: " + std::to_string(impl.srvMap_.size()) + "\n");
179 message.append("\tDiscovery Count: " + std::to_string(discoveryMap_.size()) + "\n");
180 }
181
IsAvailableCallback(const sptr<IDiscoveryCallback> & cb)182 bool MDnsManager::IsAvailableCallback(const sptr<IDiscoveryCallback> &cb)
183 {
184 std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
185 return cb != nullptr && discoveryMap_.find(cb) != discoveryMap_.end();
186 }
187 } // namespace NetManagerStandard
188 } // namespace OHOS