1 /*
2 * Copyright (C) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "bt_napi_utils"
17 #endif
18
19 #include "napi_bluetooth_utils.h"
20 #include <algorithm>
21 #include <functional>
22 #include <optional>
23 #include "bluetooth_log.h"
24 #include "bluetooth_utils.h"
25 #include "event_handler.h" // libeventhandler
26 #include "event_runner.h" // libeventhandler
27 #include "napi/native_api.h"
28 #include "napi/native_node_api.h"
29 #include "napi_bluetooth_error.h"
30 #include "napi_bluetooth_spp_client.h"
31 #include "../parser/napi_parser_utils.h"
32 #include "securec.h"
33
34 namespace OHOS {
35 namespace Bluetooth {
36 using namespace std;
37
GetCallbackErrorValue(napi_env env,int errCode)38 napi_value GetCallbackErrorValue(napi_env env, int errCode)
39 {
40 HILOGE("errCode: %{public}d", errCode);
41 napi_value result = NapiGetNull(env);
42 napi_value eCode = NapiGetNull(env);
43 if (errCode == BT_NO_ERROR) {
44 return result;
45 }
46 NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
47 NAPI_CALL(env, napi_create_object(env, &result));
48 NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode));
49
50 std::string errMsg = GetNapiErrMsg(env, errCode);
51 napi_value message = nullptr;
52 napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
53 napi_set_named_property(env, result, "message", message);
54 return result;
55 }
56
GetCallbackInfoByType(const std::string & type)57 std::shared_ptr<BluetoothCallbackInfo> GetCallbackInfoByType(const std::string &type)
58 {
59 std::lock_guard<std::mutex> lock(g_observerMutex);
60 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> observers = GetObserver();
61 if (!observers[type]) {
62 return nullptr;
63 }
64 return observers[type];
65 }
66
ParseString(napi_env env,string & param,napi_value args)67 bool ParseString(napi_env env, string ¶m, napi_value args)
68 {
69 napi_valuetype valuetype;
70 napi_typeof(env, args, &valuetype);
71
72 if (valuetype != napi_string) {
73 HILOGE("Wrong argument type(%{public}d). String expected.", valuetype);
74 return false;
75 }
76 size_t size = 0;
77
78 if (napi_get_value_string_utf8(env, args, nullptr, 0, &size) != napi_ok) {
79 HILOGE("can not get string size");
80 param = "";
81 return false;
82 }
83 param.reserve(size + 1);
84 param.resize(size);
85 if (napi_get_value_string_utf8(env, args, param.data(), (size + 1), &size) != napi_ok) {
86 HILOGE("can not get string value");
87 param = "";
88 return false;
89 }
90 return true;
91 }
92
ParseInt32(napi_env env,int32_t & param,napi_value args)93 bool ParseInt32(napi_env env, int32_t ¶m, napi_value args)
94 {
95 napi_valuetype valuetype;
96 napi_typeof(env, args, &valuetype);
97 if (valuetype != napi_number) {
98 HILOGE("Wrong argument type(%{public}d). Int32 expected.", valuetype);
99 return false;
100 }
101 napi_get_value_int32(env, args, ¶m);
102 return true;
103 }
104
ParseBool(napi_env env,bool & param,napi_value args)105 bool ParseBool(napi_env env, bool ¶m, napi_value args)
106 {
107 napi_valuetype valuetype;
108 napi_typeof(env, args, &valuetype);
109
110 if (valuetype != napi_boolean) {
111 HILOGE("Wrong argument type(%{public}d). bool expected.", valuetype);
112 return false;
113 }
114 napi_get_value_bool(env, args, ¶m);
115 return true;
116 }
117
118
ParseArrayBuffer(napi_env env,uint8_t ** data,size_t & size,napi_value args)119 bool ParseArrayBuffer(napi_env env, uint8_t** data, size_t &size, napi_value args)
120 {
121 napi_status status;
122 napi_valuetype valuetype;
123 napi_typeof(env, args, &valuetype);
124
125 if (valuetype != napi_object) {
126 HILOGE("Wrong argument type(%{public}d). object expected.", valuetype);
127 return false;
128 }
129
130 status = napi_get_arraybuffer_info(env, args, reinterpret_cast<void**>(data), &size);
131 if (status != napi_ok) {
132 HILOGE("can not get arraybuffer, error is %{public}d", status);
133 return false;
134 }
135 HILOGI("arraybuffer size is %{public}zu", size);
136 return true;
137 }
138
ConvertOppTransferInformationToJS(napi_env env,napi_value result,const BluetoothOppTransferInformation & transferInformation)139 napi_status ConvertOppTransferInformationToJS(napi_env env, napi_value result,
140 const BluetoothOppTransferInformation& transferInformation)
141 {
142 HILOGI("ConvertOppTransferInformationToJS called");
143 napi_value id;
144 napi_create_int32(env, transferInformation.GetId(), &id);
145 napi_set_named_property(env, result, "id", id);
146
147 napi_value fileName;
148 napi_create_string_utf8(env, transferInformation.GetFileName().c_str(), NAPI_AUTO_LENGTH, &fileName);
149 napi_set_named_property(env, result, "fileName", fileName);
150
151 napi_value filePath;
152 napi_create_string_utf8(env, transferInformation.GetFilePath().c_str(), NAPI_AUTO_LENGTH, &filePath);
153 napi_set_named_property(env, result, "filePath", filePath);
154
155 napi_value mimeType;
156 napi_create_string_utf8(env, transferInformation.GetMimeType().c_str(), NAPI_AUTO_LENGTH, &mimeType);
157 napi_set_named_property(env, result, "mimeType", mimeType);
158
159 napi_value deviceName;
160 napi_create_string_utf8(env, transferInformation.GetDeviceName().c_str(), NAPI_AUTO_LENGTH, &deviceName);
161 napi_set_named_property(env, result, "deviceName", deviceName);
162
163 napi_value deviceAddress;
164 napi_create_string_utf8(env, transferInformation.GetDeviceAddress().c_str(), NAPI_AUTO_LENGTH, &deviceAddress);
165 napi_set_named_property(env, result, "deviceAddress", deviceAddress);
166
167 napi_value direction;
168 napi_create_int32(env, transferInformation.GetDirection(), &direction);
169 napi_set_named_property(env, result, "direction", direction);
170
171 napi_value status;
172 napi_create_int32(env, transferInformation.GetStatus(), &status);
173 napi_set_named_property(env, result, "status", status);
174
175 napi_value failedReason;
176 napi_create_int32(env, transferInformation.GetFailedReason(), &failedReason);
177 napi_set_named_property(env, result, "failedReason", failedReason);
178
179 napi_value timeStamp;
180 napi_create_int64(env, transferInformation.GetTimeStamp(), &timeStamp);
181 napi_set_named_property(env, result, "timeStamp", timeStamp);
182
183 napi_value currentBytes;
184 napi_create_int64(env, transferInformation.GetCurrentBytes(), ¤tBytes);
185 napi_set_named_property(env, result, "currentBytes", currentBytes);
186
187 napi_value totalBytes;
188 napi_create_int64(env, transferInformation.GetTotalBytes(), &totalBytes);
189 napi_set_named_property(env, result, "totalBytes", totalBytes);
190
191 return napi_ok;
192 }
193
ConvertStringVectorToJS(napi_env env,napi_value result,std::vector<std::string> & stringVector)194 napi_status ConvertStringVectorToJS(napi_env env, napi_value result, std::vector<std::string>& stringVector)
195 {
196 HILOGI("vector size: %{public}zu", stringVector.size());
197 size_t idx = 0;
198
199 if (stringVector.empty()) {
200 return napi_ok;
201 }
202
203 for (auto& str : stringVector) {
204 napi_value obj = nullptr;
205 NAPI_BT_CALL_RETURN(napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &obj));
206 NAPI_BT_CALL_RETURN(napi_set_element(env, result, idx, obj));
207 idx++;
208 }
209 return napi_ok;
210 }
211
ConvertStateChangeParamToJS(napi_env env,napi_value result,const std::string & device,int state,int cause)212 void ConvertStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state, int cause)
213 {
214 napi_value deviceId = nullptr;
215 napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
216 napi_set_named_property(env, result, "deviceId", deviceId);
217
218 napi_value profileState = nullptr;
219 napi_create_int32(env, GetProfileConnectionState(state), &profileState);
220 napi_set_named_property(env, result, "state", profileState);
221
222 napi_value stateChangeCause = nullptr;
223 napi_create_int32(env, cause, &stateChangeCause);
224 napi_set_named_property(env, result, "cause", stateChangeCause);
225 }
226
ConvertScoStateChangeParamToJS(napi_env env,napi_value result,const std::string & device,int state)227 void ConvertScoStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state)
228 {
229 napi_value deviceId = nullptr;
230 napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
231 napi_set_named_property(env, result, "deviceId", deviceId);
232
233 napi_value profileState = nullptr;
234 napi_create_int32(env, GetScoConnectionState(state), &profileState);
235 napi_set_named_property(env, result, "state", profileState);
236 }
237
ConvertUuidsVectorToJS(napi_env env,napi_value result,const std::vector<std::string> & uuids)238 void ConvertUuidsVectorToJS(napi_env env, napi_value result, const std::vector<std::string> &uuids)
239 {
240 HILOGD("enter");
241 size_t idx = 0;
242
243 if (uuids.empty()) {
244 return;
245 }
246 HILOGI("size: %{public}zu", uuids.size());
247 for (auto& uuid : uuids) {
248 napi_value uuidValue = nullptr;
249 napi_create_string_utf8(env, uuid.c_str(), NAPI_AUTO_LENGTH, &uuidValue);
250 napi_set_element(env, result, idx, uuidValue);
251 idx++;
252 }
253 }
254
SetNamedPropertyByInteger(napi_env env,napi_value dstObj,int32_t objName,const char * propName)255 void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName)
256 {
257 napi_value prop = nullptr;
258 if (napi_create_int32(env, objName, &prop) == napi_ok) {
259 napi_set_named_property(env, dstObj, propName, prop);
260 }
261 }
262
SetNamedPropertyByString(napi_env env,napi_value dstObj,const std::string & strValue,const char * propName)263 void SetNamedPropertyByString(napi_env env, napi_value dstObj, const std::string &strValue, const char *propName)
264 {
265 napi_value prop = nullptr;
266 if (napi_create_string_utf8(env, strValue.c_str(), NAPI_AUTO_LENGTH, &prop) == napi_ok) {
267 napi_set_named_property(env, dstObj, propName, prop);
268 }
269 }
270
NapiGetNull(napi_env env)271 napi_value NapiGetNull(napi_env env)
272 {
273 napi_value result = nullptr;
274 napi_get_null(env, &result);
275 return result;
276 }
277
NapiGetBooleanFalse(napi_env env)278 napi_value NapiGetBooleanFalse(napi_env env)
279 {
280 napi_value result = nullptr;
281 napi_get_boolean(env, false, &result);
282 return result;
283 }
284
NapiGetBooleanTrue(napi_env env)285 napi_value NapiGetBooleanTrue(napi_env env)
286 {
287 napi_value result = nullptr;
288 napi_get_boolean(env, true, &result);
289 return result;
290 }
291
NapiGetBooleanRet(napi_env env,bool ret)292 napi_value NapiGetBooleanRet(napi_env env, bool ret)
293 {
294 napi_value result = nullptr;
295 napi_get_boolean(env, ret, &result);
296 return result;
297 }
298
NapiGetUndefinedRet(napi_env env)299 napi_value NapiGetUndefinedRet(napi_env env)
300 {
301 napi_value ret = nullptr;
302 napi_get_undefined(env, &ret);
303 return ret;
304 }
305
NapiGetInt32Ret(napi_env env,int32_t res)306 napi_value NapiGetInt32Ret(napi_env env, int32_t res)
307 {
308 napi_value ret = nullptr;
309 napi_create_int32(env, res, &ret);
310 return ret;
311 }
312
GetObserver()313 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> GetObserver()
314 {
315 return g_Observer;
316 }
317
GetSysBLEObserver()318 const sysBLEMap &GetSysBLEObserver()
319 {
320 return g_sysBLEObserver;
321 }
322
GetProfileConnectionState(int state)323 int GetProfileConnectionState(int state)
324 {
325 int32_t profileConnectionState = ProfileConnectionState::STATE_DISCONNECTED;
326 switch (state) {
327 case static_cast<int32_t>(BTConnectState::CONNECTING):
328 HILOGD("STATE_CONNECTING(1)");
329 profileConnectionState = ProfileConnectionState::STATE_CONNECTING;
330 break;
331 case static_cast<int32_t>(BTConnectState::CONNECTED):
332 HILOGD("STATE_CONNECTED(2)");
333 profileConnectionState = ProfileConnectionState::STATE_CONNECTED;
334 break;
335 case static_cast<int32_t>(BTConnectState::DISCONNECTING):
336 HILOGD("STATE_DISCONNECTING(3)");
337 profileConnectionState = ProfileConnectionState::STATE_DISCONNECTING;
338 break;
339 case static_cast<int32_t>(BTConnectState::DISCONNECTED):
340 HILOGD("STATE_DISCONNECTED(0)");
341 profileConnectionState = ProfileConnectionState::STATE_DISCONNECTED;
342 break;
343 default:
344 break;
345 }
346 return profileConnectionState;
347 }
348
GetProfileId(int profile)349 uint32_t GetProfileId(int profile)
350 {
351 uint32_t profileId = 0;
352 switch (profile) {
353 case static_cast<int32_t>(ProfileId::PROFILE_A2DP_SINK):
354 HILOGD("PROFILE_ID_A2DP_SINK");
355 profileId = PROFILE_ID_A2DP_SINK;
356 break;
357 case static_cast<int32_t>(ProfileId::PROFILE_A2DP_SOURCE):
358 HILOGD("PROFILE_ID_A2DP_SRC");
359 profileId = PROFILE_ID_A2DP_SRC;
360 break;
361 case static_cast<int32_t>(ProfileId::PROFILE_AVRCP_CT):
362 HILOGD("PROFILE_ID_AVRCP_CT");
363 profileId = PROFILE_ID_AVRCP_CT;
364 break;
365 case static_cast<int32_t>(ProfileId::PROFILE_AVRCP_TG):
366 HILOGD("PROFILE_ID_AVRCP_TG");
367 profileId = PROFILE_ID_AVRCP_TG;
368 break;
369 case static_cast<int32_t>(ProfileId::PROFILE_HANDS_FREE_AUDIO_GATEWAY):
370 HILOGD("PROFILE_ID_HFP_AG");
371 profileId = PROFILE_ID_HFP_AG;
372 break;
373 case static_cast<int32_t>(ProfileId::PROFILE_HANDS_FREE_UNIT):
374 HILOGD("PROFILE_ID_HFP_HF");
375 profileId = PROFILE_ID_HFP_HF;
376 break;
377 case static_cast<int32_t>(ProfileId::PROFILE_PBAP_CLIENT):
378 HILOGD("PROFILE_ID_PBAP_PCE");
379 profileId = PROFILE_ID_PBAP_PCE;
380 break;
381 case static_cast<int32_t>(ProfileId::PROFILE_PBAP_SERVER):
382 HILOGD("PROFILE_ID_PBAP_PSE");
383 profileId = PROFILE_ID_PBAP_PSE;
384 break;
385 case static_cast<int32_t>(ProfileId::PROFILE_HID_HOST):
386 HILOGD("PROFILE_HID_HOST");
387 profileId = PROFILE_ID_HID_HOST;
388 break;
389 default:
390 break;
391 }
392 return profileId;
393 }
394
GetScoConnectionState(int state)395 int GetScoConnectionState(int state)
396 {
397 int32_t scoState = ScoState::SCO_DISCONNECTED;
398 switch (state) {
399 case static_cast<int32_t>(HfpScoConnectState::SCO_CONNECTING):
400 HILOGD("SCO_CONNECTING(1)");
401 scoState = ScoState::SCO_CONNECTING;
402 break;
403 case static_cast<int32_t>(HfpScoConnectState::SCO_CONNECTED):
404 HILOGD("SCO_CONNECTED(3)");
405 scoState = ScoState::SCO_CONNECTED;
406 break;
407 case static_cast<int32_t>(HfpScoConnectState::SCO_DISCONNECTING):
408 HILOGD("SCO_DISCONNECTING(2)");
409 scoState = ScoState::SCO_DISCONNECTING;
410 break;
411 case static_cast<int32_t>(HfpScoConnectState::SCO_DISCONNECTED):
412 HILOGD("SCO_DISCONNECTED(0)");
413 scoState = ScoState::SCO_DISCONNECTED;
414 break;
415 default:
416 break;
417 }
418 return scoState;
419 }
420
RegisterSysBLEObserver(const std::shared_ptr<BluetoothCallbackInfo> & info,int32_t callbackIndex,const std::string & type)421 void RegisterSysBLEObserver(
422 const std::shared_ptr<BluetoothCallbackInfo> &info, int32_t callbackIndex, const std::string &type)
423 {
424 if (callbackIndex >= static_cast<int32_t>(ARGS_SIZE_THREE)) {
425 return;
426 }
427 std::lock_guard<std::mutex> lock(g_sysBLEObserverMutex);
428 HILOGI("type: %{public}s, index: %{public}d", type.c_str(), callbackIndex);
429 g_sysBLEObserver[type][callbackIndex] = info;
430 }
431
UnregisterSysBLEObserver(const std::string & type)432 void UnregisterSysBLEObserver(const std::string &type)
433 {
434 std::lock_guard<std::mutex> lock(g_sysBLEObserverMutex);
435 auto itor = g_sysBLEObserver.find(type);
436 if (itor != g_sysBLEObserver.end()) {
437 g_sysBLEObserver.erase(itor);
438 }
439 }
440
DoInJsMainThread(napi_env env,std::function<void (void)> func)441 int DoInJsMainThread(napi_env env, std::function<void(void)> func)
442 {
443 if (napi_send_event(env, func, napi_eprio_high) != napi_ok) {
444 HILOGE("Failed to SendEvent");
445 return -1;
446 }
447 return 0;
448 }
449
IsValidAddress(std::string bdaddr)450 bool IsValidAddress(std::string bdaddr)
451 {
452 #if defined(IOS_PLATFORM)
453 const std::regex deviceIdRegex("^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$");
454 return regex_match(bdaddr, deviceIdRegex);
455 #else
456 const std::regex deviceIdRegex("^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$");
457 return regex_match(bdaddr, deviceIdRegex);
458 #endif
459 }
460
IsValidTransport(int transport)461 bool IsValidTransport(int transport)
462 {
463 return transport == BT_TRANSPORT_BREDR || transport == BT_TRANSPORT_BLE;
464 }
465
IsValidConnectStrategy(int strategy)466 bool IsValidConnectStrategy(int strategy)
467 {
468 return strategy == static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)
469 || strategy == static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN);
470 }
471
NapiIsBoolean(napi_env env,napi_value value)472 napi_status NapiIsBoolean(napi_env env, napi_value value)
473 {
474 napi_valuetype valuetype = napi_undefined;
475 NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
476 NAPI_BT_RETURN_IF(valuetype != napi_boolean, "Wrong argument type. Boolean expected.", napi_boolean_expected);
477 return napi_ok;
478 }
479
NapiIsNumber(napi_env env,napi_value value)480 napi_status NapiIsNumber(napi_env env, napi_value value)
481 {
482 napi_valuetype valuetype = napi_undefined;
483 NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
484 NAPI_BT_RETURN_IF(valuetype != napi_number, "Wrong argument type. Number expected.", napi_number_expected);
485 return napi_ok;
486 }
487
NapiIsString(napi_env env,napi_value value)488 napi_status NapiIsString(napi_env env, napi_value value)
489 {
490 napi_valuetype valuetype = napi_undefined;
491 NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
492 NAPI_BT_RETURN_IF(valuetype != napi_string, "Wrong argument type. String expected.", napi_string_expected);
493 return napi_ok;
494 }
495
NapiIsFunction(napi_env env,napi_value value)496 napi_status NapiIsFunction(napi_env env, napi_value value)
497 {
498 napi_valuetype valuetype = napi_undefined;
499 NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
500 if (valuetype != napi_function) {
501 HILOGD("Wrong argument type. Function expected.");
502 return napi_function_expected;
503 }
504 NAPI_BT_RETURN_IF(valuetype != napi_function, "Wrong argument type. Function expected.", napi_function_expected);
505 return napi_ok;
506 }
507
NapiIsArrayBuffer(napi_env env,napi_value value)508 napi_status NapiIsArrayBuffer(napi_env env, napi_value value)
509 {
510 bool isArrayBuffer = false;
511 NAPI_BT_CALL_RETURN(napi_is_arraybuffer(env, value, &isArrayBuffer));
512 NAPI_BT_RETURN_IF(!isArrayBuffer, "Expected arraybuffer type", napi_arraybuffer_expected);
513 return napi_ok;
514 }
515
NapiIsArray(napi_env env,napi_value value)516 napi_status NapiIsArray(napi_env env, napi_value value)
517 {
518 bool isArray = false;
519 NAPI_BT_CALL_RETURN(napi_is_array(env, value, &isArray));
520 NAPI_BT_RETURN_IF(!isArray, "Expected array type", napi_array_expected);
521 return napi_ok;
522 }
523
NapiIsObject(napi_env env,napi_value value)524 napi_status NapiIsObject(napi_env env, napi_value value)
525 {
526 napi_valuetype valuetype = napi_undefined;
527 NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
528 NAPI_BT_RETURN_IF(valuetype != napi_object, "Wrong argument type. Object expected.", napi_object_expected);
529 return napi_ok;
530 }
531
ParseNumberParams(napi_env env,napi_value object,const char * name,bool & outExist,napi_value & outParam)532 napi_status ParseNumberParams(napi_env env, napi_value object, const char *name, bool &outExist,
533 napi_value &outParam)
534 {
535 bool hasProperty = false;
536 NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
537 if (hasProperty) {
538 napi_value property;
539 NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
540 napi_valuetype valuetype;
541 NAPI_BT_CALL_RETURN(napi_typeof(env, property, &valuetype));
542 NAPI_BT_RETURN_IF(valuetype != napi_number, "Wrong argument type, number expected", napi_number_expected);
543 outParam = property;
544 }
545 outExist = hasProperty;
546 return napi_ok;
547 }
548
ParseInt32Params(napi_env env,napi_value object,const char * name,bool & outExist,int32_t & outParam)549 napi_status ParseInt32Params(napi_env env, napi_value object, const char *name, bool &outExist,
550 int32_t &outParam)
551 {
552 bool exist = false;
553 napi_value param;
554 NAPI_BT_CALL_RETURN(ParseNumberParams(env, object, name, exist, param));
555 if (exist) {
556 int32_t num = 0;
557 NAPI_BT_CALL_RETURN(napi_get_value_int32(env, param, &num));
558 outParam = num;
559 }
560 outExist = exist;
561 return napi_ok;
562 }
563
ParseUint32Params(napi_env env,napi_value object,const char * name,bool & outExist,uint32_t & outParam)564 napi_status ParseUint32Params(napi_env env, napi_value object, const char *name, bool &outExist,
565 uint32_t &outParam)
566 {
567 bool exist = false;
568 napi_value param;
569 NAPI_BT_CALL_RETURN(ParseNumberParams(env, object, name, exist, param));
570 if (exist) {
571 uint32_t num = 0;
572 NAPI_BT_CALL_RETURN(napi_get_value_uint32(env, param, &num));
573 outParam = num;
574 }
575 outExist = exist;
576 return napi_ok;
577 }
578
ParseBooleanParams(napi_env env,napi_value object,const char * name,bool & outExist,bool & outParam)579 napi_status ParseBooleanParams(napi_env env, napi_value object, const char *name, bool &outExist, bool &outParam)
580 {
581 bool hasProperty = false;
582 NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
583 if (hasProperty) {
584 napi_value property;
585 NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
586 napi_valuetype valuetype;
587 NAPI_BT_CALL_RETURN(napi_typeof(env, property, &valuetype));
588 NAPI_BT_RETURN_IF(valuetype != napi_boolean, "Wrong argument type, boolean expected", napi_boolean_expected);
589
590 bool param = false;
591 NAPI_BT_CALL_RETURN(napi_get_value_bool(env, property, ¶m));
592 outParam = param;
593 }
594 outExist = hasProperty;
595 return napi_ok;
596 }
597
598 // Only used for optional paramters
ParseStringParams(napi_env env,napi_value object,const char * name,bool & outExist,std::string & outParam)599 napi_status ParseStringParams(napi_env env, napi_value object, const char *name, bool &outExist,
600 std::string &outParam)
601 {
602 bool hasProperty = false;
603 NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
604 if (hasProperty) {
605 napi_value property;
606 NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
607 napi_valuetype valuetype;
608 NAPI_BT_CALL_RETURN(napi_typeof(env, property, &valuetype));
609 NAPI_BT_RETURN_IF(valuetype != napi_string, "Wrong argument type, string expected", napi_string_expected);
610
611 std::string param {};
612 bool isSuccess = ParseString(env, param, property);
613 if (!isSuccess) {
614 return napi_invalid_arg;
615 }
616 outParam = std::move(param);
617 }
618 outExist = hasProperty;
619 return napi_ok;
620 }
621
ParseArrayBufferParams(napi_env env,napi_value object,const char * name,bool & outExist,std::vector<uint8_t> & outParam)622 napi_status ParseArrayBufferParams(napi_env env, napi_value object, const char *name, bool &outExist,
623 std::vector<uint8_t> &outParam)
624 {
625 bool hasProperty = false;
626 NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
627 if (hasProperty) {
628 napi_value property;
629 NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
630 bool isArrayBuffer = false;
631 NAPI_BT_CALL_RETURN(napi_is_arraybuffer(env, property, &isArrayBuffer));
632 NAPI_BT_RETURN_IF(!isArrayBuffer, "Wrong argument type, arraybuffer expected", napi_arraybuffer_expected);
633
634 uint8_t *data = nullptr;
635 size_t size = 0;
636 bool isSuccess = ParseArrayBuffer(env, &data, size, property);
637 if (!isSuccess) {
638 HILOGE("ParseArrayBuffer faild.");
639 return napi_invalid_arg;
640 }
641 outParam = std::vector<uint8_t>(data, data + size);
642 }
643 outExist = hasProperty;
644 return napi_ok;
645 }
646
ParseUuidParams(napi_env env,napi_value object,const char * name,bool & outExist,UUID & outUuid)647 napi_status ParseUuidParams(napi_env env, napi_value object, const char *name, bool &outExist, UUID &outUuid)
648 {
649 bool exist = false;
650 std::string uuid {};
651 NAPI_BT_CALL_RETURN(ParseStringParams(env, object, name, exist, uuid));
652 if (exist) {
653 if (!IsValidUuid(uuid)) {
654 HILOGE("match the UUID faild.");
655 return napi_invalid_arg;
656 }
657 outUuid = ParcelUuid::FromString(uuid);
658 }
659 outExist = exist;
660 return napi_ok;
661 }
662
663 // This function applies to interfaces with a single address as a parameter.
CheckDeivceIdParam(napi_env env,napi_callback_info info,std::string & addr)664 bool CheckDeivceIdParam(napi_env env, napi_callback_info info, std::string &addr)
665 {
666 size_t argc = ARGS_SIZE_ONE;
667 napi_value argv[ARGS_SIZE_ONE] = {nullptr};
668 NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok, "call failed.", false);
669 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE, "Wrong argument type", false);
670 NAPI_BT_RETURN_IF(!ParseString(env, addr, argv[PARAM0]), "ParseString failed", false);
671 NAPI_BT_RETURN_IF(!IsValidAddress(addr), "Invalid addr", false);
672 return true;
673 }
674
CheckProfileIdParam(napi_env env,napi_callback_info info,int & profileId)675 bool CheckProfileIdParam(napi_env env, napi_callback_info info, int &profileId)
676 {
677 size_t argc = ARGS_SIZE_ONE;
678 napi_value argv[ARGS_SIZE_ONE] = {nullptr};
679 napi_value thisVar = nullptr;
680 NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok, "call failed.", false);
681 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE, "Wrong argument type", false);
682 NAPI_BT_RETURN_IF(!ParseInt32(env, profileId, argv[PARAM0]), "ParseInt32 failed", false);
683 return true;
684 }
685
CheckProfileIdParamEx(napi_env env,napi_callback_info info,int & profileId,size_t & argc)686 bool CheckProfileIdParamEx(napi_env env, napi_callback_info info, int &profileId, size_t &argc)
687 {
688 napi_value argv[ARGS_SIZE_ONE] = {nullptr};
689 napi_value thisVar = nullptr;
690 NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok, "call failed.", false);
691 NAPI_BT_RETURN_IF(argc > ARGS_SIZE_ONE, "Wrong argument type", false);
692 if (argc == ARGS_SIZE_ONE) {
693 NAPI_BT_RETURN_IF(!ParseInt32(env, profileId, argv[PARAM0]), "ParseInt32 failed", false);
694 }
695 return true;
696 }
697
CheckSetDevicePairingConfirmationParam(napi_env env,napi_callback_info info,std::string & addr,bool & accept)698 bool CheckSetDevicePairingConfirmationParam(napi_env env, napi_callback_info info, std::string &addr, bool &accept)
699 {
700 size_t argc = ARGS_SIZE_TWO;
701 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
702 napi_value thisVar = nullptr;
703 NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok, "call failed.", false);
704 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Wrong argument type", false);
705 NAPI_BT_RETURN_IF(!ParseString(env, addr, argv[PARAM0]), "ParseString failed", false);
706 NAPI_BT_RETURN_IF(!IsValidAddress(addr), "Invalid addr", false);
707 NAPI_BT_RETURN_IF(!ParseBool(env, accept, argv[PARAM1]), "ParseBool failed", false);
708 return true;
709 }
710
CheckLocalNameParam(napi_env env,napi_callback_info info,std::string & name)711 bool CheckLocalNameParam(napi_env env, napi_callback_info info, std::string &name)
712 {
713 size_t argc = ARGS_SIZE_ONE;
714 napi_value argv[ARGS_SIZE_ONE] = {nullptr};
715 NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok, "call failed.", false);
716 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE, "Wrong argument type", false);
717 NAPI_BT_RETURN_IF(!ParseString(env, name, argv[PARAM0]), "ParseString failed", false);
718 return true;
719 }
720
CheckSetBluetoothScanModeParam(napi_env env,napi_callback_info info,int32_t & mode,int32_t & duration)721 bool CheckSetBluetoothScanModeParam(napi_env env, napi_callback_info info, int32_t &mode, int32_t &duration)
722 {
723 size_t argc = ARGS_SIZE_TWO;
724 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
725 napi_value thisVar = nullptr;
726 NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok, "call failed.", false);
727 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Wrong argument type", false);
728 NAPI_BT_RETURN_IF(!ParseInt32(env, mode, argv[PARAM0]), "ParseInt32 failed", false);
729 NAPI_BT_RETURN_IF(!ParseInt32(env, duration, argv[PARAM1]), "ParseInt32 failed", false);
730 return true;
731 }
732
CheckEmptyParam(napi_env env,napi_callback_info info)733 napi_status CheckEmptyParam(napi_env env, napi_callback_info info)
734 {
735 size_t argc = ARGS_SIZE_ZERO;
736 NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr));
737 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ZERO, "Requires 0 argument.", napi_invalid_arg);
738 return napi_ok;
739 }
740
NapiCheckObjectPropertiesName(napi_env env,napi_value object,const std::vector<std::string> & names)741 napi_status NapiCheckObjectPropertiesName(napi_env env, napi_value object, const std::vector<std::string> &names)
742 {
743 uint32_t len = 0;
744 napi_value properties;
745 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
746 NAPI_BT_CALL_RETURN(napi_get_property_names(env, object, &properties));
747 NAPI_BT_CALL_RETURN(napi_get_array_length(env, properties, &len));
748 for (uint32_t i = 0; i < len; ++i) {
749 std::string name {};
750 napi_value actualName;
751 NAPI_BT_CALL_RETURN(napi_get_element(env, properties, i, &actualName));
752 NAPI_BT_CALL_RETURN(NapiParseString(env, actualName, name));
753 if (std::find(names.begin(), names.end(), name) == names.end()) {
754 HILOGE("Unexpect object property name: \"%{public}s\"", name.c_str());
755 return napi_invalid_arg;
756 }
757 }
758 return napi_ok;
759 }
760
CheckSetConnectStrategyParam(napi_env env,napi_callback_info info,std::string & addr,int32_t & strategy)761 napi_status CheckSetConnectStrategyParam(napi_env env, napi_callback_info info, std::string &addr, int32_t &strategy)
762 {
763 size_t argc = ARGS_SIZE_THREE;
764 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
765 NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
766 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO && argc != ARGS_SIZE_THREE, "Requires 2 or 3 arguments.", napi_invalid_arg);
767 NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], addr));
768 NAPI_BT_RETURN_IF(!ParseInt32(env, strategy, argv[PARAM1]), "ParseInt failed", napi_invalid_arg);
769 NAPI_BT_RETURN_IF(!IsValidConnectStrategy(strategy), "Invalid strategy", napi_invalid_arg);
770 return napi_ok;
771 }
772
CheckDeviceAddressParam(napi_env env,napi_callback_info info,std::string & addr)773 napi_status CheckDeviceAddressParam(napi_env env, napi_callback_info info, std::string &addr)
774 {
775 size_t argc = ARGS_SIZE_TWO;
776 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
777 NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
778 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE && argc != ARGS_SIZE_TWO, "Requires 1 or 2 arguments.", napi_invalid_arg);
779 NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], addr));
780 return napi_ok;
781 }
782
IsAccessAuthorizationValid(int32_t accessAuthorization)783 bool IsAccessAuthorizationValid(int32_t accessAuthorization)
784 {
785 return accessAuthorization == static_cast<int32_t>(AccessAuthorization::UNKNOWN) ||
786 accessAuthorization == static_cast<int32_t>(AccessAuthorization::ALLOWED) ||
787 accessAuthorization == static_cast<int32_t>(AccessAuthorization::REJECTED);
788 }
789
CheckAccessAuthorizationParam(napi_env env,napi_callback_info info,std::string & addr,int32_t & accessAuthorization)790 napi_status CheckAccessAuthorizationParam(napi_env env, napi_callback_info info, std::string &addr,
791 int32_t &accessAuthorization)
792 {
793 size_t argc = ARGS_SIZE_THREE;
794 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
795 NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
796 NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO && argc != ARGS_SIZE_THREE, "Requires 2 or 3 arguments.", napi_invalid_arg);
797 NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], addr));
798 NAPI_BT_RETURN_IF(!ParseInt32(env, accessAuthorization, argv[PARAM1]), "ParseInt failed", napi_invalid_arg);
799 NAPI_BT_RETURN_IF(!IsAccessAuthorizationValid(accessAuthorization),
800 "Invalid accessAuthorization", napi_invalid_arg);
801 return napi_ok;
802 }
803
NapiGetOnOffCallbackName(napi_env env,napi_callback_info info,std::string & name)804 napi_status NapiGetOnOffCallbackName(napi_env env, napi_callback_info info, std::string &name)
805 {
806 size_t argc = ARGS_SIZE_TWO;
807 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
808 napi_value thisVar = nullptr;
809 NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
810 NAPI_BT_RETURN_IF(argc == ARGS_SIZE_ZERO, "Requires at least 1 arguments", napi_invalid_arg);
811
812 std::string type {};
813 NAPI_BT_CALL_RETURN(NapiParseString(env, argv[PARAM0], type));
814
815 name = type;
816 return napi_ok;
817 }
818 } // namespace Bluetooth
819 } // namespace OHOS
820