• 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 #ifndef LOG_TAG
16 #define LOG_TAG "bt_napi_access"
17 #endif
18 
19 #include "napi_bluetooth_access.h"
20 
21 #include "bluetooth_log.h"
22 #include "bluetooth_errorcode.h"
23 #include "bluetooth_host.h"
24 
25 #include "napi_bluetooth_error.h"
26 #include "napi_bluetooth_access_observer.h"
27 #include "napi_bluetooth_utils.h"
28 #include "napi_bluetooth_spp_client.h"
29 #include "parser/napi_parser_utils.h"
30 #include "hitrace_meter.h"
31 
32 namespace OHOS {
33 namespace Bluetooth {
34 namespace {
35 std::shared_ptr<NapiBluetoothAccessObserver> g_bluetoothAccessObserver =
36     std::make_shared<NapiBluetoothAccessObserver>();
37 }  // namespace
38 
DefineAccessJSFunction(napi_env env,napi_value exports)39 napi_value NapiAccess::DefineAccessJSFunction(napi_env env, napi_value exports)
40 {
41     HILOGD("enter");
42     RegisterAccessObserverToHost();
43     AccessPropertyValueInit(env, exports);
44     napi_property_descriptor desc[] = {
45         DECLARE_NAPI_FUNCTION("getState", GetState),
46         DECLARE_WRITABLE_NAPI_FUNCTION("enableBluetooth", EnableBluetooth),
47         DECLARE_NAPI_FUNCTION("disableBluetooth", DisableBluetooth),
48         DECLARE_NAPI_FUNCTION("restrictBluetooth", RestrictBluetooth),
49 #ifdef BLUETOOTH_API_SINCE_10
50         DECLARE_NAPI_FUNCTION("factoryReset", FactoryReset),
51         DECLARE_NAPI_FUNCTION("getLocalAddress", GetLocalAddress),
52         DECLARE_NAPI_FUNCTION("on", RegisterAccessObserver),
53         DECLARE_NAPI_FUNCTION("off", DeregisterAccessObserver),
54         DECLARE_NAPI_FUNCTION("addPersistentDeviceId", AddPersistentDeviceId),
55         DECLARE_NAPI_FUNCTION("deletePersistentDeviceId", DeletePersistentDeviceId),
56         DECLARE_NAPI_FUNCTION("getPersistentDeviceIds", GetPersistentDeviceIds),
57         DECLARE_NAPI_FUNCTION("isValidRandomDeviceId", isValidRandomDeviceId),
58         DECLARE_NAPI_FUNCTION("enableBluetoothAsync", EnableBluetoothAsync),
59         DECLARE_NAPI_FUNCTION("disableBluetoothAsync", DisableBluetoothAsync),
60         DECLARE_NAPI_FUNCTION("notifyDialogResult", NotifyDialogResult),
61 #endif
62     };
63     HITRACE_METER_NAME(HITRACE_TAG_OHOS, "access:napi_define_properties");
64     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
65     return exports;
66 }
67 
RegisterAccessObserverToHost()68 void NapiAccess::RegisterAccessObserverToHost()
69 {
70     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
71     host->RegisterObserver(g_bluetoothAccessObserver);
72 }
73 
EnableBluetooth(napi_env env,napi_callback_info info)74 napi_value NapiAccess::EnableBluetooth(napi_env env, napi_callback_info info)
75 {
76     HILOGI("enter");
77     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
78     int32_t ret = host->EnableBle();
79     // if return value is a specified error code, sync interface does not process.
80     if (ret == BT_ERR_DIALOG_FOR_USER_CONFIRM) {
81         ret = BT_NO_ERROR;
82     }
83     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
84     return NapiGetBooleanTrue(env);
85 }
86 
RestrictBluetooth(napi_env env,napi_callback_info info)87 napi_value NapiAccess::RestrictBluetooth(napi_env env, napi_callback_info info)
88 {
89     HILOGI("enter");
90     auto func = []() {
91         int32_t ret = BluetoothHost::GetDefaultHost().RestrictBluetooth();
92         return NapiAsyncWorkRet(ret);
93     };
94     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
95     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
96     asyncWork->Run();
97     return asyncWork->GetRet();
98 }
99 
DisableBluetooth(napi_env env,napi_callback_info info)100 napi_value NapiAccess::DisableBluetooth(napi_env env, napi_callback_info info)
101 {
102     HILOGI("enter");
103     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
104     int ret = host->DisableBt();
105     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
106     return NapiGetBooleanTrue(env);
107 }
108 
GetState(napi_env env,napi_callback_info info)109 napi_value NapiAccess::GetState(napi_env env, napi_callback_info info)
110 {
111     HILOGD("enter");
112     int32_t state = static_cast<int>(BluetoothHost::GetDefaultHost().GetBluetoothState());
113     napi_value result = nullptr;
114     napi_create_int32(env, state, &result);
115     return result;
116 }
117 
AccessPropertyValueInit(napi_env env,napi_value exports)118 napi_value NapiAccess::AccessPropertyValueInit(napi_env env, napi_value exports)
119 {
120     HILOGD("enter");
121     napi_value stateObj = StateChangeInit(env);
122     napi_value dialogTypeObj = DialogTypeInit(env);
123     napi_property_descriptor exportFuncs[] = {
124         DECLARE_NAPI_PROPERTY("BluetoothState", stateObj),
125         DECLARE_NAPI_PROPERTY("DialogType", dialogTypeObj),
126     };
127     HITRACE_METER_NAME(HITRACE_TAG_OHOS, "access:napi_define_properties");
128     napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
129     return exports;
130 }
131 
StateChangeInit(napi_env env)132 napi_value NapiAccess::StateChangeInit(napi_env env)
133 {
134     HILOGD("enter");
135     napi_value state = nullptr;
136     napi_create_object(env, &state);
137     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_OFF), "STATE_OFF");
138     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_ON), "STATE_TURNING_ON");
139     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_ON), "STATE_ON");
140     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_OFF), "STATE_TURNING_OFF");
141     SetNamedPropertyByInteger(
142         env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_ON), "STATE_BLE_TURNING_ON");
143     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_BLE_ON), "STATE_BLE_ON");
144     SetNamedPropertyByInteger(
145         env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_OFF), "STATE_BLE_TURNING_OFF");
146     return state;
147 }
148 
DialogTypeInit(napi_env env)149 napi_value NapiAccess::DialogTypeInit(napi_env env)
150 {
151     HILOGD("enter");
152     napi_value dialogType = nullptr;
153     napi_create_object(env, &dialogType);
154     SetNamedPropertyByInteger(env, dialogType, static_cast<int>(DialogBoxType::BLUETOOTH_SWITCH), "BLUETOOTH_SWITCH");
155     return dialogType;
156 }
157 
RegisterAccessObserver(napi_env env,napi_callback_info info)158 napi_value NapiAccess::RegisterAccessObserver(napi_env env, napi_callback_info info)
159 {
160     if (g_bluetoothAccessObserver) {
161         auto status = g_bluetoothAccessObserver->eventSubscribe_.Register(env, info);
162         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
163     }
164     return NapiGetUndefinedRet(env);
165 }
166 
DeregisterAccessObserver(napi_env env,napi_callback_info info)167 napi_value NapiAccess::DeregisterAccessObserver(napi_env env, napi_callback_info info)
168 {
169     if (g_bluetoothAccessObserver) {
170         auto status = g_bluetoothAccessObserver->eventSubscribe_.Deregister(env, info);
171         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
172     }
173     return NapiGetUndefinedRet(env);
174 }
175 
176 #ifdef BLUETOOTH_API_SINCE_10
FactoryReset(napi_env env,napi_callback_info info)177 napi_value NapiAccess::FactoryReset(napi_env env, napi_callback_info info)
178 {
179     HILOGD("enter");
180     auto func = []() {
181         int32_t ret = BluetoothHost::GetDefaultHost().BluetoothFactoryReset();
182         HILOGI("factoryReset ret: %{public}d", ret);
183         return NapiAsyncWorkRet(ret);
184     };
185     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
186     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
187     asyncWork->Run();
188     return asyncWork->GetRet();
189 }
190 
GetLocalAddress(napi_env env,napi_callback_info info)191 napi_value NapiAccess::GetLocalAddress(napi_env env, napi_callback_info info)
192 {
193     napi_value result = nullptr;
194     HILOGI("enter");
195     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
196     std::string localAddr = INVALID_MAC_ADDRESS;
197     int32_t err = host->GetLocalAddress(localAddr);
198     napi_create_string_utf8(env, localAddr.c_str(), localAddr.size(), &result);
199     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
200     return result;
201 }
202 #endif
203 
AddPersistentDeviceId(napi_env env,napi_callback_info info)204 napi_value NapiAccess::AddPersistentDeviceId(napi_env env, napi_callback_info info)
205 {
206     std::string deviceId = "";
207     auto status = CheckDeviceAddressParam(env, info, deviceId);
208     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
209 
210     auto func = [deviceId]() {
211         bool isValid = false;
212         std::vector<std::string> deviceIdVec = { deviceId };
213         int32_t ret = BluetoothHost::GetDefaultHost().ProcessRandomDeviceIdCommand(
214             static_cast<int32_t>(RandomDeviceIdCommand::ADD), deviceIdVec, isValid);
215         HILOGI("AddPersistentDeviceId ret: %{public}d", ret);
216         return NapiAsyncWorkRet(ret);
217     };
218     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
219     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
220     asyncWork->Run();
221     return asyncWork->GetRet();
222 }
223 
DeletePersistentDeviceId(napi_env env,napi_callback_info info)224 napi_value NapiAccess::DeletePersistentDeviceId(napi_env env, napi_callback_info info)
225 {
226     std::string deviceId = "";
227     auto status = CheckDeviceAddressParam(env, info, deviceId);
228     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
229 
230     auto func = [deviceId]() mutable {
231         bool isValid = false;
232         std::vector<std::string> deviceIdVec = { deviceId };
233         int32_t ret = BluetoothHost::GetDefaultHost().ProcessRandomDeviceIdCommand(
234             static_cast<int32_t>(RandomDeviceIdCommand::DELETE), deviceIdVec, isValid);
235         HILOGI("DeletePersistentDeviceId ret: %{public}d", ret);
236         return NapiAsyncWorkRet(ret);
237     };
238     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
239     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
240     asyncWork->Run();
241     return asyncWork->GetRet();
242 }
243 
GetPersistentDeviceIds(napi_env env,napi_callback_info info)244 napi_value NapiAccess::GetPersistentDeviceIds(napi_env env, napi_callback_info info)
245 {
246     bool isValid = false;
247     std::vector<std::string> deviceIdVec;
248     int32_t ret = BluetoothHost::GetDefaultHost().ProcessRandomDeviceIdCommand(
249         static_cast<int32_t>(RandomDeviceIdCommand::GET), deviceIdVec, isValid);
250     HILOGI("GetPersistentDeviceIds ret: %{public}d", ret);
251     NAPI_BT_ASSERT_RETURN_UNDEF(env, ret == BT_NO_ERROR, ret);
252 
253     NapiNativeStringArray object(deviceIdVec);
254     return object.ToNapiValue(env);
255 }
256 
isValidRandomDeviceId(napi_env env,napi_callback_info info)257 napi_value NapiAccess::isValidRandomDeviceId(napi_env env, napi_callback_info info)
258 {
259     std::string deviceId = "";
260     auto status = CheckDeviceAddressParam(env, info, deviceId);
261     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
262 
263     bool isValid = false;
264     std::vector<std::string> deviceIdVec = { deviceId };
265     int32_t ret = BluetoothHost::GetDefaultHost().ProcessRandomDeviceIdCommand(
266         static_cast<int32_t>(RandomDeviceIdCommand::IS_VALID), deviceIdVec, isValid);
267     HILOGI("isValidRandomDeviceId ret: %{public}d", ret);
268     NAPI_BT_ASSERT_RETURN_UNDEF(env, ret == BT_NO_ERROR, ret);
269 
270     NapiNativeBool object(isValid);
271     return object.ToNapiValue(env);
272 }
273 
EnableBluetoothAsync(napi_env env,napi_callback_info info)274 napi_value NapiAccess::EnableBluetoothAsync(napi_env env, napi_callback_info info)
275 {
276     HILOGI("enter");
277     auto func = []() {
278         bool isAsync = true;
279         int32_t ret = BluetoothHost::GetDefaultHost().EnableBle(isAsync);
280         HILOGI("EnableBluetoothAsync ret: %{public}d", ret);
281         return NapiAsyncWorkRet(ret);
282     };
283     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
284     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
285     asyncWork->Run();
286     return asyncWork->GetRet();
287 }
288 
DisableBluetoothAsync(napi_env env,napi_callback_info info)289 napi_value NapiAccess::DisableBluetoothAsync(napi_env env, napi_callback_info info)
290 {
291     HILOGI("enter");
292     auto func = []() {
293         bool isAsync = true;
294         int32_t ret = BluetoothHost::GetDefaultHost().DisableBt(isAsync);
295         HILOGI("DisableBluetoothAsync ret: %{public}d", ret);
296         return NapiAsyncWorkRet(ret);
297     };
298     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
299     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
300     asyncWork->Run();
301     return asyncWork->GetRet();
302 }
303 
ParseNotifyDialogResultParams(napi_env env,napi_value object,NapiAccess::NotifyDialogResultParams & params)304 napi_status ParseNotifyDialogResultParams(napi_env env, napi_value object,
305     NapiAccess::NotifyDialogResultParams &params)
306 {
307     HILOGD("enter");
308     NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"dialogType", "dialogResult"}));
309 
310     uint32_t tmpDialogType = INVALID_DIALOG_TYPE;
311     bool tmpDialogResult = false;
312     NAPI_BT_CALL_RETURN(NapiParseObjectUint32(env, object, "dialogType", tmpDialogType));
313     NAPI_BT_CALL_RETURN(NapiParseObjectBoolean(env, object, "dialogResult", tmpDialogResult));
314 
315     HILOGI("dialogType: %{public}u, dialogResult: %{public}d", tmpDialogType, tmpDialogResult);
316 
317     params.dialogType = tmpDialogType;
318     params.dialogResult = tmpDialogResult;
319     return napi_ok;
320 }
321 
NotifyDialogResult(napi_env env,napi_callback_info info)322 napi_value NapiAccess::NotifyDialogResult(napi_env env, napi_callback_info info)
323 {
324     HILOGI("enter");
325     size_t argc = ARGS_SIZE_ONE;
326     napi_value argv[ARGS_SIZE_ONE] = {nullptr};
327     napi_value thisVar = nullptr;
328     auto checkRes = napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL);
329     NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRes == napi_ok, BT_ERR_INVALID_PARAM);
330     NAPI_BT_ASSERT_RETURN_UNDEF(env, argc == ARGS_SIZE_ONE, BT_ERR_INVALID_PARAM);
331 
332     NotifyDialogResultParams params = { INVALID_DIALOG_TYPE, false};
333     auto status = ParseNotifyDialogResultParams(env, argv[PARAM0], params);
334     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
335     uint32_t dialogType = params.dialogType;
336     bool dialogResult = params.dialogResult;
337     auto func = [dialogType, dialogResult]() {
338         int32_t ret = BluetoothHost::GetDefaultHost().NotifyDialogResult(dialogType, dialogResult);
339         HILOGI("NotifyDialogResult err: %{public}d", ret);
340         return NapiAsyncWorkRet(ret);
341     };
342     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
343     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
344     asyncWork->Run();
345     return asyncWork->GetRet();
346 }
347 
348 }  // namespace Bluetooth
349 }  // namespace OHOS
350