* Copyright (C) 2026 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 "bluetooth_search_callback_napi.h"
#include "constant_definition.h"
#include "location_log.h"
#include "napi_util.h"
namespace OHOS {
namespace Location {
const int MAX_DEVICE_ID_STR_LEN = 64;
const int MIN_RSSI_VALUE = -128;
const int MAX_RSSI_VALUE = 127;
static bool ParseDeviceIdArrayFromJs(const napi_env& env, const napi_value& object,
BluetoothSearchRequestParams& params);
static bool ParseRssiThresholdFromJs(const napi_env& env, const napi_value& object,
BluetoothSearchRequestParams& params);
bool JsObjToBluetoothSearchRequest(const napi_env& env, const napi_value& object,
BluetoothSearchRequestParams& params)
{
napi_valuetype valueType;
NAPI_CALL_BASE(env, napi_typeof(env, object, &valueType), false);
if (valueType != napi_object) {
LBSLOGE(LOCATOR_STANDARD, "Wrong argument type, value should be object");
return false;
}
params.rssiThreshold = DEFAULT_RSSI_THRESHOLD;
params.deviceIdArray.clear();
if (!ParseDeviceIdArrayFromJs(env, object, params)) {
return false;
}
if (!ParseRssiThresholdFromJs(env, object, params)) {
return false;
}
return true;
}
static bool ParseDeviceIdArrayFromJs(const napi_env& env, const napi_value& object,
BluetoothSearchRequestParams& params)
{
bool hasDeviceIdArray = false;
NAPI_CALL_BASE(env, napi_has_named_property(env, object, "deviceIdArray", &hasDeviceIdArray), false);
if (!hasDeviceIdArray) {
LBSLOGE(LOCATOR_STANDARD, "deviceIdArray is required");
return false;
}
napi_value deviceIdArrayValue;
NAPI_CALL_BASE(env, napi_get_named_property(env, object, "deviceIdArray", &deviceIdArrayValue), false);
bool isArray = false;
NAPI_CALL_BASE(env, napi_is_array(env, deviceIdArrayValue, &isArray), false);
if (!isArray) {
LBSLOGE(LOCATOR_STANDARD, "deviceIdArray must be array");
return false;
}
uint32_t arrayLength = 0;
NAPI_CALL_BASE(env, napi_get_array_length(env, deviceIdArrayValue, &arrayLength), false);
if (arrayLength > MAX_BLUETOOTH_DEVICE_ID_ARRAY_SIZE) {
LBSLOGE(LOCATOR_STANDARD, "deviceIdArray too large, max is %{public}d", MAX_BLUETOOTH_DEVICE_ID_ARRAY_SIZE);
return false;
}
for (uint32_t i = 0; i < arrayLength; ++i) {
napi_value element;
napi_valuetype valueType;
NAPI_CALL_BASE(env, napi_get_element(env, deviceIdArrayValue, i, &element), false);
NAPI_CALL_BASE(env, napi_typeof(env, element, &valueType), false);
if (valueType != napi_string) {
LBSLOGE(LOCATOR_STANDARD, "deviceIdArray element must be string");
return false;
}
char deviceIdStr[MAX_DEVICE_ID_STR_LEN] = {0};
size_t deviceIdLen = 0;
NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, element, deviceIdStr,
sizeof(deviceIdStr), &deviceIdLen), false);
params.deviceIdArray.push_back(std::string(deviceIdStr));
}
return true;
}
static bool ParseRssiThresholdFromJs(const napi_env& env, const napi_value& object,
BluetoothSearchRequestParams& params)
{
bool hasRssiThreshold = false;
NAPI_CALL_BASE(env, napi_has_named_property(env, object, "rssiThreshold", &hasRssiThreshold), false);
if (!hasRssiThreshold) {
return true;
}
napi_valuetype valueType;
napi_value rssiValue;
NAPI_CALL_BASE(env, napi_get_named_property(env, object, "rssiThreshold", &rssiValue), false);
NAPI_CALL_BASE(env, napi_typeof(env, rssiValue, &valueType), false);
if (valueType != napi_number) {
LBSLOGE(LOCATOR_STANDARD, "rssiThreshold type error");
return false;
}
int32_t rssi = 0;
napi_status status = napi_get_value_int32(env, rssiValue, &rssi);
if (status == napi_ok) {
if (rssi < MIN_RSSI_VALUE || rssi > MAX_RSSI_VALUE) {
LBSLOGE(LOCATOR_STANDARD, "rssiThreshold out of range [%{public}d, %{public}d]",
MIN_RSSI_VALUE, MAX_RSSI_VALUE);
return false;
}
params.rssiThreshold = rssi;
}
return true;
}
}
}