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