• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_bluetooth_connection.h"
17 
18 #include <set>
19 
20 #include "napi_bluetooth_connection_observer.h"
21 #include "napi_bluetooth_remote_device_observer.h"
22 #include "bluetooth_log.h"
23 #include "bluetooth_errorcode.h"
24 #include "napi_bluetooth_error.h"
25 #include "napi_async_work.h"
26 #include "napi_bluetooth_utils.h"
27 #include "parser/napi_parser_utils.h"
28 
29 namespace OHOS {
30 namespace Bluetooth {
31 NapiBluetoothConnectionObserver g_connectionObserver;
32 std::shared_ptr<NapiBluetoothRemoteDeviceObserver> g_remoteDeviceObserver;
33 std::mutex deviceMutex;
34 std::vector<std::shared_ptr<BluetoothRemoteDevice>> g_DiscoveryDevices;
35 std::set<std::string> g_supportRegisterFunc = {
36     REGISTER_DEVICE_FIND_TYPE, REGISTER_PIN_REQUEST_TYPE, REGISTER_BOND_STATE_TYPE};
37 
38 std::map<std::string, std::function<napi_value(napi_env env)>> g_callbackDefaultValue = {
39     {REGISTER_DEVICE_FIND_TYPE,
__anon23a4181e0102() 40         [](napi_env env) -> napi_value {
41             napi_value result = 0;
42             napi_value value = 0;
43             napi_create_array(env, &result);
44             napi_create_string_utf8(env, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &value);
45             napi_set_element(env, result, 0, value);
46             return result;
47         }},
48     {REGISTER_PIN_REQUEST_TYPE,
__anon23a4181e0202() 49         [](napi_env env) -> napi_value {
50             napi_value result = 0;
51             napi_value deviceId = nullptr;
52             napi_value pinCode = nullptr;
53             napi_create_object(env, &result);
54             napi_create_string_utf8(env, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &deviceId);
55             napi_set_named_property(env, result, "deviceId", deviceId);
56             napi_create_string_utf8(env, INVALID_PIN_CODE.c_str(), NAPI_AUTO_LENGTH, &pinCode);
57             napi_set_named_property(env, result, "pinCode", pinCode);
58             return result;
59         }},
__anon23a4181e0302() 60     {REGISTER_BOND_STATE_TYPE, [](napi_env env) -> napi_value {
61          napi_value result = 0;
62          napi_value deviceId = nullptr;
63          napi_value state = nullptr;
64          napi_create_object(env, &result);
65          napi_create_string_utf8(env, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &deviceId);
66          napi_set_named_property(env, result, "deviceId", deviceId);
67          napi_create_int32(env, static_cast<int32_t>(BondState::BOND_STATE_INVALID), &state);
68          napi_set_named_property(env, result, "state", state);
69          return result;
70      }}};
71 
DefineConnectionFunctions(napi_env env,napi_value exports)72 napi_value DefineConnectionFunctions(napi_env env, napi_value exports)
73 {
74     HILOGI("start");
75     RegisterObserverToHost();
76     ConnectionPropertyValueInit(env, exports);
77     napi_property_descriptor desc[] = {
78         DECLARE_NAPI_FUNCTION("getBtConnectionState", GetBtConnectionState),
79 #ifdef BLUETOOTH_API_SINCE_10
80         DECLARE_NAPI_FUNCTION("pairDevice", PairDeviceAsync),
81         DECLARE_NAPI_FUNCTION("cancelPairedDevice", CancelPairedDeviceAsync),
82 #else
83         DECLARE_NAPI_FUNCTION("pairDevice", PairDevice),
84         DECLARE_NAPI_FUNCTION("cancelPairedDevice", CancelPairedDevice),
85 #endif
86         DECLARE_NAPI_FUNCTION("getRemoteDeviceName", GetRemoteDeviceName),
87         DECLARE_NAPI_FUNCTION("getRemoteDeviceClass", GetRemoteDeviceClass),
88         DECLARE_NAPI_FUNCTION("getLocalName", GetLocalName),
89         DECLARE_NAPI_FUNCTION("getPairedDevices", GetPairedDevices),
90         DECLARE_NAPI_FUNCTION("getProfileConnState", GetProfileConnectionState),
91         DECLARE_NAPI_FUNCTION("getProfileConnectionState", GetProfileConnectionState),
92         DECLARE_NAPI_FUNCTION("setDevicePairingConfirmation", SetDevicePairingConfirmation),
93         DECLARE_NAPI_FUNCTION("setLocalName", SetLocalName),
94         DECLARE_NAPI_FUNCTION("setBluetoothScanMode", SetBluetoothScanMode),
95         DECLARE_NAPI_FUNCTION("getBluetoothScanMode", GetBluetoothScanMode),
96         DECLARE_NAPI_FUNCTION("startBluetoothDiscovery", StartBluetoothDiscovery),
97         DECLARE_NAPI_FUNCTION("stopBluetoothDiscovery", StopBluetoothDiscovery),
98 #ifdef BLUETOOTH_API_SINCE_10
99         DECLARE_NAPI_FUNCTION("setDevicePinCode", SetDevicePinCode),
100         DECLARE_NAPI_FUNCTION("cancelPairingDevice", CancelPairingDevice),
101         DECLARE_NAPI_FUNCTION("pairCredibleDevice", PairCredibleDevice),
102         DECLARE_NAPI_FUNCTION("getLocalProfileUuids", GetLocalProfileUuids),
103         DECLARE_NAPI_FUNCTION("getRemoteProfileUuids", GetRemoteProfileUuids),
104         DECLARE_NAPI_FUNCTION("on", RegisterConnectionObserver),
105         DECLARE_NAPI_FUNCTION("off", DeRegisterConnectionObserver),
106 #endif
107     };
108 
109     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
110     return exports;
111 }
112 
CheckRegisterObserver(napi_env env,napi_callback_info info)113 napi_status CheckRegisterObserver(napi_env env, napi_callback_info info)
114 {
115     size_t argc = ARGS_SIZE_TWO;
116     napi_value argv[ARGS_SIZE_TWO] = {0};
117     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
118     HILOGI("argc: %{public}zu", argc);
119     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Requires 2 arguments.", napi_invalid_arg);
120 
121     std::string callbackName;
122     bool ok = ParseString(env, callbackName, argv[PARAM0]);
123     if (!ok) {
124         return napi_invalid_arg;
125     }
126     if (!g_supportRegisterFunc.count(callbackName)) {
127         HILOGE("not support %{public}s.", callbackName.c_str());
128         return napi_invalid_arg;
129     }
130     NAPI_BT_CALL_RETURN(NapiIsFunction(env, argv[PARAM1]));
131 
132     std::shared_ptr<BluetoothCallbackInfo> callbackInfo = std::make_shared<BluetoothCallbackInfo>();
133     NAPI_BT_CALL_RETURN(napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_));
134     callbackInfo->env_ = env;
135     if (callbackName == REGISTER_BOND_STATE_TYPE) {
136         g_remoteDeviceObserver->RegisterCallback(callbackName, callbackInfo);
137     } else {
138         g_connectionObserver.RegisterCallback(callbackName, callbackInfo);
139     }
140     return napi_ok;
141 }
142 
CheckDeRegisterObserver(napi_env env,napi_callback_info info)143 napi_status CheckDeRegisterObserver(napi_env env, napi_callback_info info)
144 {
145     size_t argc = ARGS_SIZE_TWO;
146     napi_value argv[ARGS_SIZE_TWO] = {0};
147     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
148     NAPI_BT_RETURN_IF(argc < ARGS_SIZE_ONE, "Requires 1 arguments at least.", napi_invalid_arg);
149 
150     std::string callbackName;
151     bool ok = ParseString(env, callbackName, argv[PARAM0]);
152     if (!ok) {
153         return napi_invalid_arg;
154     }
155 
156     if (!g_supportRegisterFunc.count(callbackName)) {
157         HILOGE("not support %{public}s.", callbackName.c_str());
158         return napi_invalid_arg;
159     }
160 
161     if (argc == ARGS_SIZE_ONE) {
162     } else if (argc == ARGS_SIZE_TWO) {
163         NAPI_BT_CALL_RETURN(NapiIsFunction(env, argv[PARAM1]));
164         std::shared_ptr<BluetoothCallbackInfo> callbackInfo = std::make_shared<BluetoothCallbackInfo>();
165         NAPI_BT_CALL_RETURN(napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_));
166         callbackInfo->env_ = env;
167 
168         napi_value callback = 0;
169         napi_value undefined = 0;
170         napi_value callResult = 0;
171         napi_get_undefined(callbackInfo->env_, &undefined);
172 
173         napi_value result = g_callbackDefaultValue[callbackName](env);
174         napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback);
175         napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
176     } else {
177         return napi_invalid_arg;
178     }
179 
180     if (callbackName == REGISTER_BOND_STATE_TYPE) {
181         g_remoteDeviceObserver->DeRegisterCallback(callbackName);
182     } else {
183         g_connectionObserver.DeRegisterCallback(callbackName);
184     }
185     return napi_ok;
186 }
187 
RegisterConnectionObserver(napi_env env,napi_callback_info info)188 napi_value RegisterConnectionObserver(napi_env env, napi_callback_info info)
189 {
190     HILOGI("enter");
191     auto status = CheckRegisterObserver(env, info);
192     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
193 
194     napi_value ret = nullptr;
195     napi_get_undefined(env, &ret);
196     return ret;
197 }
198 
DeRegisterConnectionObserver(napi_env env,napi_callback_info info)199 napi_value DeRegisterConnectionObserver(napi_env env, napi_callback_info info)
200 {
201     HILOGI("enter");
202     auto status = CheckDeRegisterObserver(env, info);
203     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
204 
205     napi_value ret = nullptr;
206     napi_get_undefined(env, &ret);
207     return ret;
208 }
209 
GetBtConnectionState(napi_env env,napi_callback_info info)210 napi_value GetBtConnectionState(napi_env env, napi_callback_info info)
211 {
212     HILOGI("start");
213     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
214     int state = static_cast<int>(BTConnectState::DISCONNECTED);
215     int32_t err = host->GetBtConnectionState(state);
216     HILOGI("start state %{public}d", state);
217     napi_value result = nullptr;
218     napi_create_int32(env, GetProfileConnectionState(state), &result);
219     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
220     HILOGI("end");
221     return result;
222 }
223 
PairDevice(napi_env env,napi_callback_info info)224 napi_value PairDevice(napi_env env, napi_callback_info info)
225 {
226     HILOGI("start");
227     std::string remoteAddr = INVALID_MAC_ADDRESS;
228     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
229     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
230 
231     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
232     int deviceType = remoteDevice.GetDeviceType();
233     if (deviceType == INVALID_TYPE) {
234         HILOGE("device is not discovery or scan, just quick BLE pair");
235         remoteDevice = BluetoothRemoteDevice(remoteAddr, BT_TRANSPORT_BLE);
236     }
237     if (deviceType == DEVICE_TYPE_LE) {
238         remoteDevice = BluetoothRemoteDevice(remoteAddr, BT_TRANSPORT_BLE);
239     }
240     int32_t ret = remoteDevice.StartPair();
241     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
242     return NapiGetBooleanTrue(env);
243 }
244 
CancelPairedDevice(napi_env env,napi_callback_info info)245 napi_value CancelPairedDevice(napi_env env, napi_callback_info info)
246 {
247     HILOGI("start");
248     std::string remoteAddr{};
249     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
250     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
251 
252     int transport = GetDeviceTransport(remoteAddr);
253     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
254     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
255     int32_t ret = host->RemovePair(remoteDevice);
256     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
257 
258     return NapiGetBooleanTrue(env);
259 }
260 
GetRemoteDeviceName(napi_env env,napi_callback_info info)261 napi_value GetRemoteDeviceName(napi_env env, napi_callback_info info)
262 {
263     HILOGD("start");
264     std::string remoteAddr = INVALID_MAC_ADDRESS;
265     std::string name = INVALID_NAME;
266     napi_value result = nullptr;
267     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
268     napi_create_string_utf8(env, name.c_str(), name.size(), &result);
269     NAPI_BT_ASSERT_RETURN(env, checkRet == true, BT_ERR_INVALID_PARAM, result);
270 
271     int transport = GetDeviceTransport(remoteAddr);
272     int32_t err = BluetoothHost::GetDefaultHost().GetRemoteDevice(remoteAddr, transport).GetDeviceName(name);
273     napi_create_string_utf8(env, name.c_str(), name.size(), &result);
274     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
275     return result;
276 }
277 
GetRemoteDeviceClass(napi_env env,napi_callback_info info)278 napi_value GetRemoteDeviceClass(napi_env env, napi_callback_info info)
279 {
280     HILOGD("start");
281     std::string remoteAddr = INVALID_MAC_ADDRESS;
282     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
283     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet, BT_ERR_INVALID_PARAM);
284 
285     int transport = GetDeviceTransport(remoteAddr);
286     int deviceCod = 0;
287     int32_t err = BluetoothHost::GetDefaultHost().GetRemoteDevice(remoteAddr, transport).GetDeviceClass(deviceCod);
288     BluetoothDeviceClass deviceClass = BluetoothDeviceClass(deviceCod);
289     int tmpCod = deviceClass.GetClassOfDevice();
290     int tmpMajorClass = deviceClass.GetMajorClass();
291     int tmpMajorMinorClass = deviceClass.GetMajorMinorClass();
292     if (tmpCod == 0) {
293         HILOGI("cod = %{public}d", tmpCod);
294         tmpCod = MajorClass::MAJOR_UNCATEGORIZED;
295         tmpMajorClass = MajorClass::MAJOR_UNCATEGORIZED;
296         tmpMajorMinorClass = MajorClass::MAJOR_UNCATEGORIZED;
297     }
298     HILOGD("cod = %{public}d, majorClass = %{public}d, majorMinorClass = %{public}d",
299         tmpCod,
300         tmpMajorClass,
301         tmpMajorMinorClass);
302     napi_value result = nullptr;
303     napi_create_object(env, &result);
304     napi_value majorClass = 0;
305     napi_create_int32(env, tmpMajorClass, &majorClass);
306     napi_set_named_property(env, result, "majorClass", majorClass);
307     napi_value majorMinorClass = 0;
308     napi_create_int32(env, tmpMajorMinorClass, &majorMinorClass);
309     napi_set_named_property(env, result, "majorMinorClass", majorMinorClass);
310     napi_value cod = 0;
311     napi_create_int32(env, tmpCod, &cod);
312     napi_set_named_property(env, result, "classOfDevice", cod);
313     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
314     return result;
315 }
316 
GetLocalName(napi_env env,napi_callback_info info)317 napi_value GetLocalName(napi_env env, napi_callback_info info)
318 {
319     napi_value result = nullptr;
320     HILOGI("start");
321     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
322     std::string localName = INVALID_NAME;
323     int32_t err = host->GetLocalName(localName);
324     napi_create_string_utf8(env, localName.c_str(), localName.size(), &result);
325     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
326     HILOGI("end");
327     return result;
328 }
329 
GetPairedDevices(napi_env env,napi_callback_info info)330 napi_value GetPairedDevices(napi_env env, napi_callback_info info)
331 {
332     HILOGI("start");
333     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
334     std::vector<BluetoothRemoteDevice> remoteDeviceLists;
335     int32_t ret = host->GetPairedDevices(BT_TRANSPORT_BREDR, remoteDeviceLists);
336     napi_value result = nullptr;
337     int count = 0;
338     napi_create_array(env, &result);
339     for (auto vec : remoteDeviceLists) {
340         napi_value remoteDeviceResult;
341         napi_create_string_utf8(env, vec.GetDeviceAddr().c_str(), vec.GetDeviceAddr().size(), &remoteDeviceResult);
342         napi_set_element(env, result, count, remoteDeviceResult);
343         count++;
344     }
345     NAPI_BT_ASSERT_RETURN(env, ret == BT_NO_ERROR, ret, result);
346     std::vector<BluetoothRemoteDevice> bleDeviceLists;
347     ret = host->GetPairedDevices(BT_TRANSPORT_BLE, bleDeviceLists);
348     for (auto vec : bleDeviceLists) {
349         napi_value remoteDeviceResult;
350         napi_create_string_utf8(env, vec.GetDeviceAddr().c_str(), vec.GetDeviceAddr().size(), &remoteDeviceResult);
351         napi_set_element(env, result, count, remoteDeviceResult);
352         count++;
353     }
354     NAPI_BT_ASSERT_RETURN(env, ret == BT_NO_ERROR, ret, result);
355     HILOGI("end");
356     return result;
357 }
358 
GetProfileConnectionState(napi_env env,napi_callback_info info)359 napi_value GetProfileConnectionState(napi_env env, napi_callback_info info)
360 {
361     HILOGI("enter");
362     int profileId = 0;
363     bool checkRet = CheckProfileIdParam(env, info, profileId);
364     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet, BT_ERR_INVALID_PARAM);
365 
366     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
367     int state = static_cast<int>(BTConnectState::DISCONNECTED);
368     int32_t err = host->GetBtProfileConnState(GetProfileId(profileId), state);
369     int status = GetProfileConnectionState(state);
370     napi_value ret = nullptr;
371     napi_create_int32(env, status, &ret);
372     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, ret);
373     HILOGI("status: %{public}d", status);
374     return ret;
375 }
376 
SetDevicePairingConfirmation(napi_env env,napi_callback_info info)377 napi_value SetDevicePairingConfirmation(napi_env env, napi_callback_info info)
378 {
379     HILOGI("start");
380     std::string remoteAddr{};
381     bool accept = false;
382     bool checkRet = CheckSetDevicePairingConfirmationParam(env, info, remoteAddr, accept);
383     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
384 
385     HILOGI("SetDevicePairingConfirmation::accept = %{public}d", accept);
386     int transport = GetDeviceTransport(remoteAddr);
387     int32_t ret = BT_NO_ERROR;
388     if (accept) {
389         ret =
390             BluetoothHost::GetDefaultHost().GetRemoteDevice(remoteAddr, transport).SetDevicePairingConfirmation(accept);
391     } else {
392         ret = BluetoothHost::GetDefaultHost().GetRemoteDevice(remoteAddr, transport).CancelPairing();
393     }
394     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
395     return NapiGetBooleanTrue(env);
396 }
397 
SetLocalName(napi_env env,napi_callback_info info)398 napi_value SetLocalName(napi_env env, napi_callback_info info)
399 {
400     HILOGI("start");
401     std::string localName = INVALID_NAME;
402     bool checkRet = CheckLocalNameParam(env, info, localName);
403     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
404 
405     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
406     int32_t ret = host->SetLocalName(localName);
407     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
408     return NapiGetBooleanTrue(env);
409 }
410 
SetBluetoothScanMode(napi_env env,napi_callback_info info)411 napi_value SetBluetoothScanMode(napi_env env, napi_callback_info info)
412 {
413     HILOGI("start");
414     int32_t mode = 0;
415     int32_t duration = 0;
416     bool checkRet = CheckSetBluetoothScanModeParam(env, info, mode, duration);
417     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
418     HILOGI("mode = %{public}d,duration = %{public}d", mode, duration);
419 
420     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
421     int32_t ret = host->SetBtScanMode(mode, duration);
422     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
423     host->SetBondableMode(BT_TRANSPORT_BREDR, 1);
424     return NapiGetBooleanTrue(env);
425 }
426 
GetBluetoothScanMode(napi_env env,napi_callback_info info)427 napi_value GetBluetoothScanMode(napi_env env, napi_callback_info info)
428 {
429     HILOGI("start");
430     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
431     int32_t scanMode = 0;
432     int32_t err = host->GetBtScanMode(scanMode);
433     napi_value result = nullptr;
434     napi_create_uint32(env, scanMode, &result);
435     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
436     HILOGI("end");
437     return result;
438 }
439 
AddDiscoveryDevice(std::shared_ptr<BluetoothRemoteDevice> & device)440 void AddDiscoveryDevice(std::shared_ptr<BluetoothRemoteDevice> &device)
441 {
442     std::lock_guard<std::mutex> lock(deviceMutex);
443     for (auto dev : g_DiscoveryDevices) {
444         if (device->GetDeviceAddr().compare(dev->GetDeviceAddr()) == 0) {
445             return;
446         }
447     }
448     g_DiscoveryDevices.push_back(device);
449 }
450 
ClearDiscoveryDevice()451 void ClearDiscoveryDevice()
452 {
453     std::lock_guard<std::mutex> lock(deviceMutex);
454     g_DiscoveryDevices.clear();
455 }
456 
StartBluetoothDiscovery(napi_env env,napi_callback_info info)457 napi_value StartBluetoothDiscovery(napi_env env, napi_callback_info info)
458 {
459     HILOGI("start");
460     ClearDiscoveryDevice();
461     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
462     int ret = host->StartBtDiscovery();
463     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
464     return NapiGetBooleanTrue(env);
465 }
466 
StopBluetoothDiscovery(napi_env env,napi_callback_info info)467 napi_value StopBluetoothDiscovery(napi_env env, napi_callback_info info)
468 {
469     HILOGI("start");
470     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
471     int ret = host->CancelBtDiscovery();
472     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
473     return NapiGetBooleanTrue(env);
474 }
475 
476 #ifdef BLUETOOTH_API_SINCE_10
SetCallback(const napi_env & env,const napi_ref & callbackIn,const int & errorCode,const napi_value & result)477 static void SetCallback(const napi_env &env, const napi_ref &callbackIn, const int &errorCode, const napi_value &result)
478 {
479     HILOGI("errorCode:%{public}d", errorCode);
480     napi_value undefined = nullptr;
481     napi_get_undefined(env, &undefined);
482 
483     napi_value callback = nullptr;
484     napi_value resultout = nullptr;
485     napi_get_reference_value(env, callbackIn, &callback);
486     napi_value results[ARGS_SIZE_TWO] = {nullptr};
487     results[PARAM0] = GetCallbackErrorValue(env, errorCode);
488     results[PARAM1] = result;
489     NAPI_CALL_RETURN_VOID(
490         env, napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, &results[PARAM0], &resultout));
491     HILOGI("end");
492 }
493 
SetPromise(const napi_env & env,const napi_deferred & deferred,const int32_t & errorCode,const napi_value & result)494 void SetPromise(const napi_env &env, const napi_deferred &deferred, const int32_t &errorCode, const napi_value &result)
495 {
496     if (errorCode == BT_NO_ERROR) {
497         napi_resolve_deferred(env, deferred, result);
498     } else {
499         napi_reject_deferred(env, deferred, GetCallbackErrorValue(env, errorCode));
500     }
501 }
502 
PaddingCallbackPromiseInfo(const napi_env & env,const napi_ref & callback,CallbackPromiseInfo & info,napi_value & promise)503 static void PaddingCallbackPromiseInfo(
504     const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info, napi_value &promise)
505 {
506     HILOGI("enter");
507     if (callback) {
508         info.callback = callback;
509         info.isCallback = true;
510     } else {
511         napi_deferred deferred = nullptr;
512         NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
513         info.deferred = deferred;
514         info.isCallback = false;
515     }
516     HILOGI("end");
517 }
518 
ReturnCallbackPromise(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result)519 static void ReturnCallbackPromise(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result)
520 {
521     HILOGI("enter");
522     if (info.isCallback) {
523         SetCallback(env, info.callback, info.errorCode, result);
524     } else {
525         SetPromise(env, info.deferred, info.errorCode, result);
526     }
527     HILOGI("end");
528 }
529 
ParseSetDevicePinCodeParameters(napi_env env,napi_callback_info info,SetDevicePinCodeCallbackInfo * params)530 napi_status ParseSetDevicePinCodeParameters(napi_env env, napi_callback_info info, SetDevicePinCodeCallbackInfo *params)
531 {
532     HILOGI("enter");
533     size_t expectedArgsCount = ARGS_SIZE_THREE;
534     size_t argc = expectedArgsCount;
535     std::string remoteAddr{};
536     std::string pinCode{};
537     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
538     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, NULL));
539     NAPI_BT_RETURN_IF(argc != expectedArgsCount && argc != expectedArgsCount - CALLBACK_SIZE,
540         "Requires 2 or 3 arguments.",
541         napi_invalid_arg);
542     NAPI_BT_RETURN_IF(!ParseString(env, remoteAddr, argv[PARAM0]), "remoteAddr ParseString failed", napi_invalid_arg);
543     NAPI_BT_RETURN_IF(!IsValidAddress(remoteAddr), "Invalid addr", napi_invalid_arg);
544     NAPI_BT_RETURN_IF(!ParseString(env, pinCode, argv[PARAM1]), "pinCode ParseString failed", napi_invalid_arg);
545     params->deviceId = remoteAddr;
546     params->pinCode = pinCode;
547     if (argc == expectedArgsCount) {
548         NAPI_BT_CALL_RETURN(NapiIsFunction(env, argv[PARAM2]));
549         napi_create_reference(env, argv[PARAM2], 1, &params->promise.callback);
550     }
551     HILOGI("end");
552     return napi_ok;
553 }
554 
SetDevicePinCode(napi_env env,napi_callback_info info)555 napi_value SetDevicePinCode(napi_env env, napi_callback_info info)
556 {
557     HILOGI("start");
558     SetDevicePinCodeCallbackInfo *asyncCallbackInfo =
559         new (std::nothrow) SetDevicePinCodeCallbackInfo{.env = env, .asyncWork = nullptr};
560     napi_status status = ParseSetDevicePinCodeParameters(env, info, asyncCallbackInfo);
561     if (status != napi_ok) {
562         delete asyncCallbackInfo;
563         asyncCallbackInfo = nullptr;
564     }
565     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
566 
567     napi_value promise = nullptr;
568     PaddingCallbackPromiseInfo(env, asyncCallbackInfo->promise.callback, asyncCallbackInfo->promise, promise);
569 
570     napi_value resourceName = nullptr;
571     napi_create_string_latin1(env, "setDevicePinCode", NAPI_AUTO_LENGTH, &resourceName);
572     napi_create_async_work(env,
573         nullptr,
574         resourceName,
575         [](napi_env env, void *data) {
576             HILOGI("napi_create_async_work start");
577             SetDevicePinCodeCallbackInfo *callbackInfo = static_cast<SetDevicePinCodeCallbackInfo *>(data);
578             if (callbackInfo) {
579                 int transport = GetDeviceTransport(callbackInfo->deviceId);
580                 callbackInfo->promise.errorCode = BluetoothHost::GetDefaultHost()
581                                                       .GetRemoteDevice(callbackInfo->deviceId, transport)
582                                                       .SetDevicePin(callbackInfo->pinCode);
583             }
584         },
585         [](napi_env env, napi_status status, void *data) {
586             SetDevicePinCodeCallbackInfo *callbackInfo = static_cast<SetDevicePinCodeCallbackInfo *>(data);
587             if (callbackInfo) {
588                 ReturnCallbackPromise(env, callbackInfo->promise, NapiGetNull(env));
589                 if (callbackInfo->promise.callback != nullptr) {
590                     napi_delete_reference(env, callbackInfo->promise.callback);
591                 }
592                 napi_delete_async_work(env, callbackInfo->asyncWork);
593                 delete callbackInfo;
594                 callbackInfo = nullptr;
595             }
596         },
597         static_cast<void *>(asyncCallbackInfo),
598         &asyncCallbackInfo->asyncWork);
599     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
600     HILOGI("end");
601     if (asyncCallbackInfo->promise.isCallback) {
602         return NapiGetUndefinedRet(env);
603     } else {
604         return promise;
605     }
606 }
607 
CheckDeviceAsyncParam(napi_env env,napi_callback_info info,std::string & addr)608 napi_status CheckDeviceAsyncParam(napi_env env, napi_callback_info info, std::string &addr)
609 {
610     size_t argc = ARGS_SIZE_TWO;
611     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
612     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
613     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE && argc != ARGS_SIZE_TWO, "Requires 1 or 2 arguments", napi_invalid_arg);
614     NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], addr));
615     return napi_ok;
616 }
617 
PairDeviceAsync(napi_env env,napi_callback_info info)618 napi_value PairDeviceAsync(napi_env env, napi_callback_info info)
619 {
620     HILOGI("start");
621     std::string remoteAddr = INVALID_MAC_ADDRESS;
622     auto checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
623     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
624 
625     auto func = [remoteAddr]() {
626         int transport = GetDeviceTransport(remoteAddr);
627         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
628         int32_t err = remoteDevice.StartPair();
629         HILOGI("err: %{public}d", err);
630         return NapiAsyncWorkRet(err);
631     };
632     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
633     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
634     asyncWork->Run();
635     return asyncWork->GetRet();
636 }
637 
CancelPairedDeviceAsync(napi_env env,napi_callback_info info)638 napi_value CancelPairedDeviceAsync(napi_env env, napi_callback_info info)
639 {
640     HILOGI("start");
641     std::string remoteAddr {};
642     bool checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
643     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
644 
645     auto func = [remoteAddr]() {
646         int transport = GetDeviceTransport(remoteAddr);
647         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
648         BluetoothHost *host = &BluetoothHost::GetDefaultHost();
649         int32_t err = host->RemovePair(remoteDevice);
650         HILOGI("err: %{public}d", err);
651         return NapiAsyncWorkRet(err);
652     };
653     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
654     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
655     asyncWork->Run();
656     return asyncWork->GetRet();
657 }
658 
CancelPairingDevice(napi_env env,napi_callback_info info)659 napi_value CancelPairingDevice(napi_env env, napi_callback_info info)
660 {
661     HILOGI("start");
662     std::string remoteAddr{};
663     bool checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
664     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
665 
666     auto func = [remoteAddr]() {
667         int transport = GetDeviceTransport(remoteAddr);
668         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
669         int32_t err = remoteDevice.CancelPairing();
670         HILOGI("err: %{public}d", err);
671         return NapiAsyncWorkRet(err);
672     };
673     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
674     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
675     asyncWork->Run();
676     return asyncWork->GetRet();
677 }
678 
CheckPairCredibleDeviceParam(napi_env env,napi_callback_info info,std::string & addr,int & transport)679 napi_status CheckPairCredibleDeviceParam(napi_env env, napi_callback_info info, std::string &addr, int &transport)
680 {
681     size_t argc = ARGS_SIZE_THREE;
682     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
683     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
684     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO && argc != ARGS_SIZE_THREE, "Requires 2 or 3 arguments.", napi_invalid_arg);
685     NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], addr));
686     NAPI_BT_RETURN_IF(!ParseInt32(env, transport, argv[PARAM1]), "ParseInt32 failed", napi_invalid_arg);
687     NAPI_BT_RETURN_IF(!IsValidTransport(transport), "Invalid transport", napi_invalid_arg);
688     return napi_ok;
689 }
690 
PairCredibleDevice(napi_env env,napi_callback_info info)691 napi_value PairCredibleDevice(napi_env env, napi_callback_info info)
692 {
693     HILOGI("start");
694     std::string remoteAddr = INVALID_MAC_ADDRESS;
695     int transport = INVALID_TYPE;
696     auto status = CheckPairCredibleDeviceParam(env, info, remoteAddr, transport);
697     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
698 
699     auto func = [remoteAddr, transport]() {
700         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
701         int32_t err = remoteDevice.StartPair();
702         HILOGI("err: %{public}d", err);
703         return NapiAsyncWorkRet(err);
704     };
705     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
706     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
707     asyncWork->Run();
708     return asyncWork->GetRet();
709 }
710 
CheckGetProfileUuids(napi_env env,napi_callback_info info,std::string & address)711 napi_status CheckGetProfileUuids(napi_env env, napi_callback_info info, std::string &address)
712 {
713     size_t argc = ARGS_SIZE_TWO;
714     napi_value argv[ARGS_SIZE_TWO] = {0};
715     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
716     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE && argc != ARGS_SIZE_TWO, "Requires 1 or 2 arguments.", napi_invalid_arg);
717     NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], address));
718     return napi_ok;
719 }
720 
GetLocalProfileUuids(napi_env env,napi_callback_info info)721 napi_value GetLocalProfileUuids(napi_env env, napi_callback_info info)
722 {
723     HILOGI("start");
724     auto func = []() {
725         std::vector<std::string> uuids{};
726         int32_t err = BluetoothHost::GetDefaultHost().GetLocalProfileUuids(uuids);
727         HILOGI("err: %{public}d", err);
728         auto object = std::make_shared<NapiNativeUuidsArray>(uuids);
729         return NapiAsyncWorkRet(err, object);
730     };
731     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
732     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
733     asyncWork->Run();
734     return asyncWork->GetRet();
735 }
736 
GetRemoteProfileUuids(napi_env env,napi_callback_info info)737 napi_value GetRemoteProfileUuids(napi_env env, napi_callback_info info)
738 {
739     HILOGI("start");
740     std::string address;
741     auto status = CheckGetProfileUuids(env, info, address);
742     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
743     auto func = [address]() {
744         std::vector<std::string> uuids{};
745         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(address, BT_TRANSPORT_BREDR);
746         int32_t err = remoteDevice.GetDeviceUuids(uuids);
747         HILOGI("err: %{public}d", err);
748         auto object = std::make_shared<NapiNativeUuidsArray>(uuids);
749         return NapiAsyncWorkRet(err, object);
750     };
751     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
752     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
753     asyncWork->Run();
754     return asyncWork->GetRet();
755 }
756 #endif
757 
ConnectionPropertyValueInit(napi_env env,napi_value exports)758 napi_value ConnectionPropertyValueInit(napi_env env, napi_value exports)
759 {
760     HILOGI("start");
761     napi_value scanModeObj = ScanModeInit(env);
762     napi_value bondStateObj = BondStateInit(env);
763 #ifdef BLUETOOTH_API_SINCE_10
764     napi_value bluetoothTransportObject = BluetoothTransportInit(env);
765     napi_value pinTypeObject = PinTypeInit(env);
766 #endif
767     napi_property_descriptor exportProperties[] = {
768         DECLARE_NAPI_PROPERTY("ScanMode", scanModeObj),
769         DECLARE_NAPI_PROPERTY("BondState", bondStateObj),
770 #ifdef BLUETOOTH_API_SINCE_10
771         DECLARE_NAPI_PROPERTY("BluetoothTransport", bluetoothTransportObject),
772         DECLARE_NAPI_PROPERTY("PinType", pinTypeObject),
773 #endif
774     };
775     napi_define_properties(env, exports, sizeof(exportProperties) / sizeof(*exportProperties), exportProperties);
776     HILOGI("end");
777     return exports;
778 }
779 
ScanModeInit(napi_env env)780 napi_value ScanModeInit(napi_env env)
781 {
782     HILOGI("enter");
783     napi_value scanMode = nullptr;
784     napi_create_object(env, &scanMode);
785     SetNamedPropertyByInteger(env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_NONE), "SCAN_MODE_NONE");
786     SetNamedPropertyByInteger(
787         env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_CONNECTABLE), "SCAN_MODE_CONNECTABLE");
788     SetNamedPropertyByInteger(
789         env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_GENERAL_DISCOVERABLE), "SCAN_MODE_GENERAL_DISCOVERABLE");
790     SetNamedPropertyByInteger(
791         env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_LIMITED_DISCOVERABLE), "SCAN_MODE_LIMITED_DISCOVERABLE");
792     SetNamedPropertyByInteger(env,
793         scanMode,
794         static_cast<int>(ScanMode::SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE),
795         "SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE");
796     SetNamedPropertyByInteger(env,
797         scanMode,
798         static_cast<int>(ScanMode::SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE),
799         "SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE");
800     return scanMode;
801 }
802 
BondStateInit(napi_env env)803 napi_value BondStateInit(napi_env env)
804 {
805     HILOGI("enter");
806     napi_value bondState = nullptr;
807     napi_create_object(env, &bondState);
808     SetNamedPropertyByInteger(env, bondState, static_cast<int>(BondState::BOND_STATE_INVALID), "BOND_STATE_INVALID");
809     SetNamedPropertyByInteger(env, bondState, static_cast<int>(BondState::BOND_STATE_BONDING), "BOND_STATE_BONDING");
810     SetNamedPropertyByInteger(env, bondState, static_cast<int>(BondState::BOND_STATE_BONDED), "BOND_STATE_BONDED");
811     return bondState;
812 }
813 
814 #ifdef BLUETOOTH_API_SINCE_10
BluetoothTransportInit(napi_env env)815 napi_value BluetoothTransportInit(napi_env env)
816 {
817     HILOGI("enter");
818     napi_value bluetoothTransport = nullptr;
819     napi_create_object(env, &bluetoothTransport);
820     SetNamedPropertyByInteger(
821         env, bluetoothTransport, static_cast<int>(BluetoothTransport::TRANSPORT_BR_EDR), "TRANSPORT_BR_EDR");
822     SetNamedPropertyByInteger(
823         env, bluetoothTransport, static_cast<int>(BluetoothTransport::TRANSPORT_LE), "TRANSPORT_LE");
824     return bluetoothTransport;
825 }
826 
PinTypeInit(napi_env env)827 napi_value PinTypeInit(napi_env env)
828 {
829     HILOGI("enter");
830     napi_value pinType = nullptr;
831     napi_create_object(env, &pinType);
832     SetNamedPropertyByInteger(
833         env, pinType, static_cast<int>(PinType::PIN_TYPE_ENTER_PIN_CODE), "PIN_TYPE_ENTER_PIN_CODE");
834     SetNamedPropertyByInteger(
835         env, pinType, static_cast<int>(PinType::PIN_TYPE_ENTER_PASSKEY), "PIN_TYPE_ENTER_PASSKEY");
836     SetNamedPropertyByInteger(
837         env, pinType, static_cast<int>(PinType::PIN_TYPE_CONFIRM_PASSKEY), "PIN_TYPE_CONFIRM_PASSKEY");
838     SetNamedPropertyByInteger(
839         env, pinType, static_cast<int>(PinType::PIN_TYPE_NO_PASSKEY_CONSENT), "PIN_TYPE_NO_PASSKEY_CONSENT");
840     SetNamedPropertyByInteger(
841         env, pinType, static_cast<int>(PinType::PIN_TYPE_NOTIFY_PASSKEY), "PIN_TYPE_NOTIFY_PASSKEY");
842     SetNamedPropertyByInteger(
843         env, pinType, static_cast<int>(PinType::PIN_TYPE_DISPLAY_PIN_CODE), "PIN_TYPE_DISPLAY_PIN_CODE");
844     SetNamedPropertyByInteger(env, pinType, static_cast<int>(PinType::PIN_TYPE_OOB_CONSENT), "PIN_TYPE_OOB_CONSENT");
845     SetNamedPropertyByInteger(
846         env, pinType, static_cast<int>(PinType::PIN_TYPE_PIN_16_DIGITS), "PIN_TYPE_PIN_16_DIGITS");
847     return pinType;
848 }
849 #endif
850 
RegisterObserverToHost()851 void RegisterObserverToHost()
852 {
853     HILOGI("start");
854     g_remoteDeviceObserver = std::make_shared<NapiBluetoothRemoteDeviceObserver>();
855     BluetoothHost &host = BluetoothHost::GetDefaultHost();
856     host.RegisterObserver(g_connectionObserver);
857     host.RegisterRemoteDeviceObserver(g_remoteDeviceObserver);
858 }
859 
GetDeviceTransport(const std::string & device)860 int GetDeviceTransport(const std::string &device)
861 {
862     std::lock_guard<std::mutex> lock(deviceMutex);
863     for (auto dev : g_DiscoveryDevices) {
864         if (device.compare(dev->GetDeviceAddr()) == 0) {
865             return dev->GetTransportType();
866         }
867     }
868     return BT_TRANSPORT_BREDR;
869 }
870 }  // namespace Bluetooth
871 }  // namespace OHOS