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 ¶m, 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 ¶m, 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, ¶m);
91 return true;
92 }
93
ParseBool(napi_env env,bool & param,napi_value args)94 bool ParseBool(napi_env env, bool ¶m, 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, ¶m);
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(), ¤tBytes);
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, ¶m));
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