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 #include "napi_bluetooth_ble.h"
16
17 #include "napi_bluetooth_ble_advertise_callback.h"
18 #include "napi_bluetooth_ble_central_manager_callback.h"
19 #include "napi_bluetooth_gatt_client.h"
20 #include "napi_bluetooth_gatt_server.h"
21 #include "napi_bluetooth_utils.h"
22
23 #include "bluetooth_ble_advertiser.h"
24 #include "bluetooth_ble_central_manager.h"
25
26 #include <memory>
27 namespace OHOS {
28 namespace Bluetooth {
29 namespace {
30 struct SysStopBLEContext {
31 napi_async_work work = nullptr;
32 napi_ref callbackSuccess = nullptr;
33 napi_ref callbackFail = nullptr;
34 napi_ref callbackComplete = nullptr;
35 };
36
37 NapiBluetoothBleCentralManagerCallback bleCentralMangerCallback;
38 NapiBluetoothBleAdvertiseCallback bleAdvertiseCallback;
39 BleAdvertiser bleAdvertiser;
40 std::unique_ptr<BleCentralManager> bleCentralManager = std::make_unique<BleCentralManager>(bleCentralMangerCallback);
41
GetPropertyValueByNamed(napi_env env,napi_value object,std::string_view propertyName,napi_valuetype type)42 napi_value GetPropertyValueByNamed(napi_env env, napi_value object, std::string_view propertyName, napi_valuetype type)
43 {
44 napi_value value = nullptr;
45 bool hasProperty = false;
46 napi_valuetype paraType = napi_undefined;
47
48 NAPI_CALL(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty));
49 if (hasProperty) {
50 NAPI_CALL(env, napi_get_named_property(env, object, propertyName.data(), &value));
51 NAPI_CALL(env, napi_typeof(env, value, ¶Type));
52 if (paraType != type) {
53 return NapiGetNull(env);
54 }
55 }
56 return value;
57 }
58
RegisterBLEObserver(napi_env env,napi_value val,int32_t callbackIndex,const std::string & type)59 void RegisterBLEObserver(napi_env env, napi_value val, int32_t callbackIndex, const std::string &type)
60 {
61 std::shared_ptr<BluetoothCallbackInfo> pCallbackInfo = std::make_shared<BluetoothCallbackInfo>();
62 pCallbackInfo->env_ = env;
63 napi_create_reference(env, val, 1, &pCallbackInfo->callback_);
64 RegisterSysBLEObserver(pCallbackInfo, callbackIndex, type);
65 }
ParseScanParameters(napi_env env,napi_value arg,ScanOptions & info)66 bool ParseScanParameters(napi_env env, napi_value arg, ScanOptions &info)
67 {
68 napi_value interval = GetPropertyValueByNamed(env, arg, "interval", napi_number);
69 if (interval) {
70 napi_get_value_int32(env, interval, &info.interval);
71 HILOGI("Scan interval is %{public}d", info.interval);
72 } else {
73 info.interval = 0;
74 }
75
76 std::array<std::string, ARGS_SIZE_THREE> funcArray {"success", "fail", "complete"};
77
78 for (size_t i = 0; i < funcArray.size(); i++) {
79 napi_value value = GetPropertyValueByNamed(env, arg, funcArray[i], napi_function);
80 if (value) {
81 RegisterBLEObserver(env, value, i, REGISTER_SYS_BLE_SCAN_TYPE);
82 } else {
83 UnregisterSysBLEObserver(REGISTER_SYS_BLE_SCAN_TYPE);
84 return false;
85 }
86 }
87 return true;
88 }
SysStartBLEScan(napi_env env,napi_callback_info info)89 napi_value SysStartBLEScan(napi_env env, napi_callback_info info)
90 {
91 size_t argc = ARGS_SIZE_ONE;
92 napi_value argv[] = {nullptr};
93 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
94 if (argc != 1) {
95 return NapiGetNull(env);
96 }
97
98 napi_valuetype valueType = napi_undefined;
99 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valueType));
100 if (valueType != napi_object) {
101 return NapiGetNull(env);
102 }
103 ScanOptions scanOptions;
104 if (!ParseScanParameters(env, argv[PARAM0], scanOptions)) {
105 HILOGE("SysStartBLEScan Input parameter parsing failed!");
106 return NapiGetNull(env);
107 }
108
109 BleScanSettings settinngs;
110 settinngs.SetReportDelay(scanOptions.interval);
111 settinngs.SetScanMode(static_cast<int32_t>(scanOptions.dutyMode));
112
113 bleCentralManager->StartScan(settinngs);
114 return NapiGetNull(env);
115 }
SysStopBLEScanExec(napi_env env,void * data)116 void SysStopBLEScanExec(napi_env env, void *data)
117 {
118 HILOGI("SysStopBLEScanExec");
119 bleCentralManager->StopScan();
120 UnregisterSysBLEObserver(REGISTER_SYS_BLE_SCAN_TYPE);
121 }
SysStopBLEScanComplete(napi_env env,napi_status status,void * data)122 void SysStopBLEScanComplete(napi_env env, napi_status status, void *data)
123 {
124 NAPI_CALL_RETURN_VOID(env, (data == nullptr ? napi_invalid_arg : napi_ok));
125 std::unique_ptr<SysStopBLEContext> context(static_cast<SysStopBLEContext *>(data));
126
127 napi_value undefine = nullptr;
128 NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefine));
129 napi_value funcComplete = nullptr;
130 napi_value funcSuccess = nullptr;
131 napi_value callbackResult = nullptr;
132 NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, context->callbackSuccess, &funcSuccess));
133 NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefine, funcSuccess, 0, nullptr, &callbackResult));
134 NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, context->callbackComplete, &funcComplete));
135 NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefine, funcComplete, 0, nullptr, &callbackResult));
136 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, context->callbackSuccess));
137 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, context->callbackComplete));
138 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, context->callbackFail));
139 NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, context->work));
140 HILOGI("SysStopBLEScanComplete end");
141 }
SysStopBLEScan(napi_env env,napi_callback_info info)142 napi_value SysStopBLEScan(napi_env env, napi_callback_info info)
143 {
144 size_t argc = ARGS_SIZE_ONE;
145 napi_value argv[] = {nullptr};
146 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
147 if (argc != 1) {
148 return NapiGetNull(env);
149 }
150
151 napi_valuetype valueType = napi_undefined;
152 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valueType));
153 if (valueType != napi_object) {
154 return NapiGetNull(env);
155 }
156
157 std::unique_ptr<SysStopBLEContext> context = std::make_unique<SysStopBLEContext>();
158
159 std::array<std::string, ARGS_SIZE_THREE> funcArray {"success", "fail", "complete"};
160 for (size_t i = 0; i < funcArray.size(); i++) {
161 napi_value value = GetPropertyValueByNamed(env, argv[PARAM0], funcArray[i], napi_function);
162 if (value) {
163 napi_create_reference(env, value, 1,
164 &(i == PARAM0 ? context->callbackSuccess :
165 (i == PARAM1 ? context->callbackFail : context->callbackComplete)));
166 } else {
167 HILOGE("SysStopBLEScan Input parameter parsing failed!");
168 return NapiGetNull(env);
169 }
170 }
171 napi_value resourceName = nullptr;
172 NAPI_CALL(env, napi_create_string_utf8(env, "SysStopBLEScan", NAPI_AUTO_LENGTH, &resourceName));
173 SysStopBLEContext *pContext = context.release();
174 napi_status status = napi_create_async_work(env, nullptr, resourceName, SysStopBLEScanExec,
175 SysStopBLEScanComplete, static_cast<void *>(pContext), &pContext->work);
176 if (status != napi_ok) {
177 delete pContext;
178 }
179
180 if (napi_queue_async_work(env, pContext->work) != napi_ok) {
181 delete pContext;
182 }
183 return NapiGetNull(env);
184 }
ParseDeviceFoundParameters(napi_env env,napi_value arg)185 bool ParseDeviceFoundParameters(napi_env env, napi_value arg)
186 {
187 std::array<std::string, ARGS_SIZE_TWO> funcArray {"success", "fail"};
188
189 for (size_t i = 0; i < funcArray.size(); i++) {
190 napi_value value = GetPropertyValueByNamed(env, arg, funcArray[i], napi_function);
191 if (value) {
192 RegisterBLEObserver(env, value, i, REGISTER_SYS_BLE_FIND_DEVICE_TYPE);
193 } else {
194 UnregisterSysBLEObserver(REGISTER_SYS_BLE_FIND_DEVICE_TYPE);
195 return false;
196 }
197 }
198 return true;
199 }
SysSubscribeBLEFound(napi_env env,napi_callback_info info)200 napi_value SysSubscribeBLEFound(napi_env env, napi_callback_info info)
201 {
202 size_t argc = ARGS_SIZE_ONE;
203 napi_value argv[] = {nullptr};
204 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
205 if (argc != 1) {
206 return NapiGetNull(env);
207 }
208
209 napi_valuetype valueType = napi_undefined;
210 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valueType));
211 if (valueType != napi_object) {
212 return NapiGetNull(env);
213 }
214 if (!ParseDeviceFoundParameters(env, argv[PARAM0])) {
215 HILOGE("SysSubscribeBLEFound Input parameter parsing failed!");
216 }
217 return NapiGetNull(env);
218 }
SysUnsubscribeBLEFound(napi_env env,napi_callback_info info)219 napi_value SysUnsubscribeBLEFound(napi_env env, napi_callback_info info)
220 {
221 UnregisterSysBLEObserver(REGISTER_SYS_BLE_FIND_DEVICE_TYPE);
222 return NapiGetNull(env);
223 }
224 } // namespace
225
DefineSystemBLEInterface(napi_env env,napi_value exports)226 void DefineSystemBLEInterface(napi_env env, napi_value exports)
227 {
228 napi_property_descriptor desc[] = {
229 DECLARE_NAPI_FUNCTION("startBLEScan", SysStartBLEScan),
230 DECLARE_NAPI_FUNCTION("stopBLEScan", SysStopBLEScan),
231 DECLARE_NAPI_FUNCTION("subscribeBLEFound", SysSubscribeBLEFound),
232 DECLARE_NAPI_FUNCTION("unsubscribeBLEFound", SysUnsubscribeBLEFound),
233 };
234 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
235 HILOGI("DefineSystemBLEInterface init");
236 }
DefineBLEJSObject(napi_env env,napi_value exports)237 void DefineBLEJSObject(napi_env env, napi_value exports)
238 {
239 HILOGI("DefineBLEJSObject start");
240 napi_value BLEObject = nullptr;
241 PropertyInit(env, exports);
242 napi_property_descriptor desc[] = {
243 DECLARE_NAPI_FUNCTION("createGattServer", NapiGattServer::CreateGattServer),
244 DECLARE_NAPI_FUNCTION("createGattClientDevice", NapiGattClient::CreateGattClientDevice),
245 DECLARE_NAPI_FUNCTION("startBLEScan", StartBLEScan),
246 DECLARE_NAPI_FUNCTION("stopBLEScan", StopBLEScan),
247 DECLARE_NAPI_FUNCTION("on", RegisterObserver),
248 DECLARE_NAPI_FUNCTION("off", DeregisterObserver),
249 DECLARE_NAPI_FUNCTION("getConnectedBLEDevices", GetConnectedBLEDevices),
250 };
251
252 napi_create_object(env, &BLEObject);
253 napi_define_properties(env, BLEObject, sizeof(desc) / sizeof(desc[0]), desc);
254 napi_set_named_property(env, exports, "BLE", BLEObject);
255 HILOGI("DefineBLEJSObject end");
256 }
257
ConvertMatchMode(ScanOptions & params,int32_t matchMode)258 static void ConvertMatchMode(ScanOptions ¶ms, int32_t matchMode)
259 {
260 switch (matchMode) {
261 case MatchMode::MATCH_MODE_AGGRESSIVE:
262 params.MatchMode = MatchMode::MATCH_MODE_AGGRESSIVE;
263 break;
264 case MatchMode::MATCH_MODE_STICKY:
265 params.MatchMode = MatchMode::MATCH_MODE_STICKY;
266 break;
267 default:
268 break;
269 }
270 }
271
ConvertDutyMode(ScanOptions & params,int32_t dutyMode)272 static void ConvertDutyMode(ScanOptions ¶ms, int32_t dutyMode)
273 {
274 switch (dutyMode) {
275 case static_cast<int32_t>(ScanDuty::SCAN_MODE_LOW_POWER):
276 params.dutyMode = ScanDuty::SCAN_MODE_LOW_POWER;
277 break;
278 case static_cast<int32_t>(ScanDuty::SCAN_MODE_BALANCED):
279 params.dutyMode = ScanDuty::SCAN_MODE_BALANCED;
280 break;
281 case static_cast<int32_t>(ScanDuty::SCAN_MODE_LOW_LATENCY):
282 params.dutyMode = ScanDuty::SCAN_MODE_LOW_LATENCY;
283 break;
284 default:
285 break;
286 }
287 }
288
ParseScanParameters(const napi_env & env,const napi_callback_info & info,const napi_value & scanArg,ScanOptions & params)289 static napi_value ParseScanParameters(
290 const napi_env &env, const napi_callback_info &info, const napi_value &scanArg, ScanOptions ¶ms)
291 {
292 size_t argc = ARGS_SIZE_THREE;
293 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
294 napi_value thisVar = nullptr;
295 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
296 if (argc == 0) {
297 return NapiGetNull(env);
298 }
299
300 bool hasProperty = false;
301 napi_valuetype valuetype = napi_undefined;
302 napi_value result = nullptr;
303
304 NAPI_CALL(env, napi_has_named_property(env, scanArg, "interval", &hasProperty));
305 if (hasProperty) {
306 napi_get_named_property(env, scanArg, "interval", &result);
307 NAPI_CALL(env, napi_typeof(env, result, &valuetype));
308 NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
309 napi_get_value_int32(env, result, ¶ms.interval);
310 HILOGD("StartBLEScan interval is %{public}d", params.interval);
311 }
312
313 NAPI_CALL(env, napi_has_named_property(env, scanArg, "dutyMode", &hasProperty));
314 if (hasProperty) {
315 napi_get_named_property(env, scanArg, "dutyMode", &result);
316 NAPI_CALL(env, napi_typeof(env, result, &valuetype));
317 NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
318 int32_t dutyMode = 0;
319 napi_get_value_int32(env, result, &dutyMode);
320 HILOGD("StartBLEScan dutyMode is %{public}d", dutyMode);
321 ConvertDutyMode(params, dutyMode);
322 }
323
324 NAPI_CALL(env, napi_has_named_property(env, scanArg, "matchMode", &hasProperty));
325 if (hasProperty) {
326 napi_get_named_property(env, scanArg, "matchMode", &result);
327 NAPI_CALL(env, napi_typeof(env, result, &valuetype));
328 NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
329 int32_t matchMode = -1;
330 napi_get_value_int32(env, result, &matchMode);
331 HILOGD("StartBLEScan matchMode is %{public}d", matchMode);
332 ConvertMatchMode(params, matchMode);
333 }
334 return NapiGetNull(env);
335 }
336
ParseScanFilterParameters(const napi_env & env,napi_value & args)337 static napi_value ParseScanFilterParameters(const napi_env &env, napi_value &args)
338 {
339 if (args == nullptr) {
340 return NapiGetNull(env);
341 }
342
343 bool isArray = false;
344 napi_is_array(env, args, &isArray);
345 if (isArray) {
346 uint32_t length = 0;
347 napi_get_array_length(env, args, &length);
348 for (size_t i = 0; i < length; ++i) {
349 napi_value scanFilter;
350 napi_value result;
351 napi_valuetype valuetype = napi_undefined;
352 napi_get_element(env, args, i, &scanFilter);
353 NAPI_CALL(env, napi_typeof(env, scanFilter, &valuetype));
354 NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected.");
355 bool hasProperty = false;
356 NAPI_CALL(env, napi_has_named_property(env, scanFilter, "deviceId", &hasProperty));
357 if (hasProperty) {
358 napi_get_named_property(env, scanFilter, "deviceId", &result);
359 std::string deviceId;
360 ParseString(env, deviceId, result);
361 HILOGD("ParseScanFilterParameters::deviceId = %{public}s", deviceId.c_str());
362 }
363
364 NAPI_CALL(env, napi_has_named_property(env, scanFilter, "name", &hasProperty));
365 if (hasProperty) {
366 napi_get_named_property(env, scanFilter, "name", &result);
367 std::string name;
368 ParseString(env, name, result);
369 HILOGD("ParseScanFilterParameters::name = %{public}s", name.c_str());
370 }
371
372 NAPI_CALL(env, napi_has_named_property(env, scanFilter, "serviceUuid", &hasProperty));
373 if (hasProperty) {
374 napi_get_named_property(env, scanFilter, "serviceUuid", &result);
375 std::string serviceUuid;
376 ParseString(env, serviceUuid, result);
377 HILOGD("ParseScanFilterParameters::serviceUuid = %{public}s", serviceUuid.c_str());
378 }
379 }
380 }
381
382 return NapiGetNull(env);
383 }
384
StartBLEScan(napi_env env,napi_callback_info info)385 napi_value StartBLEScan(napi_env env, napi_callback_info info)
386 {
387 HILOGI("StartBLEScan start");
388 size_t argc = ARGS_SIZE_TWO;
389 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
390 napi_value thisVar = nullptr;
391 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
392 if (argc == 0) {
393 return NapiGetNull(env);
394 }
395
396 ParseScanFilterParameters(env, argv[PARAM0]);
397
398 BleScanSettings settinngs;
399 if (argv[PARAM1] != nullptr) {
400 ScanOptions scanOptions;
401 ParseScanParameters(env, info, argv[PARAM1], scanOptions);
402 settinngs.SetReportDelay(scanOptions.interval);
403 settinngs.SetScanMode(static_cast<int32_t>(scanOptions.dutyMode));
404 }
405
406 bleCentralManager->StartScan(settinngs);
407 HILOGI("StartBLEScan end");
408 return NapiGetNull(env);
409 }
410
StopBLEScan(napi_env env,napi_callback_info info)411 napi_value StopBLEScan(napi_env env, napi_callback_info info)
412 {
413 HILOGI("StopBLEScan start");
414 bleCentralManager->StopScan();
415 HILOGI("StopBLEScan end");
416 return NapiGetNull(env);
417 }
418
ParseAdvertisingSettingsParameters(const napi_env & env,const napi_callback_info & info,const napi_value & args,BleAdvertiserSettings & settings)419 static napi_value ParseAdvertisingSettingsParameters(
420 const napi_env &env, const napi_callback_info &info, const napi_value &args, BleAdvertiserSettings &settings)
421 {
422 HILOGI("ParseAdvertisingSettingsParameters start");
423 bool hasProperty = false;
424 napi_valuetype valuetype = napi_undefined;
425 napi_value result = nullptr;
426
427 NAPI_CALL(env, napi_has_named_property(env, args, "interval", &hasProperty));
428 if (hasProperty) {
429 napi_get_named_property(env, args, "interval", &result);
430 NAPI_CALL(env, napi_typeof(env, result, &valuetype));
431 NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
432 int32_t interval = 0;
433 napi_get_value_int32(env, result, &interval);
434 HILOGD("ParseAdvertisingSettingsParameters interval is %{public}d", interval);
435 settings.SetInterval(interval);
436 }
437 NAPI_CALL(env, napi_has_named_property(env, args, "txPower", &hasProperty));
438 if (hasProperty) {
439 napi_get_named_property(env, args, "txPower", &result);
440 NAPI_CALL(env, napi_typeof(env, result, &valuetype));
441 NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
442 int32_t txPower = 0;
443 napi_get_value_int32(env, result, &txPower);
444 HILOGD("ParseAdvertisingSettingsParameters txPower is %{public}d", txPower);
445 settings.SetTxPower(txPower);
446 }
447
448 NAPI_CALL(env, napi_has_named_property(env, args, "connectable", &hasProperty));
449 if (hasProperty) {
450 napi_get_named_property(env, args, "connectable", &result);
451 NAPI_CALL(env, napi_typeof(env, result, &valuetype));
452 NAPI_ASSERT(env, valuetype == napi_boolean, "Wrong argument type. Boolean expected.");
453 bool connectable = true;
454 napi_get_value_bool(env, result, &connectable);
455 HILOGD("ParseAdvertisingSettingsParameters connectable is %{public}d", connectable);
456 settings.SetConnectable(connectable);
457 }
458 HILOGI("ParseAdvertisingSettingsParameters end");
459 return NapiGetNull(env);
460 }
461
ParseServiceUuidParameters(const napi_env & env,const napi_value & args,BleAdvertiserData & data)462 static napi_value ParseServiceUuidParameters(const napi_env &env, const napi_value &args, BleAdvertiserData &data)
463 {
464 HILOGI("ParseServiceUuidParameters start");
465 napi_value result = nullptr;
466
467 napi_get_named_property(env, args, "serviceUuids", &result);
468 bool isArray = false;
469 napi_is_array(env, result, &isArray);
470 NAPI_ASSERT(env, isArray, "Wrong argument type. Array expected.");
471 uint32_t length = 0;
472 napi_get_array_length(env, result, &length);
473 NAPI_ASSERT(env, length > 0, "The array is empty.");
474 for (size_t serviceUuidIter = 0; serviceUuidIter < length; ++serviceUuidIter) {
475 napi_value uuid = nullptr;
476 napi_get_element(env, result, serviceUuidIter, &uuid);
477 std::string serviceUuid;
478 ParseString(env, serviceUuid, uuid);
479 data.AddServiceUuid(ParcelUuid::FromString(serviceUuid));
480 HILOGD("Service Uuid = %{public}s", serviceUuid.c_str());
481 }
482 HILOGI("ParseServiceUuidParameters end");
483 return NapiGetNull(env);
484 }
485
ParseManufactureDataParameters(const napi_env & env,const napi_value & args,BleAdvertiserData & data)486 static napi_value ParseManufactureDataParameters(const napi_env &env, const napi_value &args, BleAdvertiserData &data)
487 {
488 HILOGI("ParseManufactureDataParameters start");
489 napi_value result = nullptr;
490
491 napi_get_named_property(env, args, "manufactureData", &result);
492 bool isArray = false;
493 napi_is_array(env, result, &isArray);
494 NAPI_ASSERT(env, isArray, "Wrong argument type. Array expected.");
495 uint32_t length = 0;
496 napi_get_array_length(env, result, &length);
497 if (length == 0) {
498 HILOGE("ParseManufactureDataParameters,The array is empty.");
499 return NapiGetNull(env);
500 }
501 for (size_t manufactureDataIter = 0; manufactureDataIter < length; ++manufactureDataIter) {
502 napi_value manufactureData = nullptr;
503 napi_valuetype valuetype = napi_undefined;
504 napi_get_element(env, result, manufactureDataIter, &manufactureData);
505 NAPI_CALL(env, napi_typeof(env, manufactureData, &valuetype));
506 NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected.");
507 bool hasProperty = false;
508 NAPI_CALL(env, napi_has_named_property(env, manufactureData, "manufactureId", &hasProperty));
509 NAPI_ASSERT(env, hasProperty, "manufactureId expected.");
510 napi_get_named_property(env, manufactureData, "manufactureId", &result);
511 NAPI_CALL(env, napi_typeof(env, result, &valuetype));
512 NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
513 int32_t manufactureId = 0;
514 napi_get_value_int32(env, result, &manufactureId);
515 HILOGD("ParseManufactureDataParameters::manufactureId = %{public}d", manufactureId);
516 NAPI_CALL(env, napi_has_named_property(env, manufactureData, "manufactureValue", &hasProperty));
517 NAPI_ASSERT(env, hasProperty, "manufactureValue expected.");
518 napi_get_named_property(env, manufactureData, "manufactureValue", &result);
519 bool isArrayBuffer = false;
520 napi_is_arraybuffer(env, result, &isArrayBuffer);
521 if (isArrayBuffer) {
522 uint8_t *arrayBufferData = nullptr;
523 size_t arrayBufferTotal = 0;
524 ParseArrayBuffer(env, &arrayBufferData, arrayBufferTotal, result);
525 std::string manuData(arrayBufferData, arrayBufferData + arrayBufferTotal);
526 data.AddManufacturerData(manufactureId, manuData);
527 }
528 }
529 HILOGI("ParseManufactureDataParameters end");
530 return NapiGetNull(env);
531 }
532
ParseServiceDataParameters(const napi_env & env,const napi_value & args,BleAdvertiserData & data)533 static napi_value ParseServiceDataParameters(const napi_env &env, const napi_value &args, BleAdvertiserData &data)
534 {
535 HILOGI("ParseServiceDataParameters start");
536 napi_valuetype valuetype = napi_undefined;
537 napi_value result = nullptr;
538 napi_get_named_property(env, args, "serviceData", &result);
539 bool isArray = false;
540 napi_is_array(env, result, &isArray);
541 NAPI_ASSERT(env, isArray, "Wrong argument type. Array expected.");
542 uint32_t length = 0;
543 napi_get_array_length(env, result, &length);
544 if (length == 0) {
545 HILOGE("ParseServiceDataParameters,The array is empty.");
546 return NapiGetNull(env);
547 }
548 for (size_t serviceDataIter = 0; serviceDataIter < length; ++serviceDataIter) {
549 napi_value serviceData = nullptr;
550 napi_get_element(env, result, serviceDataIter, &serviceData);
551 NAPI_CALL(env, napi_typeof(env, serviceData, &valuetype));
552 NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected.");
553 bool hasProperty = false;
554 NAPI_CALL(env, napi_has_named_property(env, serviceData, "serviceUuid", &hasProperty));
555 NAPI_ASSERT(env, hasProperty, "serviceUuid expected.");
556 napi_get_named_property(env, serviceData, "serviceUuid", &result);
557 std::string serviceBuffer;
558 ParseString(env, serviceBuffer, result);
559 ParcelUuid serviceUuid(ParcelUuid::FromString(serviceBuffer));
560 HILOGD("ParseManufactureDataParameters::serviceUuid = %{public}s", serviceUuid.ToString().c_str());
561
562 NAPI_CALL(env, napi_has_named_property(env, serviceData, "serviceValue", &hasProperty));
563 NAPI_ASSERT(env, hasProperty, "serviceValue expected.");
564 napi_get_named_property(env, serviceData, "serviceValue", &result);
565 bool isArrayBuffer = false;
566 napi_is_arraybuffer(env, result, &isArrayBuffer);
567 NAPI_ASSERT(env, isArrayBuffer, "Array buffer expected.");
568 uint8_t *arrayBufferData;
569 size_t arrayBufferTotal;
570 napi_get_arraybuffer_info(env, result, reinterpret_cast<void **>(&arrayBufferData), &arrayBufferTotal);
571 std::string serviceDataStr(arrayBufferData, arrayBufferData + arrayBufferTotal);
572 data.AddServiceData(serviceUuid, serviceDataStr);
573 }
574 HILOGI("ParseServiceDataParameters end");
575 return NapiGetNull(env);
576 }
577
ParseAdvertisDataParameters(const napi_env & env,const napi_callback_info & info,const napi_value & args,BleAdvertiserData & data)578 static napi_value ParseAdvertisDataParameters(
579 const napi_env &env, const napi_callback_info &info, const napi_value &args, BleAdvertiserData &data)
580 {
581 HILOGI("ParseAdvertisDataParameters start");
582 bool hasProperty = false;
583 NAPI_CALL(env, napi_has_named_property(env, args, "serviceUuids", &hasProperty));
584 if (hasProperty) {
585 ParseServiceUuidParameters(env, args, data);
586 }
587 NAPI_CALL(env, napi_has_named_property(env, args, "manufactureData", &hasProperty));
588 if (hasProperty) {
589 ParseManufactureDataParameters(env, args, data);
590 }
591 NAPI_CALL(env, napi_has_named_property(env, args, "serviceData", &hasProperty));
592 if (hasProperty) {
593 ParseServiceDataParameters(env, args, data);
594 }
595 HILOGI("ParseAdvertisDataParameters end");
596 return NapiGetNull(env);
597 }
598
StartAdvertising(napi_env env,napi_callback_info info)599 napi_value StartAdvertising(napi_env env, napi_callback_info info)
600 {
601 HILOGI("StartAdvertising start");
602 size_t argc = ARGS_SIZE_THREE;
603 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
604 napi_value thisVar = nullptr;
605 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
606 if (argc == 0) {
607 return NapiGetNull(env);
608 }
609 BleAdvertiserSettings settings;
610 ParseAdvertisingSettingsParameters(env, info, argv[PARAM0], settings);
611 BleAdvertiserData AdvData;
612 ParseAdvertisDataParameters(env, info, argv[PARAM1], AdvData);
613 BleAdvertiserData ScanRespData;
614 if (argv[PARAM2] != nullptr) {
615 ParseAdvertisDataParameters(env, info, argv[PARAM2], ScanRespData);
616 }
617
618 bleAdvertiser.StartAdvertising(settings, AdvData, ScanRespData, bleAdvertiseCallback);
619 HILOGI("StartAdvertising end");
620 return NapiGetNull(env);
621 }
622
StopAdvertising(napi_env env,napi_callback_info info)623 napi_value StopAdvertising(napi_env env, napi_callback_info info)
624 {
625 HILOGI("StopAdvertising start");
626 bleAdvertiser.StopAdvertising(bleAdvertiseCallback);
627 HILOGI("StopAdvertising end");
628 return NapiGetNull(env);
629 }
630
GetConnectedBLEDevices(napi_env env,napi_callback_info info)631 napi_value GetConnectedBLEDevices(napi_env env, napi_callback_info info)
632 {
633 HILOGI("GetConnectedBLEDevices start");
634 napi_value result = nullptr;
635 napi_create_array(env, &result);
636
637 ConvertStringVectorToJS(env, result, NapiGattServer::deviceList);
638 HILOGI("GetConnectedBLEDevices end");
639 return result;
640 }
641
PropertyInit(napi_env env,napi_value exports)642 napi_value PropertyInit(napi_env env, napi_value exports)
643 {
644 HILOGI("%{public}s, enter", __func__);
645
646 napi_value matchModeObj = nullptr;
647 napi_value scanDutyObj = nullptr;
648 napi_create_object(env, &matchModeObj);
649 napi_create_object(env, &scanDutyObj);
650
651 SetNamedPropertyByInteger(env, matchModeObj, MatchMode::MATCH_MODE_STICKY, "MATCH_MODE_STICKY");
652 SetNamedPropertyByInteger(env, matchModeObj, MatchMode::MATCH_MODE_AGGRESSIVE, "MATCH_MODE_AGGRESSIVE");
653 SetNamedPropertyByInteger(
654 env, scanDutyObj, static_cast<int32_t>(ScanDuty::SCAN_MODE_BALANCED), "SCAN_MODE_BALANCED");
655 SetNamedPropertyByInteger(
656 env, scanDutyObj, static_cast<int32_t>(ScanDuty::SCAN_MODE_LOW_LATENCY), "SCAN_MODE_LOW_LATENCY");
657 SetNamedPropertyByInteger(
658 env, scanDutyObj, static_cast<int32_t>(ScanDuty::SCAN_MODE_LOW_POWER), "SCAN_MODE_LOW_POWER");
659
660 napi_property_descriptor exportFuncs[] = {
661 DECLARE_NAPI_PROPERTY("MatchMode", matchModeObj),
662 DECLARE_NAPI_PROPERTY("ScanDuty", scanDutyObj),
663 };
664
665 napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
666 return exports;
667 }
668 } // namespace Bluetooth
669 } // namespace OHOS