• 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_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 
28 namespace OHOS {
29 namespace Bluetooth {
30 namespace {
31 std::shared_ptr<NapiBluetoothAccessObserver> g_bluetoothAccessObserver =
32     std::make_shared<NapiBluetoothAccessObserver>();
33 }  // namespace
34 
DefineAccessJSFunction(napi_env env,napi_value exports)35 napi_value NapiAccess::DefineAccessJSFunction(napi_env env, napi_value exports)
36 {
37     HILOGD("enter");
38     RegisterAccessObserverToHost();
39     AccessPropertyValueInit(env, exports);
40     napi_property_descriptor desc[] = {
41         DECLARE_NAPI_FUNCTION("getState", GetState),
42         DECLARE_NAPI_FUNCTION("enableBluetooth", EnableBluetooth),
43         DECLARE_NAPI_FUNCTION("disableBluetooth", DisableBluetooth),
44 #ifdef BLUETOOTH_API_SINCE_10
45         DECLARE_NAPI_FUNCTION("factoryReset", FactoryReset),
46         DECLARE_NAPI_FUNCTION("getLocalAddress", GetLocalAddress),
47         DECLARE_NAPI_FUNCTION("on", RegisterAccessObserver),
48         DECLARE_NAPI_FUNCTION("off", DeregisterAccessObserver),
49 #endif
50     };
51     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
52     return exports;
53 }
54 
RegisterAccessObserverToHost()55 void NapiAccess::RegisterAccessObserverToHost()
56 {
57     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
58     host->RegisterObserver(g_bluetoothAccessObserver);
59 }
60 
EnableBluetooth(napi_env env,napi_callback_info info)61 napi_value NapiAccess::EnableBluetooth(napi_env env, napi_callback_info info)
62 {
63     HILOGI("enter");
64     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
65     int32_t ret = host->EnableBle();
66     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
67     return NapiGetBooleanTrue(env);
68 }
69 
DisableBluetooth(napi_env env,napi_callback_info info)70 napi_value NapiAccess::DisableBluetooth(napi_env env, napi_callback_info info)
71 {
72     HILOGI("enter");
73     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
74     int ret = host->DisableBt();
75     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_NO_ERROR, ret);
76     return NapiGetBooleanTrue(env);
77 }
78 
GetState(napi_env env,napi_callback_info info)79 napi_value NapiAccess::GetState(napi_env env, napi_callback_info info)
80 {
81     HILOGD("enter");
82     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
83     int32_t state = BTStateID::STATE_TURN_OFF;
84     int32_t err = host->GetBtState(state);
85     NAPI_BT_ASSERT_RETURN_FALSE(env, err == NO_ERROR, err);
86     int32_t status = static_cast<int32_t>(BluetoothState::STATE_OFF);
87     switch (state) {
88         case BTStateID::STATE_TURNING_ON:
89             HILOGI("STATE_TURNING_ON(1)");
90             status = static_cast<int32_t>(BluetoothState::STATE_TURNING_ON);
91             break;
92         case BTStateID::STATE_TURN_ON:
93             HILOGD("STATE_ON(2)");
94             status = static_cast<int32_t>(BluetoothState::STATE_ON);
95             break;
96         case BTStateID::STATE_TURNING_OFF:
97             HILOGI("STATE_TURNING_OFF(3)");
98             status = static_cast<int32_t>(BluetoothState::STATE_TURNING_OFF);
99             break;
100         case BTStateID::STATE_TURN_OFF:
101             HILOGI("STATE_OFF(0)");
102             status = static_cast<int32_t>(BluetoothState::STATE_OFF);
103             break;
104         default:
105             HILOGE("get state failed");
106             break;
107     }
108 
109     bool enableBle = host->IsBleEnabled();
110     if (enableBle && (state == BTStateID::STATE_TURN_OFF)) {
111         HILOGI("BR off and BLE on, STATE_BLE_ON(5)");
112         status = static_cast<int32_t>(BluetoothState::STATE_BLE_ON);
113     } else if (!enableBle && (state == BTStateID::STATE_TURN_OFF)) {
114         status = static_cast<int32_t>(BluetoothState::STATE_OFF);
115     }
116 
117     napi_value result = nullptr;
118     napi_create_int32(env, status, &result);
119     return result;
120 }
121 
AccessPropertyValueInit(napi_env env,napi_value exports)122 napi_value NapiAccess::AccessPropertyValueInit(napi_env env, napi_value exports)
123 {
124     HILOGD("enter");
125     napi_value stateObj = StateChangeInit(env);
126     napi_property_descriptor exportFuncs[] = {
127         DECLARE_NAPI_PROPERTY("BluetoothState", stateObj),
128     };
129     napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
130     return exports;
131 }
132 
StateChangeInit(napi_env env)133 napi_value NapiAccess::StateChangeInit(napi_env env)
134 {
135     HILOGD("enter");
136     napi_value state = nullptr;
137     napi_create_object(env, &state);
138     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_OFF), "STATE_OFF");
139     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_ON), "STATE_TURNING_ON");
140     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_ON), "STATE_ON");
141     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_TURNING_OFF), "STATE_TURNING_OFF");
142     SetNamedPropertyByInteger(
143         env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_ON), "STATE_BLE_TURNING_ON");
144     SetNamedPropertyByInteger(env, state, static_cast<int>(BluetoothState::STATE_BLE_ON), "STATE_BLE_ON");
145     SetNamedPropertyByInteger(
146         env, state, static_cast<int>(BluetoothState::STATE_BLE_TURNING_OFF), "STATE_BLE_TURNING_OFF");
147     return state;
148 }
149 
IsValidObserverType(const std::string & outType)150 static bool IsValidObserverType(const std::string &outType)
151 {
152     return outType == REGISTER_STATE_CHANGE_TYPE;
153 }
154 
NapiParseObserverType(napi_env env,napi_value value,std::string & outType)155 static napi_status NapiParseObserverType(napi_env env, napi_value value, std::string &outType)
156 {
157     std::string type{};
158     NAPI_BT_CALL_RETURN(NapiParseString(env, value, type));
159     HILOGI("type: %{public}s", type.c_str());
160     NAPI_BT_RETURN_IF(!IsValidObserverType(type), "Invalid type", napi_invalid_arg);
161     outType = std::move(type);
162     return napi_ok;
163 }
164 
CheckAccessObserverParams(napi_env env,napi_callback_info info)165 static napi_status CheckAccessObserverParams(napi_env env, napi_callback_info info)
166 {
167     size_t argc = ARGS_SIZE_TWO;
168     napi_value argv[ARGS_SIZE_TWO] = {0};
169     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
170     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_TWO, "Requires 2 arguments.", napi_invalid_arg);
171     std::string type;
172     NAPI_BT_CALL_RETURN(NapiParseObserverType(env, argv[PARAM0], type));
173     HILOGI("%{public}s is registered", type.c_str());
174 
175     g_bluetoothAccessObserver->napiStateChangeCallback_ = std::make_shared<NapiCallback>(env, argv[PARAM1]);
176     return napi_ok;
177 }
178 
RegisterAccessObserver(napi_env env,napi_callback_info info)179 napi_value NapiAccess::RegisterAccessObserver(napi_env env, napi_callback_info info)
180 {
181     auto status = CheckAccessObserverParams(env, info);
182     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
183     return NapiGetUndefinedRet(env);
184 }
185 
CheckAccessDeregisterObserver(napi_env env,napi_callback_info info)186 static napi_status CheckAccessDeregisterObserver(napi_env env, napi_callback_info info)
187 {
188     size_t argc = ARGS_SIZE_TWO;
189     napi_value argv[ARGS_SIZE_TWO] = {0};
190     napi_value thisVar = nullptr;
191     NAPI_BT_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
192     NAPI_BT_RETURN_IF(argc != ARGS_SIZE_ONE && argc != ARGS_SIZE_TWO, "Requires 1 or 2 arguments.", napi_invalid_arg);
193 
194     std::string type;
195     NAPI_BT_CALL_RETURN(NapiParseObserverType(env, argv[PARAM0], type));
196     HILOGI("%{public}s is unregistered", type.c_str());
197 
198     g_bluetoothAccessObserver->napiStateChangeCallback_ = nullptr;
199     return napi_ok;
200 }
201 
DeregisterAccessObserver(napi_env env,napi_callback_info info)202 napi_value NapiAccess::DeregisterAccessObserver(napi_env env, napi_callback_info info)
203 {
204     HILOGI("enter");
205     auto status = CheckAccessDeregisterObserver(env, info);
206     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
207     return NapiGetUndefinedRet(env);
208 }
209 
210 #ifdef BLUETOOTH_API_SINCE_10
FactoryReset(napi_env env,napi_callback_info info)211 napi_value NapiAccess::FactoryReset(napi_env env, napi_callback_info info)
212 {
213     HILOGD("enter");
214     auto func = []() {
215         int32_t ret = BluetoothHost::GetDefaultHost().BluetoothFactoryReset();
216         HILOGI("factoryReset ret: %{public}d", ret);
217         return NapiAsyncWorkRet(ret);
218     };
219     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
220     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
221     asyncWork->Run();
222     return asyncWork->GetRet();
223 }
224 
GetLocalAddress(napi_env env,napi_callback_info info)225 napi_value NapiAccess::GetLocalAddress(napi_env env, napi_callback_info info)
226 {
227     napi_value result = nullptr;
228     HILOGI("enter");
229     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
230     std::string localAddr = INVALID_MAC_ADDRESS;
231     int32_t err = host->GetLocalAddress(localAddr);
232     napi_create_string_utf8(env, localAddr.c_str(), localAddr.size(), &result);
233     NAPI_BT_ASSERT_RETURN(env, err == BT_NO_ERROR, err, result);
234     return result;
235 }
236 #endif
237 }  // namespace Bluetooth
238 }  // namespace OHOS
239