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_access.h"
17
18 #include "bluetooth_log.h"
19 #include "bluetooth_errorcode.h"
20 #include "bluetooth_host.h"
21
22 #include "napi_bluetooth_error.h"
23 #include "napi_bluetooth_access_observer.h"
24 #include "napi_bluetooth_utils.h"
25 #include "napi_bluetooth_spp_client.h"
26 #include "../parser/napi_parser_utils.h"
27 #include "hitrace_meter.h"
28
29 namespace OHOS {
30 namespace Bluetooth {
31 namespace {
32 std::shared_ptr<NapiBluetoothAccessObserver> g_bluetoothAccessObserver =
33 std::make_shared<NapiBluetoothAccessObserver>();
34 } // namespace
35
DefineAccessJSFunction(napi_env env, napi_value exports)36 napi_value NapiAccess::DefineAccessJSFunction(napi_env env, napi_value exports)
37 {
38 HILOGD("enter");
39 RegisterAccessObserverToHost();
40 AccessPropertyValueInit(env, exports);
41 napi_property_descriptor desc[] = {
42 DECLARE_NAPI_FUNCTION("getState", GetState),
43 DECLARE_NAPI_FUNCTION("enableBluetooth", EnableBluetooth),
44 DECLARE_NAPI_FUNCTION("disableBluetooth", DisableBluetooth),
45 DECLARE_NAPI_FUNCTION("restrictBluetooth", RestrictBluetooth),
46 #ifdef BLUETOOTH_API_SINCE_10
47 DECLARE_NAPI_FUNCTION("factoryReset", FactoryReset),
48 DECLARE_NAPI_FUNCTION("getLocalAddress", GetLocalAddress),
49 DECLARE_NAPI_FUNCTION("on", RegisterAccessObserver),
50 DECLARE_NAPI_FUNCTION("off", DeregisterAccessObserver),
51 #endif
52 };
53 HITRACE_METER_NAME(HITRACE_TAG_OHOS, "access:napi_define_properties");
54 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
55 return exports;
56 }
57
RegisterAccessObserverToHost()58 void NapiAccess::RegisterAccessObserverToHost()
59 {
60 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
61 host->RegisterObserver(g_bluetoothAccessObserver);
62 }
63
EnableBluetooth(napi_env env, napi_callback_info info)64 napi_value NapiAccess::EnableBluetooth(napi_env env, napi_callback_info info)
65 {
66 HILOGI("enter");
67 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
68 int32_t ret = host->EnableBle();
69 NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
70 return NapiGetBooleanTrue(env);
71 }
72
RestrictBluetooth(napi_env env, napi_callback_info info)73 napi_value NapiAccess::RestrictBluetooth(napi_env env, napi_callback_info info)
74 {
75 HILOGI("enter");
76 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
77 int32_t ret = host->RestrictBluetooth();
78 NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
79 return NapiGetBooleanTrue(env);
80 }
81
DisableBluetooth(napi_env env, napi_callback_info info)82 napi_value NapiAccess::DisableBluetooth(napi_env env, napi_callback_info info)
83 {
84 HILOGI("enter");
85 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
86 int ret = host->DisableBt();
87 NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
88 return NapiGetBooleanTrue(env);
89 }
90
GetState(napi_env env, napi_callback_info info)91 napi_value NapiAccess::GetState(napi_env env, napi_callback_info info)
92 {
93 HILOGD("enter");
94 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
95 int32_t state = BTStateID::STATE_TURN_OFF;
96 int32_t err = host->GetBtState(state);
97 NAPI_BT_ASSERT_RETURN_FALSE(env, err == NO_ERROR, err);
98 int32_t status = static_cast<int32_t>(BluetoothState::STATE_OFF);
99 switch (state) {
100 case BTStateID::STATE_TURNING_ON:
101 HILOGI("STATE_TURNING_ON(1)");
102 status = static_cast<int32_t>(BluetoothState::STATE_TURNING_ON);
103 break;
104 case BTStateID::STATE_TURN_ON:
105 HILOGD("STATE_ON(2)");
106 status = static_cast<int32_t>(BluetoothState::STATE_ON);
107 break;
108 case BTStateID::STATE_TURNING_OFF:
109 HILOGI("STATE_TURNING_OFF(3)");
110 status = static_cast<int32_t>(BluetoothState::STATE_TURNING_OFF);
111 break;
112 case BTStateID::STATE_TURN_OFF:
113 HILOGD("STATE_OFF(0)");
114 status = static_cast<int32_t>(BluetoothState::STATE_OFF);
115 break;
116 default:
117 HILOGE("get state failed");
118 break;
119 }
120
121 bool enableBle = host->IsBleEnabled();
122 if (enableBle && (state == BTStateID::STATE_TURN_OFF)) {
123 HILOGD("BR off and BLE on, STATE_BLE_ON(5)");
124 status = static_cast<int32_t>(BluetoothState::STATE_BLE_ON);
125 } else if (!enableBle && (state == BTStateID::STATE_TURN_OFF)) {
126 status = static_cast<int32_t>(BluetoothState::STATE_OFF);
127 }
128
129 napi_value result = nullptr;
130 napi_create_int32(env, status, &result);
131 return result;
132 }
133
AccessPropertyValueInit(napi_env env, napi_value exports)134 napi_value NapiAccess::AccessPropertyValueInit(napi_env env, napi_value exports)
135 {
136 HILOGD("enter");
137 napi_value stateObj = StateChangeInit(env);
138 napi_property_descriptor exportFuncs[] = {
139 DECLARE_NAPI_PROPERTY("BluetoothState", stateObj),
140 };
141 HITRACE_METER_NAME(HITRACE_TAG_OHOS, "access:napi_define_properties");
142 napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
143 return exports;
144 }
145
StateChangeInit(napi_env env)146 napi_value NapiAccess::StateChangeInit(napi_env env)
147 {
148 HILOGD("enter");
149 napi_value state = nullptr;
150 napi_create_object(env, &state);
151 SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_OFF), "STATE_OFF");
152 SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_ON), "STATE_TURNING_ON");
153 SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_ON), "STATE_ON");
154 SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_OFF), "STATE_TURNING_OFF");
155 SetNamedPropertyByInteger(
156 env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_ON), "STATE_BLE_TURNING_ON");
157 SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_BLE_ON), "STATE_BLE_ON");
158 SetNamedPropertyByInteger(
159 env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_OFF), "STATE_BLE_TURNING_OFF");
160 return state;
161 }
162
RegisterAccessObserver(napi_env env, napi_callback_info info)163 napi_value NapiAccess::RegisterAccessObserver(napi_env env, napi_callback_info info)
164 {
165 if (g_bluetoothAccessObserver) {
166 auto status = g_bluetoothAccessObserver->eventSubscribe_.Register(env, info);
167 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
168 }
169 return NapiGetUndefinedRet(env);
170 }
171
DeregisterAccessObserver(napi_env env, napi_callback_info info)172 napi_value NapiAccess::DeregisterAccessObserver(napi_env env, napi_callback_info info)
173 {
174 if (g_bluetoothAccessObserver) {
175 auto status = g_bluetoothAccessObserver->eventSubscribe_.Deregister(env, info);
176 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
177 }
178 return NapiGetUndefinedRet(env);
179 }
180
181 #ifdef BLUETOOTH_API_SINCE_10
FactoryReset(napi_env env, napi_callback_info info)182 napi_value NapiAccess::FactoryReset(napi_env env, napi_callback_info info)
183 {
184 HILOGD("enter");
185 auto func = []() {
186 int32_t ret = BluetoothHost::GetDefaultHost().BluetoothFactoryReset();
187 HILOGI("factoryReset ret: %{public}d", ret);
188 return NapiAsyncWorkRet(ret);
189 };
190 auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
191 NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
192 asyncWork->Run();
193 return asyncWork->GetRet();
194 }
195
GetLocalAddress(napi_env env, napi_callback_info info)196 napi_value NapiAccess::GetLocalAddress(napi_env env, napi_callback_info info)
197 {
198 napi_value result = nullptr;
199 HILOGI("enter");
200 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
201 std::string localAddr = INVALID_MAC_ADDRESS;
202 int32_t err = host->GetLocalAddress(localAddr);
203 napi_create_string_utf8(env, localAddr.c_str(), localAddr.size(), &result);
204 NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
205 return result;
206 }
207 #endif
208 } // namespace Bluetooth
209 } // namespace OHOS
210