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 #include "napi_bluetooth_event.h"
19
20 namespace OHOS {
21 namespace Bluetooth {
22 using namespace std;
23
24 NapiHandsFreeUnitObserver NapiHandsFreeUnit::observer_;
25 bool NapiHandsFreeUnit::isRegistered_ = false;
26
DefineHandsFreeUnitJSClass(napi_env env)27 void NapiHandsFreeUnit::DefineHandsFreeUnitJSClass(napi_env env)
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(env, ProfileId::PROFILE_HANDS_FREE_UNIT, napiProfile);
49 HILOGI("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("enter");
63 std::unique_lock<std::shared_mutex> guard(NapiHandsFreeUnitObserver::g_handsFreeUnitCallbackInfosMutex);
64
65 napi_value ret = nullptr;
66 ret = NapiEvent::OnEvent(env, info, observer_.callbackInfos_);
67 if (!isRegistered_) {
68 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
69 profile->RegisterObserver(&observer_);
70 isRegistered_ = true;
71 }
72
73 HILOGI("Hands Free Unit is registered");
74 return ret;
75 }
76
Off(napi_env env,napi_callback_info info)77 napi_value NapiHandsFreeUnit::Off(napi_env env, napi_callback_info info)
78 {
79 HILOGI("enter");
80 std::unique_lock<std::shared_mutex> guard(NapiHandsFreeUnitObserver::g_handsFreeUnitCallbackInfosMutex);
81
82 napi_value ret = nullptr;
83 ret = NapiEvent::OffEvent(env, info, observer_.callbackInfos_);
84 HILOGI("Hands Free Unit is unregistered");
85 return ret;
86 }
87
GetConnectionDevices(napi_env env,napi_callback_info info)88 napi_value NapiHandsFreeUnit::GetConnectionDevices(napi_env env, napi_callback_info info)
89 {
90 HILOGI("enter");
91 napi_value ret = nullptr;
92 napi_create_array(env, &ret);
93 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
94 vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };
95 vector<BluetoothRemoteDevice> devices = profile->GetDevicesByStates(states);
96 vector<string> deviceVector;
97 for (auto &device: devices) {
98 deviceVector.push_back(device.GetDeviceAddr());
99 }
100 ConvertStringVectorToJS(env, ret, deviceVector);
101 return ret;
102 }
103
GetDeviceState(napi_env env,napi_callback_info info)104 napi_value NapiHandsFreeUnit::GetDeviceState(napi_env env, napi_callback_info info)
105 {
106 HILOGI("enter");
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 deviceId;
121 if (!ParseString(env, deviceId, argv[PARAM0])) {
122 HILOGE("string expected.");
123 return ret;
124 }
125
126 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
127 BluetoothRemoteDevice device(deviceId, 1);
128 int state = profile->GetDeviceState(device);
129 int status = GetProfileConnectionState(state);
130 napi_value result = nullptr;
131 napi_create_int32(env, status, &result);
132 HILOGI("status: %{public}d", status);
133 return result;
134 }
135
GetScoState(napi_env env,napi_callback_info info)136 napi_value NapiHandsFreeUnit::GetScoState(napi_env env, napi_callback_info info)
137 {
138 HILOGI("enter");
139 size_t expectedArgsCount = ARGS_SIZE_ONE;
140 size_t argc = expectedArgsCount;
141 napi_value argv[ARGS_SIZE_ONE] = {0};
142 napi_value thisVar = nullptr;
143
144 napi_value ret = nullptr;
145 napi_get_undefined(env, &ret);
146
147 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
148 if (argc != expectedArgsCount) {
149 HILOGE("Requires 1 argument.");
150 return ret;
151 }
152 string deviceId;
153 if (!ParseString(env, deviceId, argv[PARAM0])) {
154 HILOGE("string expected.");
155 return ret;
156 }
157
158 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
159 BluetoothRemoteDevice device(deviceId, 1);
160 int state = profile->GetScoState(device);
161 int status = GetScoConnectionState(state);
162 napi_value result = nullptr;
163 napi_create_int32(env, status, &result);
164 HILOGI("status: %{public}d", status);
165 return result;
166 }
167
Connect(napi_env env,napi_callback_info info)168 napi_value NapiHandsFreeUnit::Connect(napi_env env, napi_callback_info info)
169 {
170 HILOGI("enter");
171 size_t expectedArgsCount = ARGS_SIZE_ONE;
172 size_t argc = expectedArgsCount;
173 napi_value argv[ARGS_SIZE_ONE] = {0};
174 napi_value thisVar = nullptr;
175
176 napi_value ret = nullptr;
177 napi_get_undefined(env, &ret);
178
179 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
180 if (argc != expectedArgsCount) {
181 HILOGE("Requires 1 argument.");
182 return ret;
183 }
184 string deviceId;
185 if (!ParseString(env, deviceId, argv[PARAM0])) {
186 HILOGE("string expected.");
187 return ret;
188 }
189
190 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
191 BluetoothRemoteDevice device(deviceId, 1);
192 bool isOK = profile->Connect(device);
193 napi_value result = nullptr;
194 napi_get_boolean(env, isOK, &result);
195 HILOGI("res: %{public}d", isOK);
196 return result;
197 }
198
Disconnect(napi_env env,napi_callback_info info)199 napi_value NapiHandsFreeUnit::Disconnect(napi_env env, napi_callback_info info)
200 {
201 HILOGI("enter");
202 size_t expectedArgsCount = ARGS_SIZE_ONE;
203 size_t argc = expectedArgsCount;
204 napi_value argv[ARGS_SIZE_ONE] = {0};
205 napi_value thisVar = nullptr;
206
207 napi_value ret = nullptr;
208 napi_get_undefined(env, &ret);
209
210 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
211 if (argc != expectedArgsCount) {
212 HILOGE("Requires 1 argument.");
213 return ret;
214 }
215 string deviceId;
216 if (!ParseString(env, deviceId, argv[PARAM0])) {
217 HILOGE("string expected.");
218 return ret;
219 }
220
221 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
222 BluetoothRemoteDevice device(deviceId, 1);
223 bool isOK = profile->Disconnect(device);
224 napi_value result = nullptr;
225 napi_get_boolean(env, isOK, &result);
226 HILOGI("res: %{public}d", isOK);
227 return result;
228 }
229
ConnectSco(napi_env env,napi_callback_info info)230 napi_value NapiHandsFreeUnit::ConnectSco(napi_env env, napi_callback_info info)
231 {
232 HILOGI("enter");
233 size_t expectedArgsCount = ARGS_SIZE_ONE;
234 size_t argc = expectedArgsCount;
235 napi_value argv[ARGS_SIZE_ONE] = {0};
236 napi_value thisVar = nullptr;
237
238 napi_value ret = nullptr;
239 napi_get_undefined(env, &ret);
240
241 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
242 if (argc != expectedArgsCount) {
243 HILOGE("Requires 1 argument.");
244 return ret;
245 }
246 string deviceId;
247 if (!ParseString(env, deviceId, argv[PARAM0])) {
248 HILOGE("string expected.");
249 return ret;
250 }
251
252 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
253 BluetoothRemoteDevice device(deviceId, 1);
254 bool isOK = profile->ConnectSco(device);
255 napi_value result = nullptr;
256 napi_get_boolean(env, isOK, &result);
257 HILOGI("res: %{public}d", isOK);
258 return result;
259 }
260
DisconnectSco(napi_env env,napi_callback_info info)261 napi_value NapiHandsFreeUnit::DisconnectSco(napi_env env, napi_callback_info info)
262 {
263 HILOGI("enter");
264 size_t expectedArgsCount = ARGS_SIZE_ONE;
265 size_t argc = expectedArgsCount;
266 napi_value argv[ARGS_SIZE_ONE] = {0};
267 napi_value thisVar = nullptr;
268
269 napi_value ret = nullptr;
270 napi_get_undefined(env, &ret);
271
272 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
273 if (argc != expectedArgsCount) {
274 HILOGE("Requires 1 argument.");
275 return ret;
276 }
277 string deviceId;
278 if (!ParseString(env, deviceId, argv[PARAM0])) {
279 HILOGE("string expected.");
280 return ret;
281 }
282
283 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
284 BluetoothRemoteDevice device(deviceId, 1);
285 bool isOK = profile->DisconnectSco(device);
286 napi_value result = nullptr;
287 napi_get_boolean(env, isOK, &result);
288 HILOGI("res: %{public}d", isOK);
289 return result;
290 }
291
SendDTMF(napi_env env,napi_callback_info info)292 napi_value NapiHandsFreeUnit::SendDTMF(napi_env env, napi_callback_info info)
293 {
294 HILOGI("enter");
295 size_t expectedArgsCount = ARGS_SIZE_TWO;
296 size_t argc = expectedArgsCount;
297 napi_value argv[ARGS_SIZE_TWO] = {0};
298 napi_value thisVar = nullptr;
299
300 napi_value ret = nullptr;
301 napi_get_undefined(env, &ret);
302
303 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
304 if (argc != expectedArgsCount) {
305 HILOGE("Requires 2 argument.");
306 return ret;
307 }
308 string deviceId;
309 if (!ParseString(env, deviceId, argv[PARAM0])) {
310 HILOGE("string expected.");
311 return ret;
312 }
313 int code;
314 if (ParseInt32(env, code, argv[PARAM1])) {
315 HILOGE("int32 expected.");
316 return ret;
317 }
318
319 HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
320 BluetoothRemoteDevice device(deviceId, 1);
321 bool isOK = profile->SendDTMFTone(device, code);
322 napi_value result = nullptr;
323 napi_get_boolean(env, isOK, &result);
324 HILOGI("res: %{public}d", isOK);
325 return result;
326 }
327
328 } // namespace Bluetooth
329 } // namespace OHOS