• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param, 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 &param, 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, &param);
100     return true;
101 }
102 
ParseBool(napi_env env,bool & param,napi_value args)103 bool ParseBool(napi_env env, bool &param, 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, &param);
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(), &currentBytes);
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(), &currentCount);
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, &param));
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