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