• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #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, &paraType));
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 &params, 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 &params, 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 &params)
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, &params.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