* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdint>
#include <string_view>
#include "module_template.h"
#include "napi/native_api.h"
#include "napi/native_common.h"
#include "napi_utils.h"
#include "netmanager_ext_log.h"
#include "constant.h"
#include "mdns_addlocalservice_context.h"
#include "mdns_async_work.h"
#include "mdns_instances.h"
#include "mdns_module.h"
#include "mdns_removelocalservice_context.h"
#include "mdns_resolvelocalservice_context.h"
#include "mdns_startsearching_context.h"
namespace OHOS {
namespace NetManagerStandard {
constexpr const char *MDNS_MODULE_NAME = "net.mdns";
static std::string GetContextIdString(napi_env env, napi_value obj)
{
if (NapiUtils::HasNamedProperty(env, obj, CONTEXT_ATTR_APPINFO)) {
napi_value info = NapiUtils::GetNamedProperty(env, obj, CONTEXT_ATTR_APPINFO);
if (NapiUtils::HasNamedProperty(env, info, APPINFO_ATTR_NAME)) {
return NapiUtils::GetStringPropertyUtf8(env, info, APPINFO_ATTR_NAME);
}
}
return std::string();
}
static void *ParseMDnsDiscoveryParams(napi_env env, size_t argc, napi_value *argv,
std::shared_ptr<EventManager>& manager)
{
std::unique_ptr<MDnsDiscoveryInstance, decltype(&MDnsDiscoveryInstance::DeleteMDnsDiscovery)> mdnsDiscover(
MDnsDiscoveryInstance::MakeMDnsDiscovery(manager), MDnsDiscoveryInstance::DeleteMDnsDiscovery);
if (!mdnsDiscover) {
NETMANAGER_EXT_LOGE("mdnsDiscover failed!");
return nullptr;
}
if (NapiUtils::GetValueType(env, argv[ARG_NUM_0]) == napi_object &&
NapiUtils::GetValueType(env, argv[ARG_NUM_1]) == napi_string) {
mdnsDiscover->context_ = GetContextIdString(env, argv[ARG_NUM_0]);
mdnsDiscover->serviceType_ = NapiUtils::GetStringFromValueUtf8(env, argv[ARG_NUM_1]);
return mdnsDiscover.release();
}
NETMANAGER_EXT_LOGE("constructor params invalid, should be context + serviceType");
return nullptr;
}
napi_value MDnsModule::CreateDiscoveryService(napi_env env, napi_callback_info info)
{
return ModuleTemplate::NewInstance(env, info, FUNCTION_DISCOVERY_SERVICE, ParseMDnsDiscoveryParams,
[](napi_env, void *data, void *) {
NETMANAGER_BASE_LOGI("finalize DiscoveryService");
auto sharedManager = static_cast<std::shared_ptr<EventManager> *>(data);
if (sharedManager == nullptr || *sharedManager == nullptr) {
return;
}
auto manager = *sharedManager;
auto mdnsDiscover = static_cast<MDnsDiscoveryInstance *>(manager->GetData());
delete sharedManager;
MDnsDiscoveryInstance::DeleteMDnsDiscovery(mdnsDiscover);
});
}
napi_value MDnsModule::AddLocalService(napi_env env, napi_callback_info info)
{
return ModuleTemplate::Interface<MDnsAddLocalServiceContext>(env, info, FUNCTION_ADDLOCALSERVICE, nullptr,
MDnsAsyncWork::ExecAddLocalService,
MDnsAsyncWork::AddLocalServiceCallback);
}
napi_value MDnsModule::RemoveLocalService(napi_env env, napi_callback_info info)
{
return ModuleTemplate::Interface<MDnsRemoveLocalServiceContext>(env, info, FUNCTION_REMOVELOCALSERVICE, nullptr,
MDnsAsyncWork::ExecRemoveLocalService,
MDnsAsyncWork::RemoveLocalServiceCallback);
}
napi_value MDnsModule::ResolveLocalService(napi_env env, napi_callback_info info)
{
return ModuleTemplate::Interface<MDnsResolveLocalServiceContext>(env, info, FUNCTION_RESOLVELOCALSERVICE, nullptr,
MDnsAsyncWork::ExecResolveLocalService,
MDnsAsyncWork::ResolveLocalServiceCallback);
}
napi_value MDnsModule::DiscoveryServiceInterface::On(napi_env env, napi_callback_info info)
{
std::initializer_list<std::string> events = {EVENT_SERVICESTART, EVENT_SERVICESTOP, EVENT_SERVICEFOUND,
EVENT_SERVICELOST};
return ModuleTemplate::On(env, info, events, false);
}
napi_value MDnsModule::DiscoveryServiceInterface::Off(napi_env env, napi_callback_info info)
{
std::initializer_list<std::string> events = {EVENT_SERVICESTART, EVENT_SERVICESTOP, EVENT_SERVICEFOUND,
EVENT_SERVICELOST};
return ModuleTemplate::Off(env, info, events);
}
napi_value MDnsModule::DiscoveryServiceInterface::StartSearchingMDNS(napi_env env, napi_callback_info info)
{
return ModuleTemplate::Interface<MDnsStartSearchingContext>(
env, info, FUNCTION_STARTSEARCHINGMDNS, nullptr,
MDnsAsyncWork::MDnsDiscoverInterfaceAsyncWork::ExecStartSearchingMDNS,
MDnsAsyncWork::MDnsDiscoverInterfaceAsyncWork::StartSearchingMDNSCallback);
}
napi_value MDnsModule::DiscoveryServiceInterface::StopSearchingMDNS(napi_env env, napi_callback_info info)
{
return ModuleTemplate::Interface<MDnsStopSearchingContext>(
env, info, FUNCTION_STOPSEARCHINGMDNS, nullptr,
MDnsAsyncWork::MDnsDiscoverInterfaceAsyncWork::ExecStopSearchingMDNS,
MDnsAsyncWork::MDnsDiscoverInterfaceAsyncWork::StopSearchingMDNSCallback);
}
napi_value MDnsModule::InitMDnsModule(napi_env env, napi_value exports)
{
std::initializer_list<napi_property_descriptor> functions = {
DECLARE_NAPI_FUNCTION(FUNCTION_CREATE_DISCOVERY, CreateDiscoveryService),
DECLARE_NAPI_FUNCTION(FUNCTION_ADDLOCALSERVICE, AddLocalService),
DECLARE_NAPI_FUNCTION(FUNCTION_REMOVELOCALSERVICE, RemoveLocalService),
DECLARE_NAPI_FUNCTION(FUNCTION_RESOLVELOCALSERVICE, ResolveLocalService)};
NapiUtils::DefineProperties(env, exports, functions);
std::initializer_list<napi_property_descriptor> MDnsDiscoveryFunctions = {
DECLARE_NAPI_FUNCTION(DiscoveryServiceInterface::FUNCTION_ON, DiscoveryServiceInterface::On),
DECLARE_NAPI_FUNCTION(DiscoveryServiceInterface::FUNCTION_OFF, DiscoveryServiceInterface::Off),
DECLARE_NAPI_FUNCTION(DiscoveryServiceInterface::FUNCTION_STARTSEARCHINGMDNS,
DiscoveryServiceInterface::StartSearchingMDNS),
DECLARE_NAPI_FUNCTION(DiscoveryServiceInterface::FUNCTION_STOPSEARCHINGMDNS,
DiscoveryServiceInterface::StopSearchingMDNS),
};
ModuleTemplate::DefineClass(env, exports, MDnsDiscoveryFunctions, FUNCTION_DISCOVERY_SERVICE);
std::initializer_list<napi_property_descriptor> mdnsError = {
DECLARE_NAPI_STATIC_PROPERTY(INTERNAL_ERROR_NAME,
NapiUtils::CreateUint32(env, static_cast<uint32_t>(MDnsErr::INTERNAL_ERROR))),
DECLARE_NAPI_STATIC_PROPERTY(ALREADY_ACTIVE_NAME,
NapiUtils::CreateUint32(env, static_cast<uint32_t>(MDnsErr::ALREADY_ACTIVE))),
DECLARE_NAPI_STATIC_PROPERTY(MAX_LIMIT_NAME,
NapiUtils::CreateUint32(env, static_cast<uint32_t>(MDnsErr::MAX_LIMIT))),
};
napi_value mdnsErrorValue = NapiUtils::CreateObject(env);
NapiUtils::DefineProperties(env, mdnsErrorValue, mdnsError);
NapiUtils::SetNamedProperty(env, exports, MDNS_ERR, mdnsErrorValue);
NapiUtils::SetEnvValid(env);
napi_add_env_cleanup_hook(env, NapiUtils::HookForEnvCleanup, env);
return exports;
}
static napi_module g_mdnsModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = MDnsModule::InitMDnsModule,
.nm_modname = MDNS_MODULE_NAME,
.nm_priv = nullptr,
.reserved = {nullptr},
};
extern "C" __attribute__((constructor)) void RegisterMDnsModule(void)
{
napi_module_register(&g_mdnsModule);
}
}
}