18e745fdaSopenharmony_ci/* 28e745fdaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 38e745fdaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48e745fdaSopenharmony_ci * you may not use this file except in compliance with the License. 58e745fdaSopenharmony_ci * You may obtain a copy of the License at 68e745fdaSopenharmony_ci * 78e745fdaSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88e745fdaSopenharmony_ci * 98e745fdaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108e745fdaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118e745fdaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128e745fdaSopenharmony_ci * See the License for the specific language governing permissions and 138e745fdaSopenharmony_ci * limitations under the License. 148e745fdaSopenharmony_ci */ 158e745fdaSopenharmony_ci 168e745fdaSopenharmony_ci#include "mdns_service.h" 178e745fdaSopenharmony_ci#include "net_conn_client.h" 188e745fdaSopenharmony_ci 198e745fdaSopenharmony_ci#include <sys/time.h> 208e745fdaSopenharmony_ci 218e745fdaSopenharmony_ci#include "errorcode_convertor.h" 228e745fdaSopenharmony_ci#include "hisysevent.h" 238e745fdaSopenharmony_ci#include "netmgr_ext_log_wrapper.h" 248e745fdaSopenharmony_ci#include "system_ability_definition.h" 258e745fdaSopenharmony_ci#include "iservice_registry.h" 268e745fdaSopenharmony_ci 278e745fdaSopenharmony_cinamespace OHOS { 288e745fdaSopenharmony_cinamespace NetManagerStandard { 298e745fdaSopenharmony_ci 308e745fdaSopenharmony_cinamespace { 318e745fdaSopenharmony_ciconstexpr const char *NET_MDNS_REQUEST_FAULT = "NET_MDNS_REQUEST_FAULT"; 328e745fdaSopenharmony_ciconstexpr const char *NET_MDNS_REQUEST_BEHAVIOR = "NET_MDNS_REQUEST_BEHAVIOR"; 338e745fdaSopenharmony_ci 348e745fdaSopenharmony_ciconstexpr const char *EVENT_KEY_REQUEST_TYPE = "TYPE"; 358e745fdaSopenharmony_ciconstexpr const char *EVENT_KEY_REQUEST_DATA = "DATA"; 368e745fdaSopenharmony_ciconstexpr const char *EVENT_KEY_ERROR_TYPE = "ERROR_TYPE"; 378e745fdaSopenharmony_ciconstexpr const char *EVENT_KEY_ERROR_MSG = "ERROR_MSG"; 388e745fdaSopenharmony_ci 398e745fdaSopenharmony_ciconstexpr const char *EVENT_DATA_CALLBACK = "callback"; 408e745fdaSopenharmony_ciconstexpr int32_t UNLOAD_IMMEDIATELY = 0; 418e745fdaSopenharmony_ci 428e745fdaSopenharmony_ciusing HiSysEvent = OHOS::HiviewDFX::HiSysEvent; 438e745fdaSopenharmony_ci 448e745fdaSopenharmony_cistruct EventInfo { 458e745fdaSopenharmony_ci int32_t type = 0; 468e745fdaSopenharmony_ci std::string data; 478e745fdaSopenharmony_ci int32_t errorType = 0; 488e745fdaSopenharmony_ci}; 498e745fdaSopenharmony_ci 508e745fdaSopenharmony_civoid SendRequestEvent(const EventInfo &eventInfo) 518e745fdaSopenharmony_ci{ 528e745fdaSopenharmony_ci static NetBaseErrorCodeConvertor convertor; 538e745fdaSopenharmony_ci auto code = eventInfo.errorType; 548e745fdaSopenharmony_ci if (code == NETMANAGER_EXT_SUCCESS) { 558e745fdaSopenharmony_ci HiSysEventWrite(HiSysEvent::Domain::NETMANAGER_STANDARD, NET_MDNS_REQUEST_BEHAVIOR, 568e745fdaSopenharmony_ci HiSysEvent::EventType::BEHAVIOR, EVENT_KEY_REQUEST_TYPE, eventInfo.type, EVENT_KEY_REQUEST_DATA, 578e745fdaSopenharmony_ci eventInfo.data); 588e745fdaSopenharmony_ci } else { 598e745fdaSopenharmony_ci HiSysEventWrite(HiSysEvent::Domain::NETMANAGER_STANDARD, NET_MDNS_REQUEST_FAULT, HiSysEvent::EventType::FAULT, 608e745fdaSopenharmony_ci EVENT_KEY_REQUEST_TYPE, eventInfo.type, EVENT_KEY_REQUEST_DATA, eventInfo.data, 618e745fdaSopenharmony_ci EVENT_KEY_ERROR_TYPE, eventInfo.errorType, EVENT_KEY_ERROR_MSG, 628e745fdaSopenharmony_ci convertor.ConvertErrorCode(code)); 638e745fdaSopenharmony_ci } 648e745fdaSopenharmony_ci} 658e745fdaSopenharmony_ci 668e745fdaSopenharmony_ci} // namespace 678e745fdaSopenharmony_ci 688e745fdaSopenharmony_ciconst bool REGISTER_LOCAL_RESULT_MDNS = 698e745fdaSopenharmony_ci SystemAbility::MakeAndRegisterAbility(DelayedSingleton<MDnsService>::GetInstance().get()); 708e745fdaSopenharmony_ci 718e745fdaSopenharmony_ciMDnsService::MDnsService() 728e745fdaSopenharmony_ci : SystemAbility(COMM_MDNS_MANAGER_SYS_ABILITY_ID, true), isRegistered_(false), state_(STATE_STOPPED) 738e745fdaSopenharmony_ci{ 748e745fdaSopenharmony_ci} 758e745fdaSopenharmony_ci 768e745fdaSopenharmony_ciMDnsService::~MDnsService() 778e745fdaSopenharmony_ci{ 788e745fdaSopenharmony_ci RemoveALLClientDeathRecipient(); 798e745fdaSopenharmony_ci} 808e745fdaSopenharmony_ci 818e745fdaSopenharmony_civoid MDnsService::OnStart() 828e745fdaSopenharmony_ci{ 838e745fdaSopenharmony_ci if (state_ == STATE_RUNNING) { 848e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log MDnsService the state is already running"); 858e745fdaSopenharmony_ci return; 868e745fdaSopenharmony_ci } 878e745fdaSopenharmony_ci if (!Init()) { 888e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log MDnsService init failed"); 898e745fdaSopenharmony_ci return; 908e745fdaSopenharmony_ci } 918e745fdaSopenharmony_ci state_ = STATE_RUNNING; 928e745fdaSopenharmony_ci} 938e745fdaSopenharmony_ci 948e745fdaSopenharmony_ciint32_t MDnsService::OnIdle(const SystemAbilityOnDemandReason &idleReason) 958e745fdaSopenharmony_ci{ 968e745fdaSopenharmony_ci std::lock_guard<std::mutex> autoLock(remoteMutex_); 978e745fdaSopenharmony_ci if (!remoteCallback_.empty()) { 988e745fdaSopenharmony_ci return NETMANAGER_ERROR; 998e745fdaSopenharmony_ci } 1008e745fdaSopenharmony_ci return UNLOAD_IMMEDIATELY; 1018e745fdaSopenharmony_ci} 1028e745fdaSopenharmony_ci 1038e745fdaSopenharmony_civoid MDnsService::OnStop() 1048e745fdaSopenharmony_ci{ 1058e745fdaSopenharmony_ci state_ = STATE_STOPPED; 1068e745fdaSopenharmony_ci isRegistered_ = false; 1078e745fdaSopenharmony_ci} 1088e745fdaSopenharmony_ci 1098e745fdaSopenharmony_cibool MDnsService::Init() 1108e745fdaSopenharmony_ci{ 1118e745fdaSopenharmony_ci if (!REGISTER_LOCAL_RESULT_MDNS) { 1128e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log mDnsService Register to local sa manager failed"); 1138e745fdaSopenharmony_ci return false; 1148e745fdaSopenharmony_ci } 1158e745fdaSopenharmony_ci if (!isRegistered_) { 1168e745fdaSopenharmony_ci if (!Publish(DelayedSingleton<MDnsService>::GetInstance().get())) { 1178e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log mDnsService Register to sa manager failed"); 1188e745fdaSopenharmony_ci return false; 1198e745fdaSopenharmony_ci } 1208e745fdaSopenharmony_ci isRegistered_ = true; 1218e745fdaSopenharmony_ci } 1228e745fdaSopenharmony_ci netStateCallback_ = new (std::nothrow) NetInterfaceStateCallback(); 1238e745fdaSopenharmony_ci int32_t err = NetConnClient::GetInstance().RegisterNetInterfaceCallback(netStateCallback_); 1248e745fdaSopenharmony_ci if (err != NETMANAGER_EXT_SUCCESS) { 1258e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log Failed to register the NetInterfaceCallback, error code: [%{public}d]", err); 1268e745fdaSopenharmony_ci return err; 1278e745fdaSopenharmony_ci } 1288e745fdaSopenharmony_ci 1298e745fdaSopenharmony_ci if (deathRecipient_ == nullptr) { 1308e745fdaSopenharmony_ci deathRecipient_ = new (std::nothrow) MdnsCallbackDeathRecipient(*this); 1318e745fdaSopenharmony_ci } 1328e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Init mdns service OK"); 1338e745fdaSopenharmony_ci return true; 1348e745fdaSopenharmony_ci} 1358e745fdaSopenharmony_ci 1368e745fdaSopenharmony_ciint32_t MDnsService::RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb) 1378e745fdaSopenharmony_ci{ 1388e745fdaSopenharmony_ci int32_t err = MDnsManager::GetInstance().RegisterService(serviceInfo, cb); 1398e745fdaSopenharmony_ci if (err != NETMANAGER_EXT_SUCCESS) { 1408e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err); 1418e745fdaSopenharmony_ci } 1428e745fdaSopenharmony_ci EventInfo eventInfo; 1438e745fdaSopenharmony_ci eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_REGISTER); 1448e745fdaSopenharmony_ci eventInfo.data = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type + MDNS_HOSTPORT_SPLITER_STR + 1458e745fdaSopenharmony_ci std::to_string(serviceInfo.port); 1468e745fdaSopenharmony_ci eventInfo.errorType = err; 1478e745fdaSopenharmony_ci SendRequestEvent(eventInfo); 1488e745fdaSopenharmony_ci return err; 1498e745fdaSopenharmony_ci} 1508e745fdaSopenharmony_ci 1518e745fdaSopenharmony_ciint32_t MDnsService::UnRegisterService(const sptr<IRegistrationCallback> &cb) 1528e745fdaSopenharmony_ci{ 1538e745fdaSopenharmony_ci int32_t err = MDnsManager::GetInstance().UnRegisterService(cb); 1548e745fdaSopenharmony_ci if (err != NETMANAGER_EXT_SUCCESS) { 1558e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err); 1568e745fdaSopenharmony_ci } 1578e745fdaSopenharmony_ci EventInfo eventInfo; 1588e745fdaSopenharmony_ci eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_STOP_REGISTER); 1598e745fdaSopenharmony_ci eventInfo.data = EVENT_DATA_CALLBACK; 1608e745fdaSopenharmony_ci eventInfo.errorType = err; 1618e745fdaSopenharmony_ci SendRequestEvent(eventInfo); 1628e745fdaSopenharmony_ci return err; 1638e745fdaSopenharmony_ci} 1648e745fdaSopenharmony_ci 1658e745fdaSopenharmony_civoid MDnsService::UnloadSystemAbility() 1668e745fdaSopenharmony_ci{ 1678e745fdaSopenharmony_ci auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 1688e745fdaSopenharmony_ci if (systemAbilityMgr == nullptr) { 1698e745fdaSopenharmony_ci return; 1708e745fdaSopenharmony_ci } 1718e745fdaSopenharmony_ci int32_t ret = systemAbilityMgr->UnloadSystemAbility(COMM_MDNS_MANAGER_SYS_ABILITY_ID); 1728e745fdaSopenharmony_ci if (ret != NETMANAGER_EXT_SUCCESS) { 1738e745fdaSopenharmony_ci return; 1748e745fdaSopenharmony_ci } 1758e745fdaSopenharmony_ci} 1768e745fdaSopenharmony_ci 1778e745fdaSopenharmony_civoid MDnsService::OnRemoteDied(const wptr<IRemoteObject> &remoteObject) 1788e745fdaSopenharmony_ci{ 1798e745fdaSopenharmony_ci sptr<IRemoteObject> diedRemoted = remoteObject.promote(); 1808e745fdaSopenharmony_ci if (diedRemoted == nullptr) { 1818e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log diedRemoted is null"); 1828e745fdaSopenharmony_ci return; 1838e745fdaSopenharmony_ci } 1848e745fdaSopenharmony_ci sptr<IDiscoveryCallback> cb = iface_cast<IDiscoveryCallback>(diedRemoted); 1858e745fdaSopenharmony_ci RemoveClientDeathRecipient(cb); 1868e745fdaSopenharmony_ci} 1878e745fdaSopenharmony_ci 1888e745fdaSopenharmony_civoid MDnsService::AddClientDeathRecipient(const sptr<IDiscoveryCallback> &cb) 1898e745fdaSopenharmony_ci{ 1908e745fdaSopenharmony_ci if (deathRecipient_ == nullptr) { 1918e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log deathRecipient is null"); 1928e745fdaSopenharmony_ci return; 1938e745fdaSopenharmony_ci } 1948e745fdaSopenharmony_ci if (!cb->AsObject()->AddDeathRecipient(deathRecipient_)) { 1958e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log AddClientDeathRecipient failed"); 1968e745fdaSopenharmony_ci return; 1978e745fdaSopenharmony_ci } 1988e745fdaSopenharmony_ci std::lock_guard<std::mutex> autoLock(remoteMutex_); 1998e745fdaSopenharmony_ci auto iter = 2008e745fdaSopenharmony_ci std::find_if(remoteCallback_.cbegin(), remoteCallback_.cend(), [&cb](const sptr<IDiscoveryCallback> &item) { 2018e745fdaSopenharmony_ci return item->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr(); 2028e745fdaSopenharmony_ci }); 2038e745fdaSopenharmony_ci if (iter == remoteCallback_.cend()) { 2048e745fdaSopenharmony_ci remoteCallback_.emplace_back(cb); 2058e745fdaSopenharmony_ci } 2068e745fdaSopenharmony_ci} 2078e745fdaSopenharmony_ci 2088e745fdaSopenharmony_civoid MDnsService::RemoveClientDeathRecipient(const sptr<IDiscoveryCallback> &cb) 2098e745fdaSopenharmony_ci{ 2108e745fdaSopenharmony_ci { 2118e745fdaSopenharmony_ci std::lock_guard<std::mutex> autoLock(remoteMutex_); 2128e745fdaSopenharmony_ci auto iter = 2138e745fdaSopenharmony_ci std::find_if(remoteCallback_.cbegin(), remoteCallback_.cend(), [&cb](const sptr<IDiscoveryCallback> &item) { 2148e745fdaSopenharmony_ci return item->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr(); 2158e745fdaSopenharmony_ci }); 2168e745fdaSopenharmony_ci if (iter == remoteCallback_.cend()) { 2178e745fdaSopenharmony_ci return; 2188e745fdaSopenharmony_ci } 2198e745fdaSopenharmony_ci cb->AsObject()->RemoveDeathRecipient(deathRecipient_); 2208e745fdaSopenharmony_ci remoteCallback_.erase(iter); 2218e745fdaSopenharmony_ci if (!remoteCallback_.empty()) { 2228e745fdaSopenharmony_ci return; 2238e745fdaSopenharmony_ci } 2248e745fdaSopenharmony_ci } 2258e745fdaSopenharmony_ci UnloadSystemAbility(); 2268e745fdaSopenharmony_ci} 2278e745fdaSopenharmony_ci 2288e745fdaSopenharmony_civoid MDnsService::RemoveALLClientDeathRecipient() 2298e745fdaSopenharmony_ci{ 2308e745fdaSopenharmony_ci std::lock_guard<std::mutex> autoLock(remoteMutex_); 2318e745fdaSopenharmony_ci for (auto &item : remoteCallback_) { 2328e745fdaSopenharmony_ci item->AsObject()->RemoveDeathRecipient(deathRecipient_); 2338e745fdaSopenharmony_ci } 2348e745fdaSopenharmony_ci remoteCallback_.clear(); 2358e745fdaSopenharmony_ci deathRecipient_ = nullptr; 2368e745fdaSopenharmony_ci} 2378e745fdaSopenharmony_ci 2388e745fdaSopenharmony_ciint32_t MDnsService::StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb) 2398e745fdaSopenharmony_ci{ 2408e745fdaSopenharmony_ci int32_t err = MDnsManager::GetInstance().StartDiscoverService(serviceType, cb); 2418e745fdaSopenharmony_ci if (err != NETMANAGER_EXT_SUCCESS) { 2428e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err); 2438e745fdaSopenharmony_ci } 2448e745fdaSopenharmony_ci EventInfo eventInfo; 2458e745fdaSopenharmony_ci eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_DISCOVER); 2468e745fdaSopenharmony_ci eventInfo.data = serviceType; 2478e745fdaSopenharmony_ci eventInfo.errorType = err; 2488e745fdaSopenharmony_ci SendRequestEvent(eventInfo); 2498e745fdaSopenharmony_ci AddClientDeathRecipient(cb); 2508e745fdaSopenharmony_ci return err; 2518e745fdaSopenharmony_ci} 2528e745fdaSopenharmony_ci 2538e745fdaSopenharmony_ciint32_t MDnsService::StopDiscoverService(const sptr<IDiscoveryCallback> &cb) 2548e745fdaSopenharmony_ci{ 2558e745fdaSopenharmony_ci int32_t err = MDnsManager::GetInstance().StopDiscoverService(cb); 2568e745fdaSopenharmony_ci if (err != NETMANAGER_EXT_SUCCESS) { 2578e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err); 2588e745fdaSopenharmony_ci } 2598e745fdaSopenharmony_ci EventInfo eventInfo; 2608e745fdaSopenharmony_ci eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_STOP_DISCOVER); 2618e745fdaSopenharmony_ci eventInfo.data = EVENT_DATA_CALLBACK; 2628e745fdaSopenharmony_ci eventInfo.errorType = err; 2638e745fdaSopenharmony_ci SendRequestEvent(eventInfo); 2648e745fdaSopenharmony_ci RemoveClientDeathRecipient(cb); 2658e745fdaSopenharmony_ci return err; 2668e745fdaSopenharmony_ci} 2678e745fdaSopenharmony_ci 2688e745fdaSopenharmony_ciint32_t MDnsService::ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb) 2698e745fdaSopenharmony_ci{ 2708e745fdaSopenharmony_ci int32_t err = MDnsManager::GetInstance().ResolveService(serviceInfo, cb); 2718e745fdaSopenharmony_ci if (err != NETMANAGER_EXT_SUCCESS) { 2728e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("mdns_log manager call failed, error code: [%{public}d]", err); 2738e745fdaSopenharmony_ci } 2748e745fdaSopenharmony_ci EventInfo eventInfo; 2758e745fdaSopenharmony_ci eventInfo.type = static_cast<int32_t>(MdnsServiceInterfaceCode::CMD_RESOLVE); 2768e745fdaSopenharmony_ci eventInfo.data = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type; 2778e745fdaSopenharmony_ci eventInfo.errorType = err; 2788e745fdaSopenharmony_ci SendRequestEvent(eventInfo); 2798e745fdaSopenharmony_ci return err; 2808e745fdaSopenharmony_ci} 2818e745fdaSopenharmony_ci 2828e745fdaSopenharmony_ciint32_t MDnsService::Dump(int32_t fd, const std::vector<std::u16string> &args) 2838e745fdaSopenharmony_ci{ 2848e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Start Dump, fd: %{public}d", fd); 2858e745fdaSopenharmony_ci std::string result; 2868e745fdaSopenharmony_ci MDnsManager::GetInstance().GetDumpMessage(result); 2878e745fdaSopenharmony_ci int32_t ret = dprintf(fd, "%s\n", result.c_str()); 2888e745fdaSopenharmony_ci return ret < 0 ? NET_MDNS_ERR_WRITE_DUMP : NETMANAGER_EXT_SUCCESS; 2898e745fdaSopenharmony_ci} 2908e745fdaSopenharmony_ci 2918e745fdaSopenharmony_ci} // namespace NetManagerStandard 2928e745fdaSopenharmony_ci} // namespace OHOS