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