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