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