* Copyright (C) 2024 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 "napi_util.h"
#include "securec.h"
#include "string_ex.h"
#include "common_utils.h"
#include "location_log.h"
#include "beacon_fence_napi.h"
namespace OHOS {
namespace Location {
static constexpr int MAX_BUF_LEN = 100;
bool ParseBeaconFenceRequest(
const napi_env& env, const napi_value& value, std::shared_ptr<BeaconFenceRequest>& request)
{
if (env == nullptr || value == nullptr || request == nullptr) {
LBSLOGE(NAPI_UTILS, "parseBeaconFenceRequest param is nullptr");
return false;
}
napi_valuetype valueType;
NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
if (valueType != napi_object) {
LBSLOGE(NAPI_UTILS, "Wrong argument type, value should be object");
return false;
}
return GenBeaconFenceRequest(env, value, request);
}
bool GenBeaconFenceRequest(
const napi_env& env, const napi_value& value, std::shared_ptr<BeaconFenceRequest>& beaconFenceRequest)
{
if (env == nullptr || value == nullptr || beaconFenceRequest == nullptr) {
LBSLOGE(NAPI_UTILS, "genBeaconFenceRequest param is nullptr");
return false;
}
napi_value beaconValue = GetNapiValueByKey(env, "beacon", value);
if (beaconValue == nullptr) {
LBSLOGE(LOCATOR_STANDARD, "parse beacon failed");
return false;
}
std::shared_ptr<BeaconFence> beaconFence = std::make_shared<BeaconFence>();
bool isValidParameter = JsObjToBeaconFence(env, beaconValue, beaconFence);
if (!isValidParameter) {
return false;
}
beaconFenceRequest->SetBeaconFence(beaconFence);
std::string fenceExtensionAbilityName = "";
int fenceExtensionAbilityNameRes =
JsObjectToString(env, value, "fenceExtensionAbilityName", MAX_BUF_LEN, fenceExtensionAbilityName);
if (fenceExtensionAbilityNameRes == SUCCESS) {
beaconFenceRequest->SetFenceExtensionAbilityName(fenceExtensionAbilityName);
}
napi_value callbackNapiValue = nullptr;
NAPI_CALL_BASE(env,
napi_get_named_property(env, value, "transitionCallback", &callbackNapiValue), false);
napi_valuetype napiValueType = napi_undefined;
if (callbackNapiValue != nullptr) {
NAPI_CALL_BASE(env, napi_typeof(env, callbackNapiValue, &napiValueType), false);
}
if (napiValueType == napi_undefined && fenceExtensionAbilityNameRes != SUCCESS) {
LBSLOGE(NAPI_UTILS, "%{public}s, parse transitionCallback and fenceExtensionAbilityName failed", __func__);
return false;
}
return true;
}
void JsObjToBeaconFenceTransitionCallback(const napi_env& env, const napi_value& object,
sptr<LocationGnssGeofenceCallbackNapi> callbackHost)
{
if (env == nullptr || object == nullptr || callbackHost == nullptr) {
return;
}
napi_ref handlerRef = nullptr;
napi_value callbackNapiValue = nullptr;
NAPI_CALL_RETURN_VOID(env,
napi_get_named_property(env, object, "transitionCallback", &callbackNapiValue));
if (callbackNapiValue != nullptr) {
NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, callbackNapiValue, 1, &handlerRef));
}
callbackHost->SetEnv(env);
callbackHost->SetHandleCb(handlerRef);
}
bool JsObjToBeaconFence(const napi_env& env, const napi_value& object,
const std::shared_ptr<BeaconFence>& beaconFence)
{
if (env == nullptr || object == nullptr || beaconFence == nullptr) {
return false;
}
if (JsObjectToString(env, object, "identifier", MAX_BUF_LEN, beaconFence->identifier_) != SUCCESS) {
LBSLOGE(LOCATOR_STANDARD, "parse identifier failed");
return false;
}
int value = 0;
if (JsObjectToInt(env, object, "beaconFenceInfoType", value) == SUCCESS) {
beaconFence->SetBeaconFenceInfoType(static_cast<BeaconFenceInfoType>(value));
} else {
LBSLOGE(LOCATOR_STANDARD, "parse beaconFenceInfoType failed");
return false;
}
if (!GenBeaconManufactureDataRequest(env, object, beaconFence)) {
LBSLOGE(LOCATOR_STANDARD, "parse ManufactureData failed");
return false;
}
return true;
}
bool GenBeaconManufactureDataRequest(
const napi_env& env, const napi_value& object, std::shared_ptr<BeaconFence> beaconFence)
{
if (env == nullptr || object == nullptr || beaconFence == nullptr) {
return false;
}
napi_value manufactureDataValue = GetNapiValueByKey(env, "manufactureData", object);
if (manufactureDataValue == nullptr) {
LBSLOGE(LOCATOR_STANDARD, "parse manufactureDataValue failed");
return false;
}
BeaconManufactureData beaconManufactureData = {0};
if (JsObjectToInt(env, manufactureDataValue, "manufactureId", beaconManufactureData.manufactureId) != SUCCESS) {
LBSLOGE(LOCATOR_STANDARD, "parse manufactureId failed");
return false;
}
std::vector<uint8_t> manufactureDataVector {};
if (!ParseArrayBufferParams(env, manufactureDataValue, "manufactureData", manufactureDataVector)) {
LBSLOGE(LOCATOR_STANDARD, "parse manufactureData failed");
return false;
}
beaconManufactureData.manufactureData = std::move(manufactureDataVector);
std::vector<uint8_t> manufactureDataMaskVector {};
if (!ParseArrayBufferParams(env, manufactureDataValue, "manufactureDataMask", manufactureDataMaskVector)) {
LBSLOGE(LOCATOR_STANDARD, "parse manufactureDataMask failed");
return false;
}
beaconManufactureData.manufactureDataMask = std::move(manufactureDataMaskVector);
beaconFence->SetBeaconManufactureData(beaconManufactureData);
return true;
}
bool ParseArrayBufferParams(napi_env env, napi_value object, const char *name, std::vector<uint8_t> &outParam)
{
if (env == nullptr || object == nullptr || name == nullptr) {
return false;
}
bool hasProperty = false;
napi_has_named_property(env, object, name, &hasProperty);
if (hasProperty) {
napi_value property = nullptr;
napi_get_named_property(env, object, name, &property);
bool isArrayBuffer = false;
napi_is_arraybuffer(env, property, &isArrayBuffer);
if (!isArrayBuffer) {
LBSLOGE(NAPI_UTILS, "Wrong argument type,arraybuffer");
return false;
}
uint8_t *data = nullptr;
size_t size = 0;
bool isSuccess = ParseArrayBuffer(env, &data, size, property);
if (!isSuccess) {
LBSLOGE(NAPI_UTILS, "ParseArrayBuffer faild.");
return false;
}
outParam = std::vector<uint8_t>(data, data + size);
}
return hasProperty;
}
bool ParseArrayBuffer(napi_env env, uint8_t** data, size_t &size, napi_value args)
{
if (env == nullptr || args == nullptr) {
return false;
}
napi_status status;
napi_valuetype valuetype;
napi_typeof(env, args, &valuetype);
if (valuetype != napi_object) {
LBSLOGE(NAPI_UTILS, "Wrong argument type(%{public}d). object expected.", valuetype);
return false;
}
status = napi_get_arraybuffer_info(env, args, reinterpret_cast<void**>(data), &size);
if (status != napi_ok) {
LBSLOGE(NAPI_UTILS, "can not get arraybuffer, error is %{public}d", status);
return false;
}
LBSLOGD(NAPI_UTILS, "arraybuffer size is %{public}zu", size);
return true;
}
}
}