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