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