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