1 /*
2 * Copyright (C) 2021-2022 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_hfp_hf"
17 #endif
18
19 #include "napi_bluetooth_hfp_hf.h"
20 #include "napi_bluetooth_profile.h"
21 #include "bluetooth_errorcode.h"
22 #include "bluetooth_hfp_hf.h"
23 #include "napi_bluetooth_error.h"
24 #include "napi_bluetooth_event.h"
25 #include "napi_event_subscribe_module.h"
26
27 namespace OHOS {
28 namespace Bluetooth {
29 using namespace std;
30
31 std::shared_ptr<NapiHandsFreeUnitObserver> NapiHandsFreeUnit::observer_ =
32 std::make_shared<NapiHandsFreeUnitObserver>();
33 bool NapiHandsFreeUnit::isRegistered_ = false;
34
DefineHandsFreeUnitJSClass(napi_env env)35 void NapiHandsFreeUnit::DefineHandsFreeUnitJSClass(napi_env env)
36 {
37 napi_value constructor;
38 napi_property_descriptor properties[] = {
39 DECLARE_NAPI_FUNCTION("on", On),
40 DECLARE_NAPI_FUNCTION("off", Off),
41 DECLARE_NAPI_FUNCTION("getConnectionDevices", GetConnectionDevices),
42 DECLARE_NAPI_FUNCTION("getDeviceState", GetDeviceState),
43 DECLARE_NAPI_FUNCTION("getScoState", GetScoState),
44 DECLARE_NAPI_FUNCTION("connect", Connect),
45 DECLARE_NAPI_FUNCTION("disconnect", Disconnect),
46 DECLARE_NAPI_FUNCTION("connectSco", ConnectSco),
47 DECLARE_NAPI_FUNCTION("disconnectSco", DisconnectSco),
48 DECLARE_NAPI_FUNCTION("sendDTMF", SendDTMF),
49 };
50
51 napi_define_class(env, "HandsFreeUnit", NAPI_AUTO_LENGTH, HandsFreeUnitConstructor, nullptr,
52 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
53
54 napi_value napiProfile;
55 napi_new_instance(env, constructor, 0, nullptr, &napiProfile);
56 NapiProfile::SetProfile(env, ProfileId::PROFILE_HANDS_FREE_UNIT, napiProfile);
57 }
58
HandsFreeUnitConstructor(napi_env env,napi_callback_info info)59 napi_value NapiHandsFreeUnit::HandsFreeUnitConstructor(napi_env env, napi_callback_info info)
60 {
61 napi_value thisVar = nullptr;
62 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
63 return thisVar;
64 }
65
On(napi_env env,napi_callback_info info)66 napi_value NapiHandsFreeUnit::On(napi_env env, napi_callback_info info)
67 {
68 if (observer_) {
69 auto status = observer_->eventSubscribe_.Register(env, info);
70 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
71 }
72 if (!isRegistered_) {
73 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
74 profile->RegisterObserver(observer_);
75 isRegistered_ = true;
76 }
77 return NapiGetUndefinedRet(env);
78 }
79
Off(napi_env env,napi_callback_info info)80 napi_value NapiHandsFreeUnit::Off(napi_env env, napi_callback_info info)
81 {
82 if (observer_) {
83 auto status = observer_->eventSubscribe_.Deregister(env, info);
84 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
85 }
86 return NapiGetUndefinedRet(env);
87 }
88
GetConnectionDevices(napi_env env,napi_callback_info info)89 napi_value NapiHandsFreeUnit::GetConnectionDevices(napi_env env, napi_callback_info info)
90 {
91 HILOGI("enter");
92 napi_value ret = nullptr;
93 napi_create_array(env, &ret);
94 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
95 vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };
96 vector<BluetoothRemoteDevice> devices = profile->GetDevicesByStates(states);
97 vector<string> deviceVector;
98 for (auto &device: devices) {
99 deviceVector.push_back(device.GetDeviceAddr());
100 }
101 ConvertStringVectorToJS(env, ret, deviceVector);
102 return ret;
103 }
104
GetDeviceState(napi_env env,napi_callback_info info)105 napi_value NapiHandsFreeUnit::GetDeviceState(napi_env env, napi_callback_info info)
106 {
107 HILOGI("enter");
108 size_t expectedArgsCount = ARGS_SIZE_ONE;
109 size_t argc = expectedArgsCount;
110 napi_value argv[ARGS_SIZE_ONE] = {0};
111 napi_value thisVar = nullptr;
112
113 napi_value ret = nullptr;
114 napi_get_undefined(env, &ret);
115
116 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
117 if (argc != expectedArgsCount) {
118 HILOGE("Requires 1 argument.");
119 return ret;
120 }
121 string deviceId;
122 if (!ParseString(env, deviceId, argv[PARAM0])) {
123 HILOGE("string expected.");
124 return ret;
125 }
126
127 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
128 BluetoothRemoteDevice device(deviceId, 1);
129 int state = profile->GetDeviceState(device);
130 int status = GetProfileConnectionState(state);
131 napi_value result = nullptr;
132 napi_create_int32(env, status, &result);
133 HILOGI("status: %{public}d", status);
134 return result;
135 }
136
GetScoState(napi_env env,napi_callback_info info)137 napi_value NapiHandsFreeUnit::GetScoState(napi_env env, napi_callback_info info)
138 {
139 HILOGI("enter");
140 size_t expectedArgsCount = ARGS_SIZE_ONE;
141 size_t argc = expectedArgsCount;
142 napi_value argv[ARGS_SIZE_ONE] = {0};
143 napi_value thisVar = nullptr;
144
145 napi_value ret = nullptr;
146 napi_get_undefined(env, &ret);
147
148 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
149 if (argc != expectedArgsCount) {
150 HILOGE("Requires 1 argument.");
151 return ret;
152 }
153 string deviceId;
154 if (!ParseString(env, deviceId, argv[PARAM0])) {
155 HILOGE("string expected.");
156 return ret;
157 }
158
159 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
160 BluetoothRemoteDevice device(deviceId, 1);
161 int state = profile->GetScoState(device);
162 int status = GetScoConnectionState(state);
163 napi_value result = nullptr;
164 napi_create_int32(env, status, &result);
165 HILOGI("status: %{public}d", status);
166 return result;
167 }
168
Connect(napi_env env,napi_callback_info info)169 napi_value NapiHandsFreeUnit::Connect(napi_env env, napi_callback_info info)
170 {
171 HILOGI("enter");
172 size_t expectedArgsCount = ARGS_SIZE_ONE;
173 size_t argc = expectedArgsCount;
174 napi_value argv[ARGS_SIZE_ONE] = {0};
175 napi_value thisVar = nullptr;
176
177 napi_value ret = nullptr;
178 napi_get_undefined(env, &ret);
179
180 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
181 if (argc != expectedArgsCount) {
182 HILOGE("Requires 1 argument.");
183 return ret;
184 }
185 string deviceId;
186 if (!ParseString(env, deviceId, argv[PARAM0])) {
187 HILOGE("string expected.");
188 return ret;
189 }
190
191 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
192 BluetoothRemoteDevice device(deviceId, 1);
193 bool isOK = profile->Connect(device);
194 napi_value result = nullptr;
195 napi_get_boolean(env, isOK, &result);
196 HILOGI("res: %{public}d", isOK);
197 return result;
198 }
199
Disconnect(napi_env env,napi_callback_info info)200 napi_value NapiHandsFreeUnit::Disconnect(napi_env env, napi_callback_info info)
201 {
202 HILOGI("enter");
203 size_t expectedArgsCount = ARGS_SIZE_ONE;
204 size_t argc = expectedArgsCount;
205 napi_value argv[ARGS_SIZE_ONE] = {0};
206 napi_value thisVar = nullptr;
207
208 napi_value ret = nullptr;
209 napi_get_undefined(env, &ret);
210
211 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
212 if (argc != expectedArgsCount) {
213 HILOGE("Requires 1 argument.");
214 return ret;
215 }
216 string deviceId;
217 if (!ParseString(env, deviceId, argv[PARAM0])) {
218 HILOGE("string expected.");
219 return ret;
220 }
221
222 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
223 BluetoothRemoteDevice device(deviceId, 1);
224 bool isOK = profile->Disconnect(device);
225 napi_value result = nullptr;
226 napi_get_boolean(env, isOK, &result);
227 HILOGI("res: %{public}d", isOK);
228 return result;
229 }
230
ConnectSco(napi_env env,napi_callback_info info)231 napi_value NapiHandsFreeUnit::ConnectSco(napi_env env, napi_callback_info info)
232 {
233 HILOGI("enter");
234 size_t expectedArgsCount = ARGS_SIZE_ONE;
235 size_t argc = expectedArgsCount;
236 napi_value argv[ARGS_SIZE_ONE] = {0};
237 napi_value thisVar = nullptr;
238
239 napi_value ret = nullptr;
240 napi_get_undefined(env, &ret);
241
242 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
243 if (argc != expectedArgsCount) {
244 HILOGE("Requires 1 argument.");
245 return ret;
246 }
247 string deviceId;
248 if (!ParseString(env, deviceId, argv[PARAM0])) {
249 HILOGE("string expected.");
250 return ret;
251 }
252
253 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
254 BluetoothRemoteDevice device(deviceId, 1);
255 bool isOK = profile->ConnectSco(device);
256 napi_value result = nullptr;
257 napi_get_boolean(env, isOK, &result);
258 HILOGI("res: %{public}d", isOK);
259 return result;
260 }
261
DisconnectSco(napi_env env,napi_callback_info info)262 napi_value NapiHandsFreeUnit::DisconnectSco(napi_env env, napi_callback_info info)
263 {
264 HILOGI("enter");
265 size_t expectedArgsCount = ARGS_SIZE_ONE;
266 size_t argc = expectedArgsCount;
267 napi_value argv[ARGS_SIZE_ONE] = {0};
268 napi_value thisVar = nullptr;
269
270 napi_value ret = nullptr;
271 napi_get_undefined(env, &ret);
272
273 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
274 if (argc != expectedArgsCount) {
275 HILOGE("Requires 1 argument.");
276 return ret;
277 }
278 string deviceId;
279 if (!ParseString(env, deviceId, argv[PARAM0])) {
280 HILOGE("string expected.");
281 return ret;
282 }
283
284 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
285 BluetoothRemoteDevice device(deviceId, 1);
286 bool isOK = profile->DisconnectSco(device);
287 napi_value result = nullptr;
288 napi_get_boolean(env, isOK, &result);
289 HILOGI("res: %{public}d", isOK);
290 return result;
291 }
292
SendDTMF(napi_env env,napi_callback_info info)293 napi_value NapiHandsFreeUnit::SendDTMF(napi_env env, napi_callback_info info)
294 {
295 HILOGI("enter");
296 size_t expectedArgsCount = ARGS_SIZE_TWO;
297 size_t argc = expectedArgsCount;
298 napi_value argv[ARGS_SIZE_TWO] = {0};
299 napi_value thisVar = nullptr;
300
301 napi_value ret = nullptr;
302 napi_get_undefined(env, &ret);
303
304 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
305 if (argc != expectedArgsCount) {
306 HILOGE("Requires 2 argument.");
307 return ret;
308 }
309 string deviceId;
310 if (!ParseString(env, deviceId, argv[PARAM0])) {
311 HILOGE("string expected.");
312 return ret;
313 }
314 int code;
315 if (ParseInt32(env, code, argv[PARAM1])) {
316 HILOGE("int32 expected.");
317 return ret;
318 }
319
320 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
321 BluetoothRemoteDevice device(deviceId, 1);
322 bool isOK = profile->SendDTMFTone(device, code);
323 napi_value result = nullptr;
324 napi_get_boolean(env, isOK, &result);
325 HILOGI("res: %{public}d", isOK);
326 return result;
327 }
328
329 } // namespace Bluetooth
330 } // namespace OHOS