• 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 std::shared_ptr<NapiBluetoothConnectionObserver> g_connectionObserver =
32     std::make_shared<NapiBluetoothConnectionObserver>();
33 std::shared_ptr<NapiBluetoothRemoteDeviceObserver> g_remoteDeviceObserver =
34     std::make_shared<NapiBluetoothRemoteDeviceObserver>();
35 std::mutex deviceMutex;
36 
37 std::map<std::string, std::function<napi_value(napi_env env)>> g_callbackDefaultValue = {
38     {REGISTER_DEVICE_FIND_TYPE,
__anonf2a9bdc00102() 39         [](napi_env env) -> napi_value {
40             napi_value result = 0;
41             napi_value value = 0;
42             napi_create_array(env, &result);
43             napi_create_string_utf8(env, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &value);
44             napi_set_element(env, result, 0, value);
45             return result;
46         }},
47     {REGISTER_PIN_REQUEST_TYPE,
__anonf2a9bdc00202() 48         [](napi_env env) -> napi_value {
49             napi_value result = 0;
50             napi_value deviceId = nullptr;
51             napi_value pinCode = nullptr;
52             napi_create_object(env, &result);
53             napi_create_string_utf8(env, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &deviceId);
54             napi_set_named_property(env, result, "deviceId", deviceId);
55             napi_create_string_utf8(env, INVALID_PIN_CODE.c_str(), NAPI_AUTO_LENGTH, &pinCode);
56             napi_set_named_property(env, result, "pinCode", pinCode);
57             return result;
58         }},
__anonf2a9bdc00302() 59     {REGISTER_BOND_STATE_TYPE, [](napi_env env) -> napi_value {
60          napi_value result = 0;
61          napi_value deviceId = nullptr;
62          napi_value state = nullptr;
63          napi_create_object(env, &result);
64          napi_create_string_utf8(env, INVALID_DEVICE_ID.c_str(), NAPI_AUTO_LENGTH, &deviceId);
65          napi_set_named_property(env, result, "deviceId", deviceId);
66          napi_create_int32(env, static_cast<int32_t>(BondState::BOND_STATE_INVALID), &state);
67          napi_set_named_property(env, result, "state", state);
68          return result;
69      }}};
70 
DefineConnectionFunctions(napi_env env,napi_value exports)71 napi_value DefineConnectionFunctions(napi_env env, napi_value exports)
72 {
73     HILOGD("enter");
74     RegisterObserverToHost();
75     ConnectionPropertyValueInit(env, exports);
76     napi_property_descriptor desc[] = {
77         DECLARE_NAPI_FUNCTION("getBtConnectionState", GetBtConnectionState),
78 #ifdef BLUETOOTH_API_SINCE_10
79         DECLARE_NAPI_FUNCTION("pairDevice", PairDeviceAsync),
80         DECLARE_NAPI_FUNCTION("cancelPairedDevice", CancelPairedDeviceAsync),
81         DECLARE_NAPI_FUNCTION("getProfileConnectionState", GetProfileConnectionStateEx),
82 #else
83         DECLARE_NAPI_FUNCTION("pairDevice", PairDevice),
84         DECLARE_NAPI_FUNCTION("cancelPairedDevice", CancelPairedDevice),
85         DECLARE_NAPI_FUNCTION("getProfileConnectionState", GetProfileConnectionState),
86 #endif
87         DECLARE_NAPI_FUNCTION("getRemoteDeviceName", GetRemoteDeviceName),
88         DECLARE_NAPI_FUNCTION("getRemoteDeviceClass", GetRemoteDeviceClass),
89         DECLARE_NAPI_FUNCTION("getLocalName", GetLocalName),
90         DECLARE_NAPI_FUNCTION("getPairedDevices", GetPairedDevices),
91         DECLARE_NAPI_FUNCTION("getProfileConnState", 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         DECLARE_NAPI_FUNCTION("isBluetoothDiscovering", IsBluetoothDiscovering),
107         DECLARE_NAPI_FUNCTION("getPairState", GetPairState),
108         DECLARE_NAPI_FUNCTION("connectAllowedProfiles", ConnectAllowedProfiles),
109         DECLARE_NAPI_FUNCTION("disconnectAllowedProfiles", DisconnectAllowedProfiles),
110         DECLARE_NAPI_FUNCTION("getRemoteProductId", GetRemoteProductId),
111 #endif
112     };
113 
114     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
115     return exports;
116 }
117 
IsValidObserverType(const std::string & callbackName)118 static bool IsValidObserverType(const std::string &callbackName)
119 {
120     if (callbackName == REGISTER_DEVICE_FIND_TYPE || callbackName == REGISTER_PIN_REQUEST_TYPE ||
121         callbackName == REGISTER_BOND_STATE_TYPE) {
122         return true;
123     } else {
124         HILOGE("not support %{public}s.", callbackName.c_str());
125         return false;
126     }
127 }
128 
CheckRegisterObserver(napi_env env,napi_callback_info info)129 napi_status CheckRegisterObserver(napi_env env, napi_callback_info info)
130 {
131     size_t argc = ARGS_SIZE_TWO;
132     napi_value argv[ARGS_SIZE_TWO] = {0};
133     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
134     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Requires 2 arguments.", napi_invalid_arg);
135 
136     std::string callbackName;
137     NAPI_BT_CALL_RETURN(NapiParseString(env, argv[PARAM0], callbackName));
138     NAPI_BT_RETURN_IF(!IsValidObserverType(callbackName), "Invalid type", napi_invalid_arg);
139 
140     auto napiCallback = std::make_shared<NapiCallback>(env, argv[PARAM1]);
141     if (callbackName == REGISTER_BOND_STATE_TYPE) {
142         g_remoteDeviceObserver->RegisterCallback(callbackName, napiCallback);
143     } else {
144         g_connectionObserver->RegisterCallback(callbackName, napiCallback);
145     }
146     HILOGI("%{public}s registered", callbackName.c_str());
147     return napi_ok;
148 }
149 
CheckDeRegisterObserver(napi_env env,napi_callback_info info)150 napi_status CheckDeRegisterObserver(napi_env env, napi_callback_info info)
151 {
152     size_t argc = ARGS_SIZE_TWO;
153     napi_value argv[ARGS_SIZE_TWO] = {0};
154     napi_value thisVar = nullptr;
155     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
156     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE && argc != ARGS_SIZE_TWO, "Requires 1 or 2 arguments.", napi_invalid_arg);
157 
158     std::string callbackName;
159     NAPI_BT_CALL_RETURN(NapiParseString(env, argv[PARAM0], callbackName));
160     NAPI_BT_RETURN_IF(!IsValidObserverType(callbackName), "Invalid type", napi_invalid_arg);
161 
162     if (callbackName == REGISTER_BOND_STATE_TYPE) {
163         g_remoteDeviceObserver->DeRegisterCallback(callbackName);
164     } else {
165         g_connectionObserver->DeRegisterCallback(callbackName);
166     }
167     HILOGI("%{public}s unregistered", callbackName.c_str());
168     return napi_ok;
169 }
170 
RegisterConnectionObserver(napi_env env,napi_callback_info info)171 napi_value RegisterConnectionObserver(napi_env env, napi_callback_info info)
172 {
173     HILOGD("enter");
174     auto status = CheckRegisterObserver(env, info);
175     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
176 
177     napi_value ret = nullptr;
178     napi_get_undefined(env, &ret);
179     return ret;
180 }
181 
DeRegisterConnectionObserver(napi_env env,napi_callback_info info)182 napi_value DeRegisterConnectionObserver(napi_env env, napi_callback_info info)
183 {
184     HILOGD("enter");
185     auto status = CheckDeRegisterObserver(env, info);
186     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
187 
188     napi_value ret = nullptr;
189     napi_get_undefined(env, &ret);
190     return ret;
191 }
192 
GetBtConnectionState(napi_env env,napi_callback_info info)193 napi_value GetBtConnectionState(napi_env env, napi_callback_info info)
194 {
195     HILOGD("enter");
196     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
197     int state = static_cast<int>(BTConnectState::DISCONNECTED);
198     int32_t err = host->GetBtConnectionState(state);
199     HILOGI("start state %{public}d", state);
200     napi_value result = nullptr;
201     napi_create_int32(env, GetProfileConnectionState(state), &result);
202     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
203     HILOGI("end");
204     return result;
205 }
206 
PairDevice(napi_env env,napi_callback_info info)207 napi_value PairDevice(napi_env env, napi_callback_info info)
208 {
209     HILOGD("enter");
210     std::string remoteAddr = INVALID_MAC_ADDRESS;
211     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
212     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
213 
214     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
215     int32_t ret = remoteDevice.StartPair();
216     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
217     return NapiGetBooleanTrue(env);
218 }
219 
CancelPairedDevice(napi_env env,napi_callback_info info)220 napi_value CancelPairedDevice(napi_env env, napi_callback_info info)
221 {
222     HILOGD("enter");
223     std::string remoteAddr{};
224     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
225     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
226 
227     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
228     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
229     int32_t ret = host->RemovePair(remoteDevice);
230     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
231 
232     return NapiGetBooleanTrue(env);
233 }
234 
GetRemoteDeviceName(napi_env env,napi_callback_info info)235 napi_value GetRemoteDeviceName(napi_env env, napi_callback_info info)
236 {
237     HILOGD("start");
238     std::string remoteAddr = INVALID_MAC_ADDRESS;
239     std::string name = INVALID_NAME;
240     napi_value result = nullptr;
241     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
242     napi_create_string_utf8(env, name.c_str(), name.size(), &result);
243     NAPI_BT_ASSERT_RETURN(env, checkRet == true, BT_ERR_INVALID_PARAM, result);
244 
245     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
246     int32_t err = remoteDevice.GetDeviceName(name);
247     napi_create_string_utf8(env, name.c_str(), name.size(), &result);
248     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
249     return result;
250 }
251 
GetRemoteDeviceClass(napi_env env,napi_callback_info info)252 napi_value GetRemoteDeviceClass(napi_env env, napi_callback_info info)
253 {
254     HILOGD("start");
255     std::string remoteAddr = INVALID_MAC_ADDRESS;
256     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
257     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet, BT_ERR_INVALID_PARAM);
258 
259     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
260     int tmpCod = MajorClass::MAJOR_UNCATEGORIZED;
261     int tmpMajorClass = MajorClass::MAJOR_UNCATEGORIZED;
262     int tmpMajorMinorClass = MajorClass::MAJOR_UNCATEGORIZED;
263     int32_t err = remoteDevice.GetDeviceProductType(tmpCod, tmpMajorClass, tmpMajorMinorClass);
264 
265     napi_value result = nullptr;
266     napi_create_object(env, &result);
267     napi_value majorClass = 0;
268     napi_create_int32(env, tmpMajorClass, &majorClass);
269     napi_set_named_property(env, result, "majorClass", majorClass);
270     napi_value majorMinorClass = 0;
271     napi_create_int32(env, tmpMajorMinorClass, &majorMinorClass);
272     napi_set_named_property(env, result, "majorMinorClass", majorMinorClass);
273     napi_value cod = 0;
274     napi_create_int32(env, tmpCod, &cod);
275     napi_set_named_property(env, result, "classOfDevice", cod);
276     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
277     return result;
278 }
279 
GetLocalName(napi_env env,napi_callback_info info)280 napi_value GetLocalName(napi_env env, napi_callback_info info)
281 {
282     napi_value result = nullptr;
283     HILOGD("enter");
284     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
285     std::string localName = INVALID_NAME;
286     int32_t err = host->GetLocalName(localName);
287     napi_create_string_utf8(env, localName.c_str(), localName.size(), &result);
288     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
289     HILOGI("end");
290     return result;
291 }
292 
GetPairedDevices(napi_env env,napi_callback_info info)293 napi_value GetPairedDevices(napi_env env, napi_callback_info info)
294 {
295     HILOGD("enter");
296     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
297     std::vector<BluetoothRemoteDevice> remoteDeviceLists;
298     int32_t ret = host->GetPairedDevices(BT_TRANSPORT_BREDR, remoteDeviceLists);
299     napi_value result = nullptr;
300     int count = 0;
301     napi_create_array(env, &result);
302     for (auto vec : remoteDeviceLists) {
303         napi_value remoteDeviceResult;
304         napi_create_string_utf8(env, vec.GetDeviceAddr().c_str(), vec.GetDeviceAddr().size(), &remoteDeviceResult);
305         napi_set_element(env, result, count, remoteDeviceResult);
306         count++;
307     }
308     NAPI_BT_ASSERT_RETURN(env, ret == BT_NO_ERROR, ret, result);
309     HILOGI("end");
310     return result;
311 }
312 
GetProfileConnectionState(napi_env env,napi_callback_info info)313 napi_value GetProfileConnectionState(napi_env env, napi_callback_info info)
314 {
315     HILOGD("enter");
316     int profileId = 0;
317     bool checkRet = CheckProfileIdParam(env, info, profileId);
318     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet, BT_ERR_INVALID_PARAM);
319 
320     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
321     int state = static_cast<int>(BTConnectState::DISCONNECTED);
322     int32_t err = host->GetBtProfileConnState(GetProfileId(profileId), state);
323     int status = GetProfileConnectionState(state);
324     napi_value ret = nullptr;
325     napi_create_int32(env, status, &ret);
326     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, ret);
327     HILOGI("status: %{public}d", status);
328     return ret;
329 }
330 
GetProfileConnectionStateEx(napi_env env,napi_callback_info info)331 napi_value GetProfileConnectionStateEx(napi_env env, napi_callback_info info)
332 {
333     HILOGD("enter");
334     int profileId = 0;
335     size_t argSize = ARGS_SIZE_ONE;
336     bool checkRet = CheckProfileIdParamEx(env, info, profileId, argSize);
337     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet, BT_ERR_INVALID_PARAM);
338     HILOGD("argSize = %{public}zu", argSize);
339 
340     napi_value ret = nullptr;
341     if (argSize == 0) {
342         ret = GetBtConnectionState(env, info);
343     } else {
344         ret = GetProfileConnectionState(env, info);
345     }
346     return ret;
347 }
348 
SetDevicePairingConfirmation(napi_env env,napi_callback_info info)349 napi_value SetDevicePairingConfirmation(napi_env env, napi_callback_info info)
350 {
351     HILOGD("enter");
352     std::string remoteAddr{};
353     bool accept = false;
354     bool checkRet = CheckSetDevicePairingConfirmationParam(env, info, remoteAddr, accept);
355     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
356 
357     HILOGI("SetDevicePairingConfirmation::accept = %{public}d", accept);
358     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
359     int32_t ret = BT_NO_ERROR;
360     if (accept) {
361         ret = remoteDevice.SetDevicePairingConfirmation(accept);
362     } else {
363         ret = remoteDevice.CancelPairing();
364     }
365     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
366     return NapiGetBooleanTrue(env);
367 }
368 
SetLocalName(napi_env env,napi_callback_info info)369 napi_value SetLocalName(napi_env env, napi_callback_info info)
370 {
371     HILOGD("enter");
372     std::string localName = INVALID_NAME;
373     bool checkRet = CheckLocalNameParam(env, info, localName);
374     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
375 
376     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
377     int32_t ret = host->SetLocalName(localName);
378     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
379     return NapiGetBooleanTrue(env);
380 }
381 
SetBluetoothScanMode(napi_env env,napi_callback_info info)382 napi_value SetBluetoothScanMode(napi_env env, napi_callback_info info)
383 {
384     HILOGD("enter");
385     int32_t mode = 0;
386     int32_t duration = 0;
387     bool checkRet = CheckSetBluetoothScanModeParam(env, info, mode, duration);
388     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
389     HILOGI("mode = %{public}d,duration = %{public}d", mode, duration);
390 
391     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
392     int32_t ret = host->SetBtScanMode(mode, duration);
393     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
394     host->SetBondableMode(BT_TRANSPORT_BREDR, 1);
395     return NapiGetBooleanTrue(env);
396 }
397 
GetBluetoothScanMode(napi_env env,napi_callback_info info)398 napi_value GetBluetoothScanMode(napi_env env, napi_callback_info info)
399 {
400     HILOGD("enter");
401     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
402     int32_t scanMode = 0;
403     int32_t err = host->GetBtScanMode(scanMode);
404     napi_value result = nullptr;
405     napi_create_uint32(env, scanMode, &result);
406     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
407     HILOGI("end");
408     return result;
409 }
410 
StartBluetoothDiscovery(napi_env env,napi_callback_info info)411 napi_value StartBluetoothDiscovery(napi_env env, napi_callback_info info)
412 {
413     HILOGD("enter");
414     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
415     int ret = host->StartBtDiscovery();
416     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
417     return NapiGetBooleanTrue(env);
418 }
419 
StopBluetoothDiscovery(napi_env env,napi_callback_info info)420 napi_value StopBluetoothDiscovery(napi_env env, napi_callback_info info)
421 {
422     HILOGD("enter");
423     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
424     int ret = host->CancelBtDiscovery();
425     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
426     return NapiGetBooleanTrue(env);
427 }
428 
429 #ifdef BLUETOOTH_API_SINCE_10
ParseSetDevicePinCodeParameters(napi_env env,napi_callback_info info,std::string & outRemoteAddr,std::string & outPinCode)430 napi_status ParseSetDevicePinCodeParameters(napi_env env, napi_callback_info info,
431     std::string &outRemoteAddr, std::string &outPinCode)
432 {
433     HILOGD("enter");
434     std::string remoteAddr{};
435     std::string pinCode{};
436     size_t argc = ARGS_SIZE_THREE;
437     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
438     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, NULL));
439     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO && argc != ARGS_SIZE_THREE,
440         "Requires 2 or 3 arguments.", napi_invalid_arg);
441     NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], remoteAddr));
442     NAPI_BT_RETURN_IF(!ParseString(env, pinCode, argv[PARAM1]), "pinCode ParseString failed", napi_invalid_arg);
443     outRemoteAddr = remoteAddr;
444     outPinCode = pinCode;
445     return napi_ok;
446 }
447 
SetDevicePinCode(napi_env env,napi_callback_info info)448 napi_value SetDevicePinCode(napi_env env, napi_callback_info info)
449 {
450     HILOGD("enter");
451     std::string remoteAddr = "";
452     std::string pinCode = "";
453     auto status = ParseSetDevicePinCodeParameters(env, info, remoteAddr, pinCode);
454     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
455 
456     auto func = [remoteAddr, pinCode]() {
457         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
458         int32_t err = remoteDevice.SetDevicePin(pinCode);
459         HILOGI("SetDevicePinCode err: %{public}d", err);
460         return NapiAsyncWorkRet(err);
461     };
462     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
463     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
464     asyncWork->Run();
465     return asyncWork->GetRet();
466 }
467 
CheckDeviceAsyncParam(napi_env env,napi_callback_info info,std::string & addr)468 napi_status CheckDeviceAsyncParam(napi_env env, napi_callback_info info, std::string &addr)
469 {
470     size_t argc = ARGS_SIZE_TWO;
471     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
472     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
473     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE && argc != ARGS_SIZE_TWO, "Requires 1 or 2 arguments", napi_invalid_arg);
474     NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], addr));
475     return napi_ok;
476 }
477 
PairDeviceAsync(napi_env env,napi_callback_info info)478 napi_value PairDeviceAsync(napi_env env, napi_callback_info info)
479 {
480     HILOGD("enter");
481     std::string remoteAddr = INVALID_MAC_ADDRESS;
482     auto checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
483     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
484 
485     auto func = [remoteAddr]() {
486         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
487         int32_t err = remoteDevice.StartPair();
488         HILOGI("err: %{public}d", err);
489         return NapiAsyncWorkRet(err);
490     };
491     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
492     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
493     asyncWork->Run();
494     return asyncWork->GetRet();
495 }
496 
CancelPairedDeviceAsync(napi_env env,napi_callback_info info)497 napi_value CancelPairedDeviceAsync(napi_env env, napi_callback_info info)
498 {
499     HILOGD("enter");
500     std::string remoteAddr {};
501     bool checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
502     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
503 
504     auto func = [remoteAddr]() {
505         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
506         BluetoothHost *host = &BluetoothHost::GetDefaultHost();
507         int32_t err = host->RemovePair(remoteDevice);
508         HILOGI("err: %{public}d", err);
509         return NapiAsyncWorkRet(err);
510     };
511     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
512     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
513     asyncWork->Run();
514     return asyncWork->GetRet();
515 }
516 
CancelPairingDevice(napi_env env,napi_callback_info info)517 napi_value CancelPairingDevice(napi_env env, napi_callback_info info)
518 {
519     HILOGD("enter");
520     std::string remoteAddr{};
521     bool checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
522     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
523 
524     auto func = [remoteAddr]() {
525         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
526         int32_t err = remoteDevice.CancelPairing();
527         HILOGI("err: %{public}d", err);
528         return NapiAsyncWorkRet(err);
529     };
530     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
531     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
532     asyncWork->Run();
533     return asyncWork->GetRet();
534 }
535 
CheckPairCredibleDeviceParam(napi_env env,napi_callback_info info,std::string & addr,int & transport)536 napi_status CheckPairCredibleDeviceParam(napi_env env, napi_callback_info info, std::string &addr, int &transport)
537 {
538     size_t argc = ARGS_SIZE_THREE;
539     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
540     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
541     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO && argc != ARGS_SIZE_THREE, "Requires 2 or 3 arguments.", napi_invalid_arg);
542     NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], addr));
543     NAPI_BT_RETURN_IF(!ParseInt32(env, transport, argv[PARAM1]), "ParseInt32 failed", napi_invalid_arg);
544     NAPI_BT_RETURN_IF(!IsValidTransport(transport), "Invalid transport", napi_invalid_arg);
545     return napi_ok;
546 }
547 
PairCredibleDevice(napi_env env,napi_callback_info info)548 napi_value PairCredibleDevice(napi_env env, napi_callback_info info)
549 {
550     HILOGD("enter");
551     std::string remoteAddr = INVALID_MAC_ADDRESS;
552     int transport = BT_TRANSPORT_NONE;
553     auto status = CheckPairCredibleDeviceParam(env, info, remoteAddr, transport);
554     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
555 
556     auto func = [remoteAddr, transport]() {
557         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
558         int32_t err = remoteDevice.StartCrediblePair();
559         HILOGI("err: %{public}d", err);
560         return NapiAsyncWorkRet(err);
561     };
562     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
563     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
564     asyncWork->Run();
565     return asyncWork->GetRet();
566 }
567 
CheckGetProfileUuids(napi_env env,napi_callback_info info,std::string & address)568 napi_status CheckGetProfileUuids(napi_env env, napi_callback_info info, std::string &address)
569 {
570     size_t argc = ARGS_SIZE_TWO;
571     napi_value argv[ARGS_SIZE_TWO] = {0};
572     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
573     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE && argc != ARGS_SIZE_TWO, "Requires 1 or 2 arguments.", napi_invalid_arg);
574     NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, argv[PARAM0], address));
575     return napi_ok;
576 }
577 
GetLocalProfileUuids(napi_env env,napi_callback_info info)578 napi_value GetLocalProfileUuids(napi_env env, napi_callback_info info)
579 {
580     HILOGD("enter");
581     auto func = []() {
582         std::vector<std::string> uuids{};
583         int32_t err = BluetoothHost::GetDefaultHost().GetLocalProfileUuids(uuids);
584         HILOGI("err: %{public}d", err);
585         auto object = std::make_shared<NapiNativeUuidsArray>(uuids);
586         return NapiAsyncWorkRet(err, object);
587     };
588     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
589     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
590     asyncWork->Run();
591     return asyncWork->GetRet();
592 }
593 
GetRemoteProfileUuids(napi_env env,napi_callback_info info)594 napi_value GetRemoteProfileUuids(napi_env env, napi_callback_info info)
595 {
596     HILOGD("enter");
597     std::string address;
598     auto status = CheckGetProfileUuids(env, info, address);
599     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
600     auto func = [address]() {
601         std::vector<std::string> uuids{};
602         BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(address);
603         int32_t err = remoteDevice.GetDeviceUuids(uuids);
604         HILOGI("err: %{public}d", err);
605         auto object = std::make_shared<NapiNativeUuidsArray>(uuids);
606         return NapiAsyncWorkRet(err, object);
607     };
608     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
609     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
610     asyncWork->Run();
611     return asyncWork->GetRet();
612 }
613 
IsBluetoothDiscovering(napi_env env,napi_callback_info info)614 napi_value IsBluetoothDiscovering(napi_env env, napi_callback_info info)
615 {
616     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
617     bool isDiscovering = false;
618     int32_t err = host->IsBtDiscovering(isDiscovering);
619     napi_value result = nullptr;
620     NAPI_BT_ASSERT_RETURN(env, napi_get_boolean(env, isDiscovering, &result) == napi_ok, err, result);
621     NAPI_BT_ASSERT_RETURN(env, err = BT_NO_ERROR, err, result);
622     HILOGE("isBluetoothDiscovering :%{public}d", isDiscovering);
623     return result;
624 }
625 
GetPairState(napi_env env,napi_callback_info info)626 napi_value GetPairState(napi_env env, napi_callback_info info)
627 {
628     std::string remoteAddr = INVALID_MAC_ADDRESS;
629     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
630     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
631     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
632     int pairState = PAIR_NONE;
633     int32_t err = remoteDevice.GetPairState(pairState);
634     napi_value result = nullptr;
635     NAPI_BT_ASSERT_RETURN(env, napi_create_int32(env, pairState, &result) == napi_ok, err, result);
636     NAPI_BT_ASSERT_RETURN(env, err = BT_NO_ERROR, err, result);
637     HILOGE("getPairState :%{public}d", pairState);
638     return result;
639 }
640 
ConnectAllowedProfiles(napi_env env,napi_callback_info info)641 napi_value ConnectAllowedProfiles(napi_env env, napi_callback_info info)
642 {
643     HILOGI("enter");
644     std::string remoteAddr = INVALID_MAC_ADDRESS;
645     auto checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
646     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
647 
648     auto func = [remoteAddr]() {
649         BluetoothHost *host = &BluetoothHost::GetDefaultHost();
650         int32_t ret = host->ConnectAllowedProfiles(remoteAddr);
651         HILOGI("ret: %{public}d", ret);
652         return NapiAsyncWorkRet(ret);
653     };
654     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
655     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
656     asyncWork->Run();
657     return asyncWork->GetRet();
658 }
659 
DisconnectAllowedProfiles(napi_env env,napi_callback_info info)660 napi_value DisconnectAllowedProfiles(napi_env env, napi_callback_info info)
661 {
662     HILOGI("enter");
663     std::string remoteAddr = INVALID_MAC_ADDRESS;
664     auto checkRet = CheckDeviceAsyncParam(env, info, remoteAddr);
665     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM);
666 
667     auto func = [remoteAddr]() {
668         BluetoothHost *host = &BluetoothHost::GetDefaultHost();
669         int32_t ret = host->DisconnectAllowedProfiles(remoteAddr);
670         HILOGI("ret: %{public}d", ret);
671         return NapiAsyncWorkRet(ret);
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 
GetRemoteProductId(napi_env env,napi_callback_info info)679 napi_value GetRemoteProductId(napi_env env, napi_callback_info info)
680 {
681     HILOGD("start");
682     std::string remoteAddr = INVALID_MAC_ADDRESS;
683     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
684     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet, BT_ERR_INVALID_PARAM);
685 
686     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
687     std::string productId;
688     int32_t err = remoteDevice.GetDeviceProductId(productId);
689 
690     napi_value result = nullptr;
691     napi_create_string_utf8(env, productId.c_str(), productId.size(), &result);
692     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
693     HILOGI("GetRemoteProductId :%{public}s", productId.c_str());
694     return result;
695 }
696 
697 #endif
698 
ConnectionPropertyValueInit(napi_env env,napi_value exports)699 napi_value ConnectionPropertyValueInit(napi_env env, napi_value exports)
700 {
701     HILOGD("enter");
702     napi_value scanModeObj = ScanModeInit(env);
703     napi_value bondStateObj = BondStateInit(env);
704 #ifdef BLUETOOTH_API_SINCE_10
705     napi_value bluetoothTransportObject = BluetoothTransportInit(env);
706     napi_value pinTypeObject = PinTypeInit(env);
707 #endif
708     napi_property_descriptor exportProperties[] = {
709         DECLARE_NAPI_PROPERTY("ScanMode", scanModeObj),
710         DECLARE_NAPI_PROPERTY("BondState", bondStateObj),
711 #ifdef BLUETOOTH_API_SINCE_10
712         DECLARE_NAPI_PROPERTY("BluetoothTransport", bluetoothTransportObject),
713         DECLARE_NAPI_PROPERTY("PinType", pinTypeObject),
714 #endif
715     };
716     napi_define_properties(env, exports, sizeof(exportProperties) / sizeof(*exportProperties), exportProperties);
717     return exports;
718 }
719 
ScanModeInit(napi_env env)720 napi_value ScanModeInit(napi_env env)
721 {
722     HILOGD("enter");
723     napi_value scanMode = nullptr;
724     napi_create_object(env, &scanMode);
725     SetNamedPropertyByInteger(env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_NONE), "SCAN_MODE_NONE");
726     SetNamedPropertyByInteger(
727         env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_CONNECTABLE), "SCAN_MODE_CONNECTABLE");
728     SetNamedPropertyByInteger(
729         env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_GENERAL_DISCOVERABLE), "SCAN_MODE_GENERAL_DISCOVERABLE");
730     SetNamedPropertyByInteger(
731         env, scanMode, static_cast<int>(ScanMode::SCAN_MODE_LIMITED_DISCOVERABLE), "SCAN_MODE_LIMITED_DISCOVERABLE");
732     SetNamedPropertyByInteger(env,
733         scanMode,
734         static_cast<int>(ScanMode::SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE),
735         "SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE");
736     SetNamedPropertyByInteger(env,
737         scanMode,
738         static_cast<int>(ScanMode::SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE),
739         "SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE");
740     return scanMode;
741 }
742 
BondStateInit(napi_env env)743 napi_value BondStateInit(napi_env env)
744 {
745     HILOGD("enter");
746     napi_value bondState = nullptr;
747     napi_create_object(env, &bondState);
748     SetNamedPropertyByInteger(env, bondState, static_cast<int>(BondState::BOND_STATE_INVALID), "BOND_STATE_INVALID");
749     SetNamedPropertyByInteger(env, bondState, static_cast<int>(BondState::BOND_STATE_BONDING), "BOND_STATE_BONDING");
750     SetNamedPropertyByInteger(env, bondState, static_cast<int>(BondState::BOND_STATE_BONDED), "BOND_STATE_BONDED");
751     return bondState;
752 }
753 
754 #ifdef BLUETOOTH_API_SINCE_10
BluetoothTransportInit(napi_env env)755 napi_value BluetoothTransportInit(napi_env env)
756 {
757     HILOGD("enter");
758     napi_value bluetoothTransport = nullptr;
759     napi_create_object(env, &bluetoothTransport);
760     SetNamedPropertyByInteger(
761         env, bluetoothTransport, static_cast<int>(BluetoothTransport::TRANSPORT_BR_EDR), "TRANSPORT_BR_EDR");
762     SetNamedPropertyByInteger(
763         env, bluetoothTransport, static_cast<int>(BluetoothTransport::TRANSPORT_LE), "TRANSPORT_LE");
764     return bluetoothTransport;
765 }
766 
PinTypeInit(napi_env env)767 napi_value PinTypeInit(napi_env env)
768 {
769     HILOGD("enter");
770     napi_value pinType = nullptr;
771     napi_create_object(env, &pinType);
772     SetNamedPropertyByInteger(
773         env, pinType, static_cast<int>(PinType::PIN_TYPE_ENTER_PIN_CODE), "PIN_TYPE_ENTER_PIN_CODE");
774     SetNamedPropertyByInteger(
775         env, pinType, static_cast<int>(PinType::PIN_TYPE_ENTER_PASSKEY), "PIN_TYPE_ENTER_PASSKEY");
776     SetNamedPropertyByInteger(
777         env, pinType, static_cast<int>(PinType::PIN_TYPE_CONFIRM_PASSKEY), "PIN_TYPE_CONFIRM_PASSKEY");
778     SetNamedPropertyByInteger(
779         env, pinType, static_cast<int>(PinType::PIN_TYPE_NO_PASSKEY_CONSENT), "PIN_TYPE_NO_PASSKEY_CONSENT");
780     SetNamedPropertyByInteger(
781         env, pinType, static_cast<int>(PinType::PIN_TYPE_NOTIFY_PASSKEY), "PIN_TYPE_NOTIFY_PASSKEY");
782     SetNamedPropertyByInteger(
783         env, pinType, static_cast<int>(PinType::PIN_TYPE_DISPLAY_PIN_CODE), "PIN_TYPE_DISPLAY_PIN_CODE");
784     SetNamedPropertyByInteger(env, pinType, static_cast<int>(PinType::PIN_TYPE_OOB_CONSENT), "PIN_TYPE_OOB_CONSENT");
785     SetNamedPropertyByInteger(
786         env, pinType, static_cast<int>(PinType::PIN_TYPE_PIN_16_DIGITS), "PIN_TYPE_PIN_16_DIGITS");
787     return pinType;
788 }
789 #endif
790 
RegisterObserverToHost()791 void RegisterObserverToHost()
792 {
793     HILOGD("enter");
794     BluetoothHost &host = BluetoothHost::GetDefaultHost();
795     host.RegisterObserver(g_connectionObserver);
796     host.RegisterRemoteDeviceObserver(g_remoteDeviceObserver);
797 }
798 }  // namespace Bluetooth
799 }  // namespace OHOS