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_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 #endif
55     };
56     HITRACE_METER_NAME(HITRACE_TAG_OHOS, "access:napi_define_properties");
57     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
58     return exports;
59 }
60 
RegisterAccessObserverToHost()61 void NapiAccess::RegisterAccessObserverToHost()
62 {
63     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
64     host->RegisterObserver(g_bluetoothAccessObserver);
65 }
66 
EnableBluetooth(napi_env env,napi_callback_info info)67 napi_value NapiAccess::EnableBluetooth(napi_env env, napi_callback_info info)
68 {
69     HILOGI("enter");
70     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
71     int32_t ret = host->EnableBle();
72     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
73     return NapiGetBooleanTrue(env);
74 }
75 
RestrictBluetooth(napi_env env,napi_callback_info info)76 napi_value NapiAccess::RestrictBluetooth(napi_env env, napi_callback_info info)
77 {
78     HILOGI("enter");
79     auto func = []() {
80         int32_t ret = BluetoothHost::GetDefaultHost().RestrictBluetooth();
81         return NapiAsyncWorkRet(ret);
82     };
83     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
84     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
85     asyncWork->Run();
86     return asyncWork->GetRet();
87 }
88 
DisableBluetooth(napi_env env,napi_callback_info info)89 napi_value NapiAccess::DisableBluetooth(napi_env env, napi_callback_info info)
90 {
91     HILOGI("enter");
92     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
93     int ret = host->DisableBt();
94     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
95     return NapiGetBooleanTrue(env);
96 }
97 
GetState(napi_env env,napi_callback_info info)98 napi_value NapiAccess::GetState(napi_env env, napi_callback_info info)
99 {
100     HILOGD("enter");
101     int32_t state = static_cast<int>(BluetoothHost::GetDefaultHost().GetBluetoothState());
102     napi_value result = nullptr;
103     napi_create_int32(env, state, &result);
104     return result;
105 }
106 
AccessPropertyValueInit(napi_env env,napi_value exports)107 napi_value NapiAccess::AccessPropertyValueInit(napi_env env, napi_value exports)
108 {
109     HILOGD("enter");
110     napi_value stateObj = StateChangeInit(env);
111     napi_property_descriptor exportFuncs[] = {
112         DECLARE_NAPI_PROPERTY("BluetoothState", stateObj),
113     };
114     HITRACE_METER_NAME(HITRACE_TAG_OHOS, "access:napi_define_properties");
115     napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
116     return exports;
117 }
118 
StateChangeInit(napi_env env)119 napi_value NapiAccess::StateChangeInit(napi_env env)
120 {
121     HILOGD("enter");
122     napi_value state = nullptr;
123     napi_create_object(env, &state);
124     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_OFF), "STATE_OFF");
125     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_ON), "STATE_TURNING_ON");
126     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_ON), "STATE_ON");
127     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_OFF), "STATE_TURNING_OFF");
128     SetNamedPropertyByInteger(
129         env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_ON), "STATE_BLE_TURNING_ON");
130     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_BLE_ON), "STATE_BLE_ON");
131     SetNamedPropertyByInteger(
132         env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_OFF), "STATE_BLE_TURNING_OFF");
133     return state;
134 }
135 
RegisterAccessObserver(napi_env env,napi_callback_info info)136 napi_value NapiAccess::RegisterAccessObserver(napi_env env, napi_callback_info info)
137 {
138     if (g_bluetoothAccessObserver) {
139         auto status = g_bluetoothAccessObserver->eventSubscribe_.Register(env, info);
140         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
141     }
142     return NapiGetUndefinedRet(env);
143 }
144 
DeregisterAccessObserver(napi_env env,napi_callback_info info)145 napi_value NapiAccess::DeregisterAccessObserver(napi_env env, napi_callback_info info)
146 {
147     if (g_bluetoothAccessObserver) {
148         auto status = g_bluetoothAccessObserver->eventSubscribe_.Deregister(env, info);
149         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
150     }
151     return NapiGetUndefinedRet(env);
152 }
153 
154 #ifdef BLUETOOTH_API_SINCE_10
FactoryReset(napi_env env,napi_callback_info info)155 napi_value NapiAccess::FactoryReset(napi_env env, napi_callback_info info)
156 {
157     HILOGD("enter");
158     auto func = []() {
159         int32_t ret = BluetoothHost::GetDefaultHost().BluetoothFactoryReset();
160         HILOGI("factoryReset ret: %{public}d", ret);
161         return NapiAsyncWorkRet(ret);
162     };
163     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
164     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
165     asyncWork->Run();
166     return asyncWork->GetRet();
167 }
168 
GetLocalAddress(napi_env env,napi_callback_info info)169 napi_value NapiAccess::GetLocalAddress(napi_env env, napi_callback_info info)
170 {
171     napi_value result = nullptr;
172     HILOGI("enter");
173     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
174     std::string localAddr = INVALID_MAC_ADDRESS;
175     int32_t err = host->GetLocalAddress(localAddr);
176     napi_create_string_utf8(env, localAddr.c_str(), localAddr.size(), &result);
177     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
178     return result;
179 }
180 #endif
181 }  // namespace Bluetooth
182 }  // namespace OHOS
183