• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 = nullptr;
38     napi_value eCode = nullptr;
39     napi_create_int32(env, errCode, &eCode);
40     napi_create_object(env, &result);
41     napi_set_named_property(env, result, "code", eCode);
42     return result;
43 }
44 
GetCallbackInfoByType(const std::string type)45 std::shared_ptr<BluetoothCallbackInfo> GetCallbackInfoByType(const std::string type)
46 {
47     std::lock_guard<std::mutex> lock(g_observerMutex);
48     std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> observers = GetObserver();
49     if (!observers[type]) {
50         return nullptr;
51     }
52     return observers[type];
53 }
54 
ParseString(napi_env env,string & param,napi_value args)55 bool ParseString(napi_env env, string &param, napi_value args)
56 {
57     napi_valuetype valuetype;
58     napi_typeof(env, args, &valuetype);
59 
60     if (valuetype != napi_string) {
61         HILOGE("Wrong argument type(%{public}d). String expected.", valuetype);
62         return false;
63     }
64     size_t size = 0;
65 
66     if (napi_get_value_string_utf8(env, args, nullptr, 0, &size) != napi_ok) {
67         HILOGE("can not get string size");
68         param = "";
69         return false;
70     }
71     param.reserve(size + 1);
72     param.resize(size);
73     if (napi_get_value_string_utf8(env, args, param.data(), (size + 1), &size) != napi_ok) {
74         HILOGE("can not get string value");
75         param = "";
76         return false;
77     }
78     return true;
79 }
80 
ParseInt32(napi_env env,int32_t & param,napi_value args)81 bool ParseInt32(napi_env env, int32_t &param, napi_value args)
82 {
83     napi_valuetype valuetype;
84     napi_typeof(env, args, &valuetype);
85 
86     if (valuetype != napi_number) {
87         HILOGE("Wrong argument type(%{public}d). Int32 expected.", valuetype);
88         return false;
89     }
90     napi_get_value_int32(env, args, &param);
91     return true;
92 }
93 
ParseBool(napi_env env,bool & param,napi_value args)94 bool ParseBool(napi_env env, bool &param, napi_value args)
95 {
96     napi_valuetype valuetype;
97     napi_typeof(env, args, &valuetype);
98 
99     if (valuetype != napi_boolean) {
100         HILOGE("Wrong argument type(%{public}d). bool expected.", valuetype);
101         return false;
102     }
103     napi_get_value_bool(env, args, &param);
104     return true;
105 }
106 
107 
ParseArrayBuffer(napi_env env,uint8_t ** data,size_t & size,napi_value args)108 bool ParseArrayBuffer(napi_env env, uint8_t** data, size_t &size, napi_value args)
109 {
110     napi_status status;
111     napi_valuetype valuetype;
112     napi_typeof(env, args, &valuetype);
113 
114     if (valuetype != napi_object) {
115         HILOGE("Wrong argument type(%{public}d). object expected.", valuetype);
116         return false;
117     }
118 
119     status = napi_get_arraybuffer_info(env, args, (void**)data, &size);
120     if (status != napi_ok) {
121         HILOGE("can not get arraybuffer, error is %{public}d", status);
122         return false;
123     }
124     HILOGI("arraybuffer size is %{public}zu", size);
125     return true;
126 }
127 
ConvertStringVectorToJS(napi_env env,napi_value result,std::vector<std::string> & stringVector)128 napi_status ConvertStringVectorToJS(napi_env env, napi_value result, std::vector<std::string>& stringVector)
129 {
130     HILOGI("vector size: %{public}zu", stringVector.size());
131     size_t idx = 0;
132 
133     if (stringVector.empty()) {
134         return napi_ok;
135     }
136 
137     for (auto& str : stringVector) {
138         napi_value obj = nullptr;
139         NAPI_BT_CALL_RETURN(napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &obj));
140         NAPI_BT_CALL_RETURN(napi_set_element(env, result, idx, obj));
141         idx++;
142     }
143     return napi_ok;
144 }
145 
ConvertGattServiceVectorToJS(napi_env env,napi_value result,vector<GattService> & services)146 void ConvertGattServiceVectorToJS(napi_env env, napi_value result, vector<GattService>& services)
147 {
148     HILOGI("enter");
149     size_t idx = 0;
150 
151     if (services.empty()) {
152         return;
153     }
154     HILOGI("size: %{public}zu", services.size());
155     for (auto& service : services) {
156         napi_value obj = nullptr;
157         napi_create_object(env, &obj);
158         ConvertGattServiceToJS(env, obj, service);
159         napi_set_element(env, result, idx, obj);
160         idx++;
161     }
162 }
163 
ConvertOppTransferInformationToJS(napi_env env,napi_value result,BluetoothOppTransferInformation & transferInformation)164 void ConvertOppTransferInformationToJS(napi_env env, napi_value result,
165     BluetoothOppTransferInformation& transferInformation)
166 {
167     HILOGI("ConvertOppTransferInformationToJS called");
168     napi_value id;
169     napi_create_int32(env, transferInformation.GetId(), &id);
170     napi_set_named_property(env, result, "id", id);
171 
172     napi_value fileName;
173     napi_create_string_utf8(env, transferInformation.GetFileName().c_str(), NAPI_AUTO_LENGTH, &fileName);
174     napi_set_named_property(env, result, "fileName", fileName);
175 
176     napi_value filePath;
177     napi_create_string_utf8(env, transferInformation.GetFilePath().c_str(), NAPI_AUTO_LENGTH, &filePath);
178     napi_set_named_property(env, result, "filePath", filePath);
179 
180     napi_value mimeType;
181     napi_create_string_utf8(env, transferInformation.GetMimeType().c_str(), NAPI_AUTO_LENGTH, &mimeType);
182     napi_set_named_property(env, result, "mimeType", mimeType);
183 
184     napi_value deviceName;
185     napi_create_string_utf8(env, transferInformation.GetDeviceName().c_str(), NAPI_AUTO_LENGTH, &deviceName);
186     napi_set_named_property(env, result, "deviceName", deviceName);
187 
188     napi_value deviceAddress;
189     napi_create_string_utf8(env, transferInformation.GetDeviceAddress().c_str(), NAPI_AUTO_LENGTH, &deviceAddress);
190     napi_set_named_property(env, result, "deviceAddress", deviceAddress);
191 
192     napi_value direction;
193     napi_create_int32(env, transferInformation.GetDirection(), &direction);
194     napi_set_named_property(env, result, "direction", direction);
195 
196     napi_value status;
197     napi_create_int32(env, transferInformation.GetStatus(), &status);
198     napi_set_named_property(env, result, "status", status);
199 
200     napi_value failedReason;
201     napi_create_int32(env, transferInformation.GetFailedReason(), &failedReason);
202     napi_set_named_property(env, result, "failedReason", failedReason);
203 
204     napi_value timeStamp;
205     napi_create_int64(env, transferInformation.GetTimeStamp(), &timeStamp);
206     napi_set_named_property(env, result, "timeStamp", timeStamp);
207 
208     napi_value currentBytes;
209     napi_create_int64(env, transferInformation.GetCurrentBytes(), &currentBytes);
210     napi_set_named_property(env, result, "currentBytes", currentBytes);
211 
212     napi_value totalBytes;
213     napi_create_int64(env, transferInformation.GetTotalBytes(), &totalBytes);
214     napi_set_named_property(env, result, "totalBytes", totalBytes);
215 }
216 
ConvertGattServiceToJS(napi_env env,napi_value result,GattService & service)217 void ConvertGattServiceToJS(napi_env env, napi_value result, GattService& service)
218 {
219     napi_value serviceUuid;
220     napi_create_string_utf8(env, service.GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH, &serviceUuid);
221     napi_set_named_property(env, result, "serviceUuid", serviceUuid);
222 
223     napi_value isPrimary;
224     napi_get_boolean(env, service.IsPrimary(), &isPrimary);
225     napi_set_named_property(env, result, "isPrimary", isPrimary);
226     HILOGI("uuid: %{public}s, isPrimary: %{public}d", service.GetUuid().ToString().c_str(), service.IsPrimary());
227 
228     napi_value characteristics;
229     napi_create_array(env, &characteristics);
230     ConvertBLECharacteristicVectorToJS(env, characteristics, service.GetCharacteristics());
231     napi_set_named_property(env, result, "characteristics", characteristics);
232 
233     napi_value includedServices;
234     napi_create_array(env, &includedServices);
235     vector<GattService> services;
236     vector<std::reference_wrapper<GattService>> srvs = service.GetIncludedServices();
237     for (auto &srv : srvs) {
238         services.push_back(srv.get());
239     }
240     ConvertGattServiceVectorToJS(env, includedServices, services);
241     napi_set_named_property(env, result, "includedServices", includedServices);
242 }
243 
ConvertBLECharacteristicVectorToJS(napi_env env,napi_value result,vector<GattCharacteristic> & characteristics)244 void ConvertBLECharacteristicVectorToJS(napi_env env, napi_value result,
245     vector<GattCharacteristic>& characteristics)
246 {
247     HILOGI("size: %{public}zu", characteristics.size());
248     size_t idx = 0;
249     if (characteristics.empty()) {
250         return;
251     }
252 
253     for (auto &characteristic : characteristics) {
254         napi_value obj = nullptr;
255         napi_create_object(env, &obj);
256         ConvertBLECharacteristicToJS(env, obj, characteristic);
257         napi_set_element(env, result, idx, obj);
258         idx++;
259     }
260 }
261 
ConvertBLECharacteristicToJS(napi_env env,napi_value result,GattCharacteristic & characteristic)262 void ConvertBLECharacteristicToJS(napi_env env, napi_value result, GattCharacteristic& characteristic)
263 {
264     napi_value characteristicUuid;
265     HILOGI("uuid: %{public}s", characteristic.GetUuid().ToString().c_str());
266     napi_create_string_utf8(env, characteristic.GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH, &characteristicUuid);
267     napi_set_named_property(env, result, "characteristicUuid", characteristicUuid);
268 
269     if (characteristic.GetService() != nullptr) {
270         napi_value serviceUuid;
271         napi_create_string_utf8(env, characteristic.GetService()->GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH,
272             &serviceUuid);
273         napi_set_named_property(env, result, "serviceUuid", serviceUuid);
274     }
275 
276     size_t valueSize = 0;
277     uint8_t* valueData = characteristic.GetValue(&valueSize).get();
278     if (valueSize != 0) {
279         napi_value value = nullptr;
280         uint8_t* bufferData = nullptr;
281         napi_create_arraybuffer(env, valueSize, (void**)&bufferData, &value);
282         if (memcpy_s(bufferData, valueSize, valueData, valueSize) != EOK) {
283             HILOGE("memcpy_s failed");
284             return;
285         }
286         napi_set_named_property(env, result, "characteristicValue", value);
287     }
288     napi_value descriptors;
289     napi_create_array(env, &descriptors);
290     ConvertBLEDescriptorVectorToJS(env, descriptors, characteristic.GetDescriptors());
291     napi_set_named_property(env, result, "descriptors", descriptors);
292 }
293 
294 
ConvertBLEDescriptorVectorToJS(napi_env env,napi_value result,vector<GattDescriptor> & descriptors)295 void ConvertBLEDescriptorVectorToJS(napi_env env, napi_value result, vector<GattDescriptor>& descriptors)
296 {
297     HILOGI("size: %{public}zu", descriptors.size());
298     size_t idx = 0;
299 
300     if (descriptors.empty()) {
301         return;
302     }
303 
304     for (auto& descriptor : descriptors) {
305         napi_value obj = nullptr;
306         napi_create_object(env, &obj);
307         ConvertBLEDescriptorToJS(env, obj, descriptor);
308         napi_set_element(env, result, idx, obj);
309         idx++;
310     }
311 }
312 
ConvertBLEDescriptorToJS(napi_env env,napi_value result,GattDescriptor & descriptor)313 void ConvertBLEDescriptorToJS(napi_env env, napi_value result, GattDescriptor& descriptor)
314 {
315     HILOGI("uuid: %{public}s", descriptor.GetUuid().ToString().c_str());
316 
317     napi_value descriptorUuid;
318     napi_create_string_utf8(env, descriptor.GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH, &descriptorUuid);
319     napi_set_named_property(env, result, "descriptorUuid", descriptorUuid);
320 
321     if (descriptor.GetCharacteristic() != nullptr) {
322         napi_value characteristicUuid;
323         napi_create_string_utf8(env, descriptor.GetCharacteristic()->GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH,
324             &characteristicUuid);
325         napi_set_named_property(env, result, "characteristicUuid", characteristicUuid);
326 
327         if (descriptor.GetCharacteristic()->GetService() != nullptr) {
328             napi_value serviceUuid;
329             napi_create_string_utf8(env, descriptor.GetCharacteristic()->GetService()->GetUuid().ToString().c_str(),
330                 NAPI_AUTO_LENGTH, &serviceUuid);
331             napi_set_named_property(env, result, "serviceUuid", serviceUuid);
332         }
333     }
334 
335     napi_value value;
336     size_t valueSize;
337     uint8_t* valueData = descriptor.GetValue(&valueSize).get();
338     uint8_t* bufferData = nullptr;
339     napi_create_arraybuffer(env, valueSize, (void**)&bufferData, &value);
340     (void)memcpy_s(bufferData, valueSize, valueData, valueSize);
341     napi_set_named_property(env, result, "descriptorValue", value);
342 }
343 
ConvertCharacteristicReadReqToJS(napi_env env,napi_value result,const std::string & device,GattCharacteristic & characteristic,int requestId)344 void ConvertCharacteristicReadReqToJS(napi_env env, napi_value result, const std::string &device,
345     GattCharacteristic &characteristic, int requestId)
346 {
347     napi_value deviceId;
348     napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
349     napi_set_named_property(env, result, "deviceId", deviceId);
350 
351     napi_value transId;
352     napi_create_int32(env, requestId, &transId);
353     napi_set_named_property(env, result, "transId", transId);
354 
355     napi_value offset;
356     napi_create_int32(env, 0, &offset);
357     napi_set_named_property(env, result, "offset", offset);
358     HILOGI("offset is %{public}d", 0);
359 
360     napi_value characteristicUuid;
361     napi_create_string_utf8(env, characteristic.GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH, &characteristicUuid);
362     napi_set_named_property(env, result, "characteristicUuid", characteristicUuid);
363     HILOGI("characteristicUuid is %{public}s", characteristic.GetUuid().ToString().c_str());
364 
365     if (characteristic.GetService() != nullptr) {
366         napi_value serviceUuid;
367         napi_create_string_utf8(env, characteristic.GetService()->GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH,
368             &serviceUuid);
369         napi_set_named_property(env, result, "serviceUuid", serviceUuid);
370     }
371 }
372 
ConvertDescriptorReadReqToJS(napi_env env,napi_value result,const std::string & device,GattDescriptor & descriptor,int requestId)373 void ConvertDescriptorReadReqToJS(napi_env env, napi_value result, const std::string &device,
374     GattDescriptor& descriptor, int requestId)
375 {
376     napi_value deviceId;
377     napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
378     napi_set_named_property(env, result, "deviceId", deviceId);
379 
380     napi_value transId;
381     napi_create_int32(env, requestId, &transId);
382     napi_set_named_property(env, result, "transId", transId);
383 
384     napi_value offset;
385     napi_create_int32(env, 0, &offset);
386     napi_set_named_property(env, result, "offset", offset);
387     HILOGI("offset is %{public}d", 0);
388 
389     napi_value descriptorUuid;
390     napi_create_string_utf8(env, descriptor.GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH, &descriptorUuid);
391     napi_set_named_property(env, result, "descriptorUuid", descriptorUuid);
392     HILOGI("descriptorUuid is %{public}s", descriptor.GetUuid().ToString().c_str());
393 
394     if (descriptor.GetCharacteristic() != nullptr) {
395     napi_value characteristicUuid;
396     napi_create_string_utf8(env, descriptor.GetCharacteristic()->GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH,
397         &characteristicUuid);
398     napi_set_named_property(env, result, "characteristicUuid", characteristicUuid);
399 
400         if (descriptor.GetCharacteristic()->GetService() != nullptr) {
401             napi_value serviceUuid;
402             napi_create_string_utf8(env, descriptor.GetCharacteristic()->GetService()->GetUuid().ToString().c_str(),
403                 NAPI_AUTO_LENGTH, &serviceUuid);
404             napi_set_named_property(env, result, "serviceUuid", serviceUuid);
405         }
406     }
407 }
408 
ConvertCharacteristicWriteReqToJS(napi_env env,napi_value result,const std::string & device,GattCharacteristic & characteristic,int requestId)409 void ConvertCharacteristicWriteReqToJS(napi_env env, napi_value result, const std::string &device,
410     GattCharacteristic& characteristic, int requestId)
411 {
412     napi_value deviceId;
413     napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
414     napi_set_named_property(env, result, "deviceId", deviceId);
415 
416     napi_value transId;
417     napi_create_int32(env, requestId, &transId);
418     napi_set_named_property(env, result, "transId", transId);
419 
420     napi_value offset;
421     napi_create_int32(env, 0, &offset);
422     napi_set_named_property(env, result, "offset", offset);
423     HILOGI("offset is %{public}d", 0);
424 
425     napi_value isPrep;
426     napi_get_boolean(env, false, &isPrep);
427     napi_set_named_property(env, result, "isPrep", isPrep);
428 
429     napi_value needRsp;
430     napi_get_boolean(env, true, &needRsp);
431     napi_set_named_property(env, result, "needRsp", needRsp);
432 
433     napi_value value;
434     size_t valueSize;
435     uint8_t* valueData = characteristic.GetValue(&valueSize).get();
436     uint8_t* bufferData = nullptr;
437     napi_create_arraybuffer(env, valueSize, (void**)&bufferData, &value);
438     (void)memcpy_s(bufferData, valueSize, valueData, valueSize);
439     napi_set_named_property(env, result, "value", value);
440 
441     napi_value characteristicUuid;
442     napi_create_string_utf8(env, characteristic.GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH, &characteristicUuid);
443     napi_set_named_property(env, result, "characteristicUuid", characteristicUuid);
444     HILOGI("characteristicUuid is %{public}s", characteristic.GetUuid().ToString().c_str());
445 
446     if (characteristic.GetService() != nullptr) {
447         napi_value serviceUuid;
448         napi_create_string_utf8(env, characteristic.GetService()->GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH,
449             &serviceUuid);
450         napi_set_named_property(env, result, "serviceUuid", serviceUuid);
451     }
452 }
453 
ConvertDescriptorWriteReqToJS(napi_env env,napi_value result,const std::string & device,GattDescriptor & descriptor,int requestId)454 void ConvertDescriptorWriteReqToJS(napi_env env, napi_value result, const std::string &device,
455     GattDescriptor &descriptor, int requestId)
456 {
457     napi_value deviceId;
458     napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
459     napi_set_named_property(env, result, "deviceId", deviceId);
460 
461     napi_value transId;
462     napi_create_int32(env, requestId, &transId);
463     napi_set_named_property(env, result, "transId", transId);
464 
465     napi_value offset;
466     napi_create_int32(env, 0, &offset);
467     napi_set_named_property(env, result, "offset", offset);
468     HILOGI("offset is %{public}d", 0);
469 
470     napi_value isPrep;
471     napi_get_boolean(env, false, &isPrep);
472     napi_set_named_property(env, result, "isPrep", isPrep);
473 
474     napi_value needRsp;
475     napi_get_boolean(env, true, &needRsp);
476     napi_set_named_property(env, result, "needRsp", needRsp);
477 
478     napi_value value;
479     size_t valueSize;
480     uint8_t* valueData = descriptor.GetValue(&valueSize).get();
481     uint8_t* bufferData = nullptr;
482     napi_create_arraybuffer(env, valueSize, (void**)&bufferData, &value);
483     (void)memcpy_s(bufferData, valueSize, valueData, valueSize);
484     napi_set_named_property(env, result, "value", value);
485 
486     napi_value descriptorUuid;
487     napi_create_string_utf8(env, descriptor.GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH, &descriptorUuid);
488     napi_set_named_property(env, result, "descriptorUuid", descriptorUuid);
489     HILOGI("descriptorUuid is %{public}s", descriptor.GetUuid().ToString().c_str());
490 
491     if (descriptor.GetCharacteristic() != nullptr) {
492         napi_value characteristicUuid;
493         napi_create_string_utf8(env, descriptor.GetCharacteristic()->GetUuid().ToString().c_str(), NAPI_AUTO_LENGTH,
494             &characteristicUuid);
495         napi_set_named_property(env, result, "characteristicUuid", characteristicUuid);
496 
497         if (descriptor.GetCharacteristic()->GetService() != nullptr) {
498             napi_value serviceUuid;
499             napi_create_string_utf8(env, descriptor.GetCharacteristic()->GetService()->GetUuid().ToString().c_str(),
500                 NAPI_AUTO_LENGTH, &serviceUuid);
501             napi_set_named_property(env, result, "serviceUuid", serviceUuid);
502         }
503     }
504 }
505 
ConvertStateChangeParamToJS(napi_env env,napi_value result,const std::string & device,int state)506 void ConvertStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state)
507 {
508     napi_value deviceId = nullptr;
509     napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
510     napi_set_named_property(env, result, "deviceId", deviceId);
511 
512     napi_value profileState = nullptr;
513     napi_create_int32(env, GetProfileConnectionState(state), &profileState);
514     napi_set_named_property(env, result, "state", profileState);
515 }
516 
ConvertScoStateChangeParamToJS(napi_env env,napi_value result,const std::string & device,int state)517 void ConvertScoStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state)
518 {
519     napi_value deviceId = nullptr;
520     napi_create_string_utf8(env, device.c_str(), NAPI_AUTO_LENGTH, &deviceId);
521     napi_set_named_property(env, result, "deviceId", deviceId);
522 
523     napi_value profileState = nullptr;
524     napi_create_int32(env, GetScoConnectionState(state), &profileState);
525     napi_set_named_property(env, result, "state", profileState);
526 }
527 
GetServiceVectorFromJS(napi_env env,napi_value object,vector<GattService> & services,std::shared_ptr<GattServer> server,std::shared_ptr<GattClient> client)528 bool GetServiceVectorFromJS(napi_env env, napi_value object, vector<GattService>& services,
529     std::shared_ptr<GattServer> server, std::shared_ptr<GattClient> client)
530 {
531     size_t idx = 0;
532     bool hasElement = false;
533     napi_has_element(env, object, idx, &hasElement);
534     while (hasElement) {
535         napi_value result = nullptr;
536         napi_create_object(env, &result);
537         napi_get_element(env, object, idx, &result);
538         GattService* service = GetServiceFromJS(env, result, nullptr, nullptr);
539         if (service == nullptr) {
540             HILOGE("characteristic is nullptr");
541             return false;
542         }
543         services.push_back(*service);
544         delete service;
545         idx++;
546         napi_has_element(env, object, idx, &hasElement);
547     }
548     HILOGI("services size is %{public}zu", services.size());
549     return true;
550 }
551 
GetServiceFromJS(napi_env env,napi_value object,std::shared_ptr<GattServer> server,std::shared_ptr<GattClient> client)552 GattService* GetServiceFromJS(napi_env env, napi_value object, std::shared_ptr<GattServer> server,
553     std::shared_ptr<GattClient> client)
554 {
555     string serviceUuid;
556     bool isPrimary = false;
557 
558     napi_value propertyNameValue = nullptr;
559     napi_value value = nullptr;
560     bool hasProperty = false;
561 
562     napi_create_string_utf8(env, "serviceUuid", NAPI_AUTO_LENGTH, &propertyNameValue);
563     napi_get_property(env, object, propertyNameValue, &value);
564     bool isSuccess = ParseString(env, serviceUuid, value);
565     if (!isSuccess || (!regex_match(serviceUuid, uuidRegex))) {
566         HILOGE("Parse UUID faild.");
567         return nullptr;
568     }
569 
570     napi_create_string_utf8(env, "isPrimary", NAPI_AUTO_LENGTH, &propertyNameValue);
571     napi_get_property(env, object, propertyNameValue, &value);
572     ParseBool(env, isPrimary, value);
573     HILOGI("serviceUuid: %{public}s, isPrimary: %{public}d", serviceUuid.c_str(), isPrimary);
574 
575     GattServiceType serviceType = GattServiceType::PRIMARY;
576     if (!isPrimary) {
577         serviceType = GattServiceType::SECONDARY;
578     }
579 
580     GattService* service = nullptr;
581     if (server == nullptr && client == nullptr) {
582         service =  new GattService(UUID::FromString(serviceUuid), serviceType);
583 
584         napi_create_string_utf8(env, "characteristics", NAPI_AUTO_LENGTH, &propertyNameValue);
585         napi_has_property(env, object, propertyNameValue, &hasProperty);
586         if (hasProperty) {
587             napi_get_property(env, object, propertyNameValue, &value);
588             vector<GattCharacteristic> characteristics;
589             bool ret = GetCharacteristicVectorFromJS(env, value, characteristics, server, client);
590             if (!ret) {
591                 HILOGI("GetCharacteristicVectorFromJS faild");
592                 return nullptr;
593             }
594             for (auto& characteristic : characteristics) {
595                 service->AddCharacteristic(characteristic);
596             }
597         }
598 
599         napi_create_string_utf8(env, "includeServices", NAPI_AUTO_LENGTH, &propertyNameValue);
600         napi_has_property(env, object, propertyNameValue, &hasProperty);
601         if (hasProperty) {
602             napi_get_property(env, object, propertyNameValue, &value);
603             vector<GattService> services;
604             bool res = GetServiceVectorFromJS(env, value, services, server, client);
605             if (!res) {
606                 HILOGI("GetServiceVectorFromJS faild");
607                 return nullptr;
608             }
609             for (auto& serv : services) {
610                 service->AddService(serv);
611             }
612         }
613     } else {
614         std::optional<std::reference_wrapper<GattService>> obtainedService;
615         if (server != nullptr) {
616             obtainedService = server->GetService(UUID::FromString(serviceUuid), isPrimary);
617         } else if (client != nullptr) {
618             if (client->DiscoverServices()) {
619                 obtainedService = client->GetService(UUID::FromString(serviceUuid));
620             } else {
621                 return nullptr;
622             }
623         }
624 
625         if (obtainedService == std::nullopt) {
626             return nullptr;
627         } else {
628             service = &(obtainedService->get());
629         }
630     }
631     return service;
632 }
633 
GetCharacteristicVectorFromJS(napi_env env,napi_value object,vector<GattCharacteristic> & characteristics,std::shared_ptr<GattServer> server,std::shared_ptr<GattClient> client)634 bool GetCharacteristicVectorFromJS(napi_env env, napi_value object, vector<GattCharacteristic>& characteristics,
635     std::shared_ptr<GattServer> server, std::shared_ptr<GattClient> client)
636 {
637     size_t idx = 0;
638 
639     bool hasElement = false;
640     napi_has_element(env, object, idx, &hasElement);
641     while (hasElement) {
642         napi_value result = nullptr;
643         napi_create_object(env, &result);
644         napi_get_element(env, object, idx, &result);
645         GattCharacteristic* characteristic = GetCharacteristicFromJS(env, result, server, client);
646         if (characteristic == nullptr) {
647             HILOGE("characteristic is nullptr");
648             return false;
649         }
650         characteristics.push_back(*characteristic);
651         if (server == nullptr && client == nullptr) {
652             delete characteristic;
653         }
654         idx++;
655         napi_has_element(env, object, idx, &hasElement);
656     };
657     HILOGI("characteristics size is %{public}zu", characteristics.size());
658     return true;
659 }
660 
GetCharacteristicFromJS(napi_env env,napi_value object,std::shared_ptr<GattServer> server,std::shared_ptr<GattClient> client)661 GattCharacteristic* GetCharacteristicFromJS(napi_env env, napi_value object, std::shared_ptr<GattServer> server,
662     std::shared_ptr<GattClient> client)
663 {
664     string serviceUuid;
665     string characteristicUuid;
666     uint8_t *characteristicValue = nullptr;
667     size_t characteristicValueSize = 0;
668 
669     napi_value propertyNameValue = nullptr;
670     napi_value value = nullptr;
671     bool hasProperty = false;
672 
673     napi_create_string_utf8(env, "serviceUuid", NAPI_AUTO_LENGTH, &propertyNameValue);
674     napi_get_property(env, object, propertyNameValue, &value);
675     bool parseServUuid = ParseString(env, serviceUuid, value);
676     if (!parseServUuid || (!regex_match(serviceUuid, uuidRegex))) {
677         HILOGE("Parse UUID faild.");
678         return nullptr;
679     }
680     HILOGI("serviceUuid is %{public}s", serviceUuid.c_str());
681 
682     napi_create_string_utf8(env, "characteristicUuid", NAPI_AUTO_LENGTH, &propertyNameValue);
683     napi_get_property(env, object, propertyNameValue, &value);
684     bool parseCharacUuid = ParseString(env, characteristicUuid, value);
685     if (!parseCharacUuid || (!regex_match(characteristicUuid, uuidRegex))) {
686         HILOGE("Parse UUID faild.");
687         return nullptr;
688     }
689     HILOGI("characteristicUuid is %{public}s", characteristicUuid.c_str());
690 
691     GattCharacteristic* characteristic = nullptr;
692     std::optional<std::reference_wrapper<GattService>> service = nullopt;
693 
694     if (server == nullptr && client == nullptr) {
695         characteristic = new GattCharacteristic(UUID::FromString(characteristicUuid),
696             (GattCharacteristic::Permission::READABLE | GattCharacteristic::Permission::WRITEABLE),
697                 GattCharacteristic::Propertie::NOTIFY | GattCharacteristic::Propertie::READ
698                 | GattCharacteristic::Propertie::WRITE);
699 
700         napi_create_string_utf8(env, "descriptors", NAPI_AUTO_LENGTH, &propertyNameValue);
701         napi_has_property(env, object, propertyNameValue, &hasProperty);
702         if (hasProperty) {
703             napi_get_property(env, object, propertyNameValue, &value);
704             vector<GattDescriptor> descriptors;
705             bool ret = GetDescriptorVectorFromJS(env, value, descriptors);
706             if (!ret) {
707                 HILOGE("GetDescriptorVectorFromJS faild");
708                 return nullptr;
709             }
710             for (auto& descriptor : descriptors) {
711                 characteristic->AddDescriptor(descriptor);
712             }
713         } else {
714             HILOGE("descriptor is nullptr");
715             return nullptr;
716         }
717     } else {
718         if (server != nullptr) {
719             service = server->GetService(UUID::FromString(serviceUuid), true);
720             if (service == std::nullopt) {
721                 service = server->GetService(UUID::FromString(serviceUuid), false);
722             }
723         } else if (client != nullptr) {
724             service = client->GetService(UUID::FromString(serviceUuid));
725         }
726         if (service == std::nullopt) {
727             HILOGI("service is null");
728             return nullptr;
729         } else {
730             characteristic = service->get().GetCharacteristic(UUID::FromString(characteristicUuid));
731         }
732     }
733 
734     if (characteristic == nullptr) {
735         HILOGI("characteristic is null");
736         return nullptr;
737     }
738     napi_create_string_utf8(env, "characteristicValue", NAPI_AUTO_LENGTH, &propertyNameValue);
739     napi_get_property(env, object, propertyNameValue, &value);
740     if (!ParseArrayBuffer(env, &characteristicValue, characteristicValueSize, value)) {
741         HILOGE("ParseArrayBuffer failed");
742         return nullptr;
743     }
744     characteristic->SetValue(characteristicValue, characteristicValueSize);
745     return characteristic;
746 }
747 
SetNamedPropertyByInteger(napi_env env,napi_value dstObj,int32_t objName,const char * propName)748 void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName)
749 {
750     napi_value prop = nullptr;
751     if (napi_create_int32(env, objName, &prop) == napi_ok) {
752         napi_set_named_property(env, dstObj, propName, prop);
753     }
754 }
755 
NapiGetNull(napi_env env)756 napi_value NapiGetNull(napi_env env)
757 {
758     napi_value result = nullptr;
759     napi_get_null(env, &result);
760     return result;
761 }
762 
NapiGetBooleanFalse(napi_env env)763 napi_value NapiGetBooleanFalse(napi_env env)
764 {
765     napi_value result = nullptr;
766     napi_get_boolean(env, false, &result);
767     return result;
768 }
769 
NapiGetBooleanTrue(napi_env env)770 napi_value NapiGetBooleanTrue(napi_env env)
771 {
772     napi_value result = nullptr;
773     napi_get_boolean(env, true, &result);
774     return result;
775 }
776 
NapiGetBooleanRet(napi_env env,bool ret)777 napi_value NapiGetBooleanRet(napi_env env, bool ret)
778 {
779     napi_value result = nullptr;
780     napi_get_boolean(env, ret, &result);
781     return result;
782 }
783 
NapiGetUndefinedRet(napi_env env)784 napi_value NapiGetUndefinedRet(napi_env env)
785 {
786     napi_value ret = nullptr;
787     napi_get_undefined(env, &ret);
788     return ret;
789 }
790 
NapiGetInt32Ret(napi_env env,int32_t res)791 napi_value NapiGetInt32Ret(napi_env env, int32_t res)
792 {
793     napi_value ret = nullptr;
794     napi_create_int32(env, res, &ret);
795     return ret;
796 }
797 
CheckObserverParams(napi_env env,size_t argc,napi_value * argv,std::string & outType,std::shared_ptr<BluetoothCallbackInfo> & outpCallbackInfo)798 static napi_status CheckObserverParams(napi_env env, size_t argc, napi_value *argv, std::string &outType,
799     std::shared_ptr<BluetoothCallbackInfo> &outpCallbackInfo)
800 {
801     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Requires 2 arguments.", napi_invalid_arg);
802     std::string type;
803     bool ok = ParseString(env, type, argv[PARAM0]);
804     if (!ok) {
805         return napi_invalid_arg;
806     }
807     napi_valuetype valueType = napi_undefined;
808     NAPI_BT_CALL_RETURN(napi_typeof(env, argv[PARAM1], &valueType));
809     NAPI_BT_RETURN_IF(valueType != napi_function, "Requires a function argument", napi_function_expected);
810     NAPI_BT_CALL_RETURN(napi_create_reference(env, argv[PARAM1], 1, &outpCallbackInfo->callback_));
811 
812     outType = type;
813     outpCallbackInfo->env_ = env;
814     return napi_ok;
815 }
816 
RegisterObserver(napi_env env,napi_callback_info info)817 napi_value RegisterObserver(napi_env env, napi_callback_info info)
818 {
819     HILOGI("enter");
820     size_t expectedArgsCount = ARGS_SIZE_TWO;
821     size_t argc = expectedArgsCount;
822     napi_value argv[ARGS_SIZE_TWO] = {0};
823     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
824     HILOGI("argc: %{public}zu", argc);
825     if (argc == expectedArgsCount + 1) {
826         NapiSppClient::On(env, info);
827     } else {
828         std::string type;
829         std::shared_ptr<BluetoothCallbackInfo> pCallbackInfo = std::make_shared<BluetoothCallbackInfo>();
830         auto status = CheckObserverParams(env, argc, argv, type, pCallbackInfo);
831         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
832         std::lock_guard<std::mutex> lock(g_observerMutex);
833         g_Observer[type] = pCallbackInfo;
834         HILOGI("%{public}s is registered", type.c_str());
835     }
836     napi_value ret = nullptr;
837     napi_get_undefined(env, &ret);
838     return ret;
839 }
840 
RemoveObserver(std::string type)841 static void RemoveObserver(std::string type)
842 {
843     std::lock_guard<std::mutex> lock(g_observerMutex);
844     if (g_Observer.find(type) != g_Observer.end()) {
845         g_Observer[type] = nullptr;
846         HILOGI("%{public}s is deregistered", type.c_str());
847     } else {
848         HILOGE("%{public}s has not been registered", type.c_str());
849     }
850 }
851 
852 static std::map<std::string, int32_t> registerTypeMap = {
853     {REGISTER_DEVICE_FIND_TYPE, BLUETOOTH_DEVICE_FIND_TYPE},
854     {REGISTER_STATE_CHANGE_TYPE, STATE_CHANGE_TYPE},
855     {REGISTER_PIN_REQUEST_TYPE, PIN_REQUEST_TYPE},
856     {REGISTER_BOND_STATE_TYPE, BOND_STATE_CHANGE_TYPE},
857     {REGISTER_BLE_FIND_DEVICE_TYPE, BLE_DEVICE_FIND_TYPE}
858 };
859 
CallbackObserver(int32_t typeNum,std::shared_ptr<BluetoothCallbackInfo> pCallbackInfo)860 napi_value CallbackObserver(int32_t typeNum, std::shared_ptr<BluetoothCallbackInfo> pCallbackInfo)
861 {
862     napi_value result = 0;
863     napi_value deviceId = nullptr;
864     napi_value state = nullptr;
865     napi_value pinCode = nullptr;
866     napi_value value = 0;
867 
868     switch (typeNum) {
869         case BLUETOOTH_DEVICE_FIND_TYPE:
870             napi_create_array(pCallbackInfo->env_, &result);
871             napi_create_string_utf8(pCallbackInfo->env_, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &value);
872             napi_set_element(pCallbackInfo->env_, result, 0, value);
873             break;
874         case STATE_CHANGE_TYPE:
875             napi_create_int32(pCallbackInfo->env_, static_cast<int32_t>(BluetoothState::STATE_OFF), &result);
876             break;
877         case PIN_REQUEST_TYPE:
878             napi_create_object(pCallbackInfo->env_, &result);
879             napi_create_string_utf8(pCallbackInfo->env_, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &deviceId);
880             napi_set_named_property(pCallbackInfo->env_, result, "deviceId", deviceId);
881             napi_create_string_utf8(pCallbackInfo->env_, INVALID_PIN_CODE.c_str(), NAPI_AUTO_LENGTH, &pinCode);
882             napi_set_named_property(pCallbackInfo->env_, result, "pinCode", pinCode);
883             break;
884         case BOND_STATE_CHANGE_TYPE:
885             napi_create_object(pCallbackInfo->env_, &result);
886             napi_create_string_utf8(pCallbackInfo->env_, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &deviceId);
887             napi_set_named_property(pCallbackInfo->env_, result, "deviceId", deviceId);
888             napi_create_int32(pCallbackInfo->env_, static_cast<int32_t>(BondState::BOND_STATE_INVALID), &state);
889             napi_set_named_property(pCallbackInfo->env_, result, "state", state);
890             break;
891         case BLE_DEVICE_FIND_TYPE:
892             napi_create_array(pCallbackInfo->env_, &result);
893             napi_create_string_utf8(pCallbackInfo->env_, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &value);
894             napi_set_element(pCallbackInfo->env_, result, 0, value);
895             break;
896         default:
897             result = NapiGetNull(pCallbackInfo->env_);
898             break;
899     }
900     return result;
901 }
902 
DeregisterObserver(napi_env env,napi_callback_info info)903 napi_value DeregisterObserver(napi_env env, napi_callback_info info)
904 {
905     HILOGI("enter");
906     auto status = CheckDeregisterObserver(env, info);
907     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
908     return NapiGetUndefinedRet(env);
909 }
910 
GetObserver()911 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> GetObserver()
912 {
913     return g_Observer;
914 }
915 
GetSysBLEObserver()916 const sysBLEMap &GetSysBLEObserver()
917 {
918     return g_sysBLEObserver;
919 }
920 
GetDescriptorVectorFromJS(napi_env env,napi_value object,vector<GattDescriptor> & descriptors)921 bool GetDescriptorVectorFromJS(napi_env env, napi_value object, vector<GattDescriptor>& descriptors)
922 {
923     size_t idx = 0;
924     bool hasElement = false;
925     napi_has_element(env, object, idx, &hasElement);
926 
927     while (hasElement) {
928         napi_value result = nullptr;
929         napi_create_object(env, &result);
930         napi_get_element(env, object, idx, &result);
931         GattDescriptor* descriptor = GetDescriptorFromJS(env, result, nullptr, nullptr);
932         if (descriptor == nullptr) {
933             HILOGE("descriptor is nullptr");
934             return false;
935         }
936         descriptors.push_back(*descriptor);
937         delete descriptor;
938         idx++;
939         napi_has_element(env, object, idx, &hasElement);
940     }
941     HILOGI("descriptors size: %{public}zu", descriptors.size());
942     return true;
943 }
944 
GetDescriptorFromJS(napi_env env,napi_value object,std::shared_ptr<GattServer> server,std::shared_ptr<GattClient> client)945 GattDescriptor* GetDescriptorFromJS(napi_env env, napi_value object, std::shared_ptr<GattServer> server,
946     std::shared_ptr<GattClient> client)
947 {
948     string serviceUuid;
949     string characteristicUuid;
950     string descriptorUuid;
951     uint8_t *descriptorValue = nullptr;
952     size_t descriptorValueSize = 0;
953 
954     napi_value propertyNameValue = nullptr;
955     napi_value value = nullptr;
956 
957     napi_create_string_utf8(env, "serviceUuid", NAPI_AUTO_LENGTH, &propertyNameValue);
958     napi_get_property(env, object, propertyNameValue, &value);
959     bool parseServUuid = ParseString(env, serviceUuid, value);
960     if (!parseServUuid || (!regex_match(serviceUuid, uuidRegex))) {
961         HILOGE("Parse UUID faild.");
962         return nullptr;
963     }
964     HILOGI("serviceUuid is %{public}s", serviceUuid.c_str());
965 
966     napi_create_string_utf8(env, "characteristicUuid", NAPI_AUTO_LENGTH, &propertyNameValue);
967     napi_get_property(env, object, propertyNameValue, &value);
968     bool parseCharacUuid = ParseString(env, characteristicUuid, value);
969     if (!parseCharacUuid || (!regex_match(characteristicUuid, uuidRegex))) {
970         HILOGE("Parse UUID faild.");
971         return nullptr;
972     }
973     HILOGI("characteristicUuid is %{public}s", characteristicUuid.c_str());
974 
975     napi_create_string_utf8(env, "descriptorUuid", NAPI_AUTO_LENGTH, &propertyNameValue);
976     napi_get_property(env, object, propertyNameValue, &value);
977     bool parseDescUuid = ParseString(env, descriptorUuid, value);
978     if (!parseDescUuid || (!regex_match(descriptorUuid, uuidRegex))) {
979         HILOGE("Parse UUID faild.");
980         return nullptr;
981     }
982     HILOGI("descriptorUuid is %{public}s", descriptorUuid.c_str());
983 
984     GattDescriptor* descriptor = nullptr;
985     GattCharacteristic* characteristic = nullptr;
986     std::optional<std::reference_wrapper<GattService>> service = nullopt;
987 
988     if (server == nullptr && client == nullptr) {
989         descriptor = new GattDescriptor(UUID::FromString(descriptorUuid),
990             GattCharacteristic::Permission::READABLE | GattCharacteristic::Permission::WRITEABLE);
991     } else {
992         if (server != nullptr) {
993             service = server->GetService(UUID::FromString(serviceUuid), true);
994             if (service == std::nullopt) {
995                 service = server->GetService(UUID::FromString(serviceUuid), false);
996             }
997         } else if (client != nullptr) {
998             service = client->GetService(UUID::FromString(serviceUuid));
999         }
1000 
1001         if (service == std::nullopt) {
1002             return nullptr;
1003         } else {
1004             characteristic = service->get().GetCharacteristic(UUID::FromString(characteristicUuid));
1005         }
1006 
1007         if (characteristic == nullptr) {
1008             return nullptr;
1009         } else {
1010             descriptor = characteristic->GetDescriptor(UUID::FromString(descriptorUuid));
1011         }
1012     }
1013 
1014     if (descriptor == nullptr) {
1015         HILOGE("descriptor is nullptr");
1016         return nullptr;
1017     }
1018 
1019     napi_create_string_utf8(env, "descriptorValue", NAPI_AUTO_LENGTH, &propertyNameValue);
1020     napi_get_property(env, object, propertyNameValue, &value);
1021     if (!ParseArrayBuffer(env, &descriptorValue, descriptorValueSize, value)) {
1022         HILOGE("ParseArrayBuffer failed");
1023         return nullptr;
1024     } else {
1025         HILOGI("descriptorValue is %{public}d", descriptorValue[0]);
1026     }
1027     descriptor->SetValue(descriptorValue, descriptorValueSize);
1028 
1029     return descriptor;
1030 }
1031 
GetServerResponseFromJS(napi_env env,napi_value object)1032 ServerResponse GetServerResponseFromJS(napi_env env, napi_value object)
1033 {
1034     ServerResponse serverResponse;
1035     napi_value propertyNameValue = nullptr;
1036     napi_value value = nullptr;
1037     uint8_t *values = nullptr;
1038     size_t valuesSize = 0;
1039 
1040     napi_create_string_utf8(env, "deviceId", NAPI_AUTO_LENGTH, &propertyNameValue);
1041     napi_get_property(env, object, propertyNameValue, &value);
1042     ParseString(env, serverResponse.deviceId, value);
1043 
1044     napi_create_string_utf8(env, "transId", NAPI_AUTO_LENGTH, &propertyNameValue);
1045     napi_get_property(env, object, propertyNameValue, &value);
1046     ParseInt32(env, serverResponse.transId, value);
1047 
1048     napi_create_string_utf8(env, "status", NAPI_AUTO_LENGTH, &propertyNameValue);
1049     napi_get_property(env, object, propertyNameValue, &value);
1050     ParseInt32(env, serverResponse.status, value);
1051     HILOGI("deviceId: %{public}s, transId: %{public}d, status: %{public}d",
1052         GetEncryptAddr(serverResponse.deviceId).c_str(), serverResponse.transId, serverResponse.status);
1053 
1054     napi_create_string_utf8(env, "offset", NAPI_AUTO_LENGTH, &propertyNameValue);
1055     napi_get_property(env, object, propertyNameValue, &value);
1056     ParseInt32(env, serverResponse.offset, value);
1057 
1058     napi_create_string_utf8(env, "value", NAPI_AUTO_LENGTH, &propertyNameValue);
1059     napi_get_property(env, object, propertyNameValue, &value);
1060     if (!ParseArrayBuffer(env, &values, valuesSize, value)) {
1061         HILOGE("ParseArrayBuffer failed");
1062     }
1063     serverResponse.SetValue(values, valuesSize);
1064     return serverResponse;
1065 }
1066 
GetSppOptionFromJS(napi_env env,napi_value object)1067 std::shared_ptr<SppOption> GetSppOptionFromJS(napi_env env, napi_value object)
1068 {
1069     std::shared_ptr<SppOption> sppOption = std::make_shared<SppOption>();
1070     napi_value propertyNameValue = nullptr;
1071     napi_value value = nullptr;
1072 
1073     napi_create_string_utf8(env, "uuid", NAPI_AUTO_LENGTH, &propertyNameValue);
1074     napi_get_property(env, object, propertyNameValue, &value);
1075     bool isSuccess = ParseString(env, sppOption->uuid_, value);
1076     if (!isSuccess || (!regex_match(sppOption->uuid_, uuidRegex))) {
1077         HILOGE("Parse UUID faild.");
1078         return nullptr;
1079     }
1080     HILOGI("uuid is %{public}s", sppOption->uuid_.c_str());
1081 
1082     napi_create_string_utf8(env, "secure", NAPI_AUTO_LENGTH, &propertyNameValue);
1083     napi_get_property(env, object, propertyNameValue, &value);
1084     ParseBool(env, sppOption->secure_, value);
1085     HILOGI("secure is %{public}d", sppOption->secure_);
1086 
1087     int type = 0;
1088     napi_create_string_utf8(env, "type", NAPI_AUTO_LENGTH, &propertyNameValue);
1089     napi_get_property(env, object, propertyNameValue, &value);
1090     ParseInt32(env, type, value);
1091     sppOption->type_ = SppSocketType(type);
1092     HILOGI("uuid: %{public}s, secure: %{public}d, type: %{public}d",
1093         sppOption->uuid_.c_str(), sppOption->secure_, sppOption->type_);
1094     return sppOption;
1095 }
1096 
SetGattClientDeviceId(const std::string & deviceId)1097 void SetGattClientDeviceId(const std::string &deviceId)
1098 {
1099     deviceAddr = deviceId;
1100 }
1101 
GetGattClientDeviceId()1102 std::string GetGattClientDeviceId()
1103 {
1104     return deviceAddr;
1105 }
1106 
SetRssiValueCallbackInfo(std::shared_ptr<GattGetRssiValueCallbackInfo> & callback)1107 void SetRssiValueCallbackInfo(std::shared_ptr<GattGetRssiValueCallbackInfo> &callback)
1108 {
1109     callbackInfo = callback;
1110 }
1111 
GetRssiValueCallbackInfo()1112 std::shared_ptr<GattGetRssiValueCallbackInfo> GetRssiValueCallbackInfo()
1113 {
1114     return callbackInfo;
1115 }
1116 
GetProfileConnectionState(int state)1117 int GetProfileConnectionState(int state)
1118 {
1119     int32_t profileConnectionState = ProfileConnectionState::STATE_DISCONNECTED;
1120     switch (state) {
1121         case static_cast<int32_t>(BTConnectState::CONNECTING):
1122             HILOGD("STATE_CONNECTING(1)");
1123             profileConnectionState = ProfileConnectionState::STATE_CONNECTING;
1124             break;
1125         case static_cast<int32_t>(BTConnectState::CONNECTED):
1126             HILOGD("STATE_CONNECTED(2)");
1127             profileConnectionState = ProfileConnectionState::STATE_CONNECTED;
1128             break;
1129         case static_cast<int32_t>(BTConnectState::DISCONNECTING):
1130             HILOGD("STATE_DISCONNECTING(3)");
1131             profileConnectionState = ProfileConnectionState::STATE_DISCONNECTING;
1132             break;
1133         case static_cast<int32_t>(BTConnectState::DISCONNECTED):
1134             HILOGD("STATE_DISCONNECTED(0)");
1135             profileConnectionState = ProfileConnectionState::STATE_DISCONNECTED;
1136             break;
1137         default:
1138             break;
1139     }
1140     return profileConnectionState;
1141 }
1142 
GetProfileId(int profile)1143 uint32_t GetProfileId(int profile)
1144 {
1145     uint32_t profileId = 0;
1146     switch (profile) {
1147         case static_cast<int32_t>(ProfileId::PROFILE_A2DP_SINK):
1148             HILOGD("PROFILE_ID_A2DP_SINK");
1149             profileId = PROFILE_ID_A2DP_SINK;
1150             break;
1151         case static_cast<int32_t>(ProfileId::PROFILE_A2DP_SOURCE):
1152             HILOGD("PROFILE_ID_A2DP_SRC");
1153             profileId = PROFILE_ID_A2DP_SRC;
1154             break;
1155         case static_cast<int32_t>(ProfileId::PROFILE_AVRCP_CT):
1156             HILOGD("PROFILE_ID_AVRCP_CT");
1157             profileId = PROFILE_ID_AVRCP_CT;
1158             break;
1159         case static_cast<int32_t>(ProfileId::PROFILE_AVRCP_TG):
1160             HILOGD("PROFILE_ID_AVRCP_TG");
1161             profileId = PROFILE_ID_AVRCP_TG;
1162             break;
1163         case static_cast<int32_t>(ProfileId::PROFILE_HANDS_FREE_AUDIO_GATEWAY):
1164             HILOGD("PROFILE_ID_HFP_AG");
1165             profileId = PROFILE_ID_HFP_AG;
1166             break;
1167         case static_cast<int32_t>(ProfileId::PROFILE_HANDS_FREE_UNIT):
1168             HILOGD("PROFILE_ID_HFP_HF");
1169             profileId = PROFILE_ID_HFP_HF;
1170             break;
1171         case static_cast<int32_t>(ProfileId::PROFILE_PBAP_CLIENT):
1172             HILOGD("PROFILE_ID_PBAP_PCE");
1173             profileId = PROFILE_ID_PBAP_PCE;
1174             break;
1175         case static_cast<int32_t>(ProfileId::PROFILE_PBAP_SERVER):
1176             HILOGD("PROFILE_ID_PBAP_PSE");
1177             profileId = PROFILE_ID_PBAP_PSE;
1178             break;
1179         default:
1180             break;
1181     }
1182     return profileId;
1183 }
1184 
GetScoConnectionState(int state)1185 int GetScoConnectionState(int state)
1186 {
1187     int32_t scoState = ScoState::SCO_DISCONNECTED;
1188     switch (state) {
1189         case static_cast<int32_t>(HfpScoConnectState::SCO_CONNECTING):
1190             HILOGD("SCO_CONNECTING(1)");
1191             scoState = ScoState::SCO_CONNECTING;
1192             break;
1193         case static_cast<int32_t>(HfpScoConnectState::SCO_CONNECTED):
1194             HILOGD("SCO_CONNECTED(3)");
1195             scoState = ScoState::SCO_CONNECTED;
1196             break;
1197         case static_cast<int32_t>(HfpScoConnectState::SCO_DISCONNECTING):
1198             HILOGD("SCO_DISCONNECTING(2)");
1199             scoState = ScoState::SCO_DISCONNECTING;
1200             break;
1201         case static_cast<int32_t>(HfpScoConnectState::SCO_DISCONNECTED):
1202             HILOGD("SCO_DISCONNECTED(0)");
1203             scoState = ScoState::SCO_DISCONNECTED;
1204             break;
1205         default:
1206             break;
1207     }
1208     return scoState;
1209 }
1210 
SetCurrentAppOperate(const bool & isCurrentApp)1211 void SetCurrentAppOperate(const bool &isCurrentApp)
1212 {
1213     isCurrentAppOperate.store(isCurrentApp);
1214 }
1215 
GetCurrentAppOperate()1216 bool GetCurrentAppOperate()
1217 {
1218     return isCurrentAppOperate.load();
1219 }
1220 
RegisterSysBLEObserver(const std::shared_ptr<BluetoothCallbackInfo> & info,int32_t callbackIndex,const std::string & type)1221 void RegisterSysBLEObserver(
1222     const std::shared_ptr<BluetoothCallbackInfo> &info, int32_t callbackIndex, const std::string &type)
1223 {
1224     if (callbackIndex >= static_cast<int32_t>(ARGS_SIZE_THREE)) {
1225         return;
1226     }
1227     std::lock_guard<std::mutex> lock(g_sysBLEObserverMutex);
1228     HILOGI("type: %{public}s, index: %{public}d", type.c_str(), callbackIndex);
1229     g_sysBLEObserver[type][callbackIndex] = info;
1230 }
1231 
UnregisterSysBLEObserver(const std::string & type)1232 void UnregisterSysBLEObserver(const std::string &type)
1233 {
1234     std::lock_guard<std::mutex> lock(g_sysBLEObserverMutex);
1235     auto itor = g_sysBLEObserver.find(type);
1236     if (itor != g_sysBLEObserver.end()) {
1237         g_sysBLEObserver.erase(itor);
1238     }
1239 }
1240 
IsValidAddress(std::string bdaddr)1241 bool IsValidAddress(std::string bdaddr)
1242 {
1243     const std::regex deviceIdRegex("^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$");
1244     return regex_match(bdaddr, deviceIdRegex);
1245 }
1246 
IsValidUuid(std::string uuid)1247 bool IsValidUuid(std::string uuid)
1248 {
1249     return regex_match(uuid, uuidRegex);
1250 }
1251 
NapiIsBoolean(napi_env env,napi_value value)1252 napi_status NapiIsBoolean(napi_env env, napi_value value)
1253 {
1254     napi_valuetype valuetype = napi_undefined;
1255     NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
1256     NAPI_BT_RETURN_IF(valuetype != napi_boolean, "Wrong argument type. Boolean expected.", napi_boolean_expected);
1257     return napi_ok;
1258 }
1259 
NapiIsNumber(napi_env env,napi_value value)1260 napi_status NapiIsNumber(napi_env env, napi_value value)
1261 {
1262     napi_valuetype valuetype = napi_undefined;
1263     NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
1264     NAPI_BT_RETURN_IF(valuetype != napi_number, "Wrong argument type. Number expected.", napi_number_expected);
1265     return napi_ok;
1266 }
1267 
NapiIsString(napi_env env,napi_value value)1268 napi_status NapiIsString(napi_env env, napi_value value)
1269 {
1270     napi_valuetype valuetype = napi_undefined;
1271     NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
1272     NAPI_BT_RETURN_IF(valuetype != napi_string, "Wrong argument type. String expected.", napi_string_expected);
1273     return napi_ok;
1274 }
1275 
NapiIsFunction(napi_env env,napi_value value)1276 napi_status NapiIsFunction(napi_env env, napi_value value)
1277 {
1278     napi_valuetype valuetype = napi_undefined;
1279     NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
1280     NAPI_BT_RETURN_IF(valuetype != napi_function, "Wrong argument type. Function expected.", napi_function_expected);
1281     return napi_ok;
1282 }
1283 
NapiIsArrayBuffer(napi_env env,napi_value value)1284 napi_status NapiIsArrayBuffer(napi_env env, napi_value value)
1285 {
1286     bool isArrayBuffer = false;
1287     NAPI_BT_CALL_RETURN(napi_is_arraybuffer(env, value, &isArrayBuffer));
1288     NAPI_BT_RETURN_IF(!isArrayBuffer, "Expected arraybuffer type", napi_arraybuffer_expected);
1289     return napi_ok;
1290 }
1291 
NapiIsArray(napi_env env,napi_value value)1292 napi_status NapiIsArray(napi_env env, napi_value value)
1293 {
1294     bool isArray = false;
1295     NAPI_BT_CALL_RETURN(napi_is_array(env, value, &isArray));
1296     NAPI_BT_RETURN_IF(!isArray, "Expected array type", napi_array_expected);
1297     return napi_ok;
1298 }
1299 
NapiIsObject(napi_env env,napi_value value)1300 napi_status NapiIsObject(napi_env env, napi_value value)
1301 {
1302     napi_valuetype valuetype = napi_undefined;
1303     NAPI_BT_CALL_RETURN(napi_typeof(env, value, &valuetype));
1304     NAPI_BT_RETURN_IF(valuetype != napi_object, "Wrong argument type. Object expected.", napi_object_expected);
1305     return napi_ok;
1306 }
1307 
ParseNumberParams(napi_env env,napi_value object,const char * name,bool & outExist,napi_value & outParam)1308 napi_status ParseNumberParams(napi_env env, napi_value object, const char *name, bool &outExist,
1309     napi_value &outParam)
1310 {
1311     bool hasProperty = false;
1312     NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
1313     if (hasProperty) {
1314         napi_value property;
1315         NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
1316         napi_valuetype valuetype;
1317         NAPI_BT_CALL_RETURN(napi_typeof(env, property, &valuetype));
1318         NAPI_BT_RETURN_IF(valuetype != napi_number, "Wrong argument type, number expected", napi_number_expected);
1319         outParam = property;
1320     }
1321     outExist = hasProperty;
1322     return napi_ok;
1323 }
1324 
ParseInt32Params(napi_env env,napi_value object,const char * name,bool & outExist,int32_t & outParam)1325 napi_status ParseInt32Params(napi_env env, napi_value object, const char *name, bool &outExist,
1326     int32_t &outParam)
1327 {
1328     bool exist = false;
1329     napi_value param;
1330     NAPI_BT_CALL_RETURN(ParseNumberParams(env, object, name, exist, param));
1331     if (exist) {
1332         int32_t num = 0;
1333         NAPI_BT_CALL_RETURN(napi_get_value_int32(env, param, &num));
1334         outParam = num;
1335     }
1336     outExist = exist;
1337     return napi_ok;
1338 }
1339 
ParseUint32Params(napi_env env,napi_value object,const char * name,bool & outExist,uint32_t & outParam)1340 napi_status ParseUint32Params(napi_env env, napi_value object, const char *name, bool &outExist,
1341     uint32_t &outParam)
1342 {
1343     bool exist = false;
1344     napi_value param;
1345     NAPI_BT_CALL_RETURN(ParseNumberParams(env, object, name, exist, param));
1346     if (exist) {
1347         uint32_t num = 0;
1348         NAPI_BT_CALL_RETURN(napi_get_value_uint32(env, param, &num));
1349         outParam = num;
1350     }
1351     outExist = exist;
1352     return napi_ok;
1353 }
1354 
ParseBooleanParams(napi_env env,napi_value object,const char * name,bool & outExist,bool & outParam)1355 napi_status ParseBooleanParams(napi_env env, napi_value object, const char *name, bool &outExist, bool &outParam)
1356 {
1357     bool hasProperty = false;
1358     NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
1359     if (hasProperty) {
1360         napi_value property;
1361         NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
1362         napi_valuetype valuetype;
1363         NAPI_BT_CALL_RETURN(napi_typeof(env, property, &valuetype));
1364         NAPI_BT_RETURN_IF(valuetype != napi_boolean, "Wrong argument type, boolean expected", napi_boolean_expected);
1365 
1366         bool param = false;
1367         NAPI_BT_CALL_RETURN(napi_get_value_bool(env, property, &param));
1368         outParam = param;
1369     }
1370     outExist = hasProperty;
1371     return napi_ok;
1372 }
1373 
1374 // Only used for optional paramters
ParseStringParams(napi_env env,napi_value object,const char * name,bool & outExist,std::string & outParam)1375 napi_status ParseStringParams(napi_env env, napi_value object, const char *name, bool &outExist,
1376     std::string &outParam)
1377 {
1378     bool hasProperty = false;
1379     NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
1380     if (hasProperty) {
1381         napi_value property;
1382         NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
1383         napi_valuetype valuetype;
1384         NAPI_BT_CALL_RETURN(napi_typeof(env, property, &valuetype));
1385         NAPI_BT_RETURN_IF(valuetype != napi_string, "Wrong argument type, string expected", napi_string_expected);
1386 
1387         std::string param {};
1388         bool isSuccess = ParseString(env, param, property);
1389         if (!isSuccess) {
1390             return napi_invalid_arg;
1391         }
1392         outParam = std::move(param);
1393     }
1394     outExist = hasProperty;
1395     return napi_ok;
1396 }
1397 
ParseArrayBufferParams(napi_env env,napi_value object,const char * name,bool & outExist,std::vector<uint8_t> & outParam)1398 napi_status ParseArrayBufferParams(napi_env env, napi_value object, const char *name, bool &outExist,
1399     std::vector<uint8_t> &outParam)
1400 {
1401     bool hasProperty = false;
1402     NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &hasProperty));
1403     if (hasProperty) {
1404         napi_value property;
1405         NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
1406         bool isArrayBuffer = false;
1407         NAPI_BT_CALL_RETURN(napi_is_arraybuffer(env, property, &isArrayBuffer));
1408         NAPI_BT_RETURN_IF(!isArrayBuffer, "Wrong argument type, arraybuffer expected", napi_arraybuffer_expected);
1409 
1410         uint8_t *data = nullptr;
1411         size_t size = 0;
1412         bool isSuccess = ParseArrayBuffer(env, &data, size, property);
1413         if (!isSuccess) {
1414             HILOGE("ParseArrayBuffer faild.");
1415             return napi_invalid_arg;
1416         }
1417         outParam = std::vector<uint8_t>(data, data + size);
1418     }
1419     outExist = hasProperty;
1420     return napi_ok;
1421 }
1422 
ParseUuidParams(napi_env env,napi_value object,const char * name,bool & outExist,UUID & outUuid)1423 napi_status ParseUuidParams(napi_env env, napi_value object, const char *name, bool &outExist, UUID &outUuid)
1424 {
1425     bool exist = false;
1426     std::string uuid {};
1427     NAPI_BT_CALL_RETURN(ParseStringParams(env, object, name, exist, uuid));
1428     if (exist) {
1429         if (!regex_match(uuid, uuidRegex)) {
1430             HILOGE("match the UUID faild.");
1431             return napi_invalid_arg;
1432         }
1433         outUuid = ParcelUuid::FromString(uuid);
1434     }
1435     outExist = exist;
1436     return napi_ok;
1437 }
1438 
1439 // This function applies to interfaces with a single address as a parameter.
CheckDeivceIdParam(napi_env env,napi_callback_info info,std::string & addr)1440 bool CheckDeivceIdParam(napi_env env, napi_callback_info info, std::string &addr)
1441 {
1442     size_t argc = ARGS_SIZE_ONE;
1443     napi_value argv[ARGS_SIZE_ONE] = {nullptr};
1444     NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok, "call failed.", false);
1445     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE, "Wrong argument type", false);
1446     NAPI_BT_RETURN_IF(!ParseString(env, addr, argv[PARAM0]), "ParseString failed", false);
1447     NAPI_BT_RETURN_IF(!IsValidAddress(addr), "Invalid addr", false);
1448     return true;
1449 }
1450 
CheckProfileIdParam(napi_env env,napi_callback_info info,int & profileId)1451 bool CheckProfileIdParam(napi_env env, napi_callback_info info, int &profileId)
1452 {
1453     size_t argc = ARGS_SIZE_ONE;
1454     napi_value argv[ARGS_SIZE_ONE] = {nullptr};
1455     napi_value thisVar = nullptr;
1456     NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok, "call failed.", false);
1457     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE, "Wrong argument type", false);
1458     NAPI_BT_RETURN_IF(!ParseInt32(env, profileId, argv[PARAM0]), "ParseInt32 failed", false);
1459     return true;
1460 }
1461 
CheckSetDevicePairingConfirmationParam(napi_env env,napi_callback_info info,std::string & addr,bool & accept)1462 bool CheckSetDevicePairingConfirmationParam(napi_env env, napi_callback_info info, std::string &addr, bool &accept)
1463 {
1464     size_t argc = ARGS_SIZE_TWO;
1465     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
1466     napi_value thisVar = nullptr;
1467     NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok, "call failed.", false);
1468     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Wrong argument type", false);
1469     NAPI_BT_RETURN_IF(!ParseString(env, addr, argv[PARAM0]), "ParseString failed", false);
1470     NAPI_BT_RETURN_IF(!IsValidAddress(addr), "Invalid addr", false);
1471     NAPI_BT_RETURN_IF(!ParseBool(env, accept, argv[PARAM1]), "ParseBool failed", false);
1472     return true;
1473 }
1474 
CheckLocalNameParam(napi_env env,napi_callback_info info,std::string & name)1475 bool CheckLocalNameParam(napi_env env, napi_callback_info info, std::string &name)
1476 {
1477     size_t argc = ARGS_SIZE_ONE;
1478     napi_value argv[ARGS_SIZE_ONE] = {nullptr};
1479     NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr) != napi_ok, "call failed.", false);
1480     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE, "Wrong argument type", false);
1481     NAPI_BT_RETURN_IF(!ParseString(env, name, argv[PARAM0]), "ParseString failed", false);
1482     return true;
1483 }
1484 
CheckSetBluetoothScanModeParam(napi_env env,napi_callback_info info,int32_t & mode,int32_t & duration)1485 bool CheckSetBluetoothScanModeParam(napi_env env, napi_callback_info info, int32_t &mode, int32_t &duration)
1486 {
1487     size_t argc = ARGS_SIZE_TWO;
1488     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
1489     napi_value thisVar = nullptr;
1490     NAPI_BT_RETURN_IF(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok, "call failed.", false);
1491     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Wrong argument type", false);
1492     NAPI_BT_RETURN_IF(!ParseInt32(env, mode, argv[PARAM0]), "ParseInt32 failed", false);
1493     NAPI_BT_RETURN_IF(!ParseInt32(env, duration, argv[PARAM1]), "ParseInt32 failed", false);
1494     return true;
1495 }
1496 
CheckDeregisterObserver(napi_env env,napi_callback_info info)1497 napi_status CheckDeregisterObserver(napi_env env, napi_callback_info info)
1498 {
1499     size_t expectedArgsCount = ARGS_SIZE_TWO;
1500     size_t argc = expectedArgsCount;
1501     napi_value argv[ARGS_SIZE_TWO] = {0};
1502     napi_value thisVar = nullptr;
1503     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1504     if (argc == ARGS_SIZE_ONE) {
1505         std::string type;
1506         NAPI_BT_CALL_RETURN(NapiParseString(env, argv[PARAM0], type));
1507         RemoveObserver(type);
1508     } else if (argc == expectedArgsCount + 1) {
1509         NapiSppClient::Off(env, info);
1510     } else {
1511         NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Requires 2 arguments.", napi_invalid_arg);
1512         std::string type;
1513         NAPI_BT_CALL_RETURN(NapiParseString(env, argv[PARAM0], type));
1514 
1515         std::shared_ptr<BluetoothCallbackInfo> pCallbackInfo = std::make_shared<BluetoothCallbackInfo>();
1516         pCallbackInfo->env_ = env;
1517         NAPI_BT_RETURN_IF(pCallbackInfo == nullptr, "pCallbackInfo is nullptr.", napi_invalid_arg);
1518         NAPI_BT_CALL_RETURN(NapiIsFunction(env, argv[PARAM1]));
1519         NAPI_BT_CALL_RETURN(napi_create_reference(env, argv[PARAM1], 1, &pCallbackInfo->callback_));
1520         if (pCallbackInfo != nullptr) {
1521             napi_value callback = 0;
1522             napi_value undefined = 0;
1523             napi_value callResult = 0;
1524             napi_get_undefined(pCallbackInfo->env_, &undefined);
1525             int32_t typeNum = 0;
1526             if (registerTypeMap.find(type) != registerTypeMap.end()) {
1527                 typeNum = registerTypeMap[type];
1528             }
1529             napi_value result = CallbackObserver(typeNum, pCallbackInfo);
1530             napi_get_reference_value(pCallbackInfo->env_, pCallbackInfo->callback_, &callback);
1531             napi_call_function(pCallbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
1532         }
1533         RemoveObserver(type);
1534     }
1535     return napi_ok;
1536 }
1537 
CheckEmptyParam(napi_env env,napi_callback_info info)1538 napi_status CheckEmptyParam(napi_env env, napi_callback_info info)
1539 {
1540     size_t argc = ARGS_SIZE_ZERO;
1541     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr));
1542     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ZERO, "Requires 0 argument.", napi_invalid_arg);
1543     return napi_ok;
1544 }
1545 
NapiCheckObjectPropertiesName(napi_env env,napi_value object,const std::vector<std::string> & names)1546 napi_status NapiCheckObjectPropertiesName(napi_env env, napi_value object, const std::vector<std::string> &names)
1547 {
1548     uint32_t len = 0;
1549     napi_value properties;
1550     NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
1551     NAPI_BT_CALL_RETURN(napi_get_property_names(env, object, &properties));
1552     NAPI_BT_CALL_RETURN(napi_get_array_length(env, properties, &len));
1553     for (uint32_t i = 0; i < len; ++i) {
1554         std::string name {};
1555         napi_value actualName;
1556         NAPI_BT_CALL_RETURN(napi_get_element(env, properties, i, &actualName));
1557         NAPI_BT_CALL_RETURN(NapiParseString(env, actualName, name));
1558         if (std::find(names.begin(), names.end(), name) == names.end()) {
1559             HILOGE("Unexpect object property name: \"%{public}s\"", name.c_str());
1560             return napi_invalid_arg;
1561         }
1562     }
1563     return napi_ok;
1564 }
1565 
1566 }  // namespace Bluetooth
1567 }  // namespace OHOS
1568