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 #ifndef LOG_TAG
16 #define LOG_TAG "bt_napi_map_mse"
17 #endif
18
19 #include "bluetooth_errorcode.h"
20 #include "bluetooth_map_mse.h"
21 #include "bluetooth_utils.h"
22 #include "napi_async_work.h"
23 #include "napi_bluetooth_event.h"
24 #include "napi_bluetooth_error.h"
25 #include "napi_bluetooth_profile.h"
26 #include "napi_bluetooth_map_mse.h"
27 #include "napi_bluetooth_utils.h"
28 #include "../parser/napi_parser_utils.h"
29 #include "hitrace_meter.h"
30
31 namespace OHOS {
32 namespace Bluetooth {
33 using namespace std;
34
35 std::shared_ptr<NapiMapMseObserver> NapiMapMse::observer_ = std::make_shared<NapiMapMseObserver>();
36 thread_local napi_ref g_consRef_ = nullptr;
37
DefineMapMseJSClass(napi_env env,napi_value exports)38 void NapiMapMse::DefineMapMseJSClass(napi_env env, napi_value exports)
39 {
40 napi_value constructor;
41 napi_property_descriptor properties[] = {
42 DECLARE_NAPI_FUNCTION("on", On),
43 DECLARE_NAPI_FUNCTION("off", Off),
44 DECLARE_NAPI_FUNCTION("getConnectedDevices", GetConnectedDevices),
45 DECLARE_NAPI_FUNCTION("getConnectionState", GetConnectionState),
46 DECLARE_NAPI_FUNCTION("setConnectionStrategy", SetConnectionStrategy),
47 DECLARE_NAPI_FUNCTION("getConnectionStrategy", GetConnectionStrategy),
48 DECLARE_NAPI_FUNCTION("disconnect", Disconnect),
49 DECLARE_NAPI_FUNCTION("setMessageAccessAuthorization", SetMessageAccessAuthorization),
50 DECLARE_NAPI_FUNCTION("getMessageAccessAuthorization", GetMessageAccessAuthorization),
51 };
52
53 napi_define_class(env, "MapMse", NAPI_AUTO_LENGTH, MapMseConstructor, nullptr,
54 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
55
56 DefineCreateProfile(env, exports);
57 napi_create_reference(env, constructor, 1, &g_consRef_);
58 }
59
DefineCreateProfile(napi_env env,napi_value exports)60 napi_value NapiMapMse::DefineCreateProfile(napi_env env, napi_value exports)
61 {
62 napi_property_descriptor properties[] = {
63 DECLARE_NAPI_FUNCTION("createMapMseProfile", CreateMapMseProfile),
64 };
65 HITRACE_METER_NAME(HITRACE_TAG_OHOS, "mapmse:napi_define_properties");
66 napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties);
67 return exports;
68 }
69
CreateMapMseProfile(napi_env env,napi_callback_info info)70 napi_value NapiMapMse::CreateMapMseProfile(napi_env env, napi_callback_info info)
71 {
72 napi_value napiProfile;
73 napi_value constructor = nullptr;
74 napi_get_reference_value(env, g_consRef_, &constructor);
75 napi_new_instance(env, constructor, 0, nullptr, &napiProfile);
76
77 MapMse *profile = MapMse::GetProfile();
78 profile->RegisterObserver(observer_);
79 return napiProfile;
80 }
81
MapMseConstructor(napi_env env,napi_callback_info info)82 napi_value NapiMapMse::MapMseConstructor(napi_env env, napi_callback_info info)
83 {
84 napi_value thisVar = nullptr;
85 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
86 return thisVar;
87 }
88
On(napi_env env,napi_callback_info info)89 napi_value NapiMapMse::On(napi_env env, napi_callback_info info)
90 {
91 if (observer_) {
92 auto status = observer_->eventSubscribe_.Register(env, info);
93 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
94 }
95 return NapiGetUndefinedRet(env);
96 }
97
Off(napi_env env,napi_callback_info info)98 napi_value NapiMapMse::Off(napi_env env, napi_callback_info info)
99 {
100 if (observer_) {
101 auto status = observer_->eventSubscribe_.Deregister(env, info);
102 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
103 }
104 return NapiGetUndefinedRet(env);
105 }
106
GetConnectedDevices(napi_env env,napi_callback_info info)107 napi_value NapiMapMse::GetConnectedDevices(napi_env env, napi_callback_info info)
108 {
109 HILOGI("enter");
110 napi_value ret = nullptr;
111 napi_create_array(env, &ret);
112 napi_status checkRet = CheckEmptyParam(env, info);
113 NAPI_BT_ASSERT_RETURN(env, checkRet == napi_ok, BT_ERR_INVALID_PARAM, ret);
114
115 MapMse *profile = MapMse::GetProfile();
116 vector<int32_t> states = { static_cast<int32_t>(BTConnectState::CONNECTED) };
117 vector<BluetoothRemoteDevice> devices {};
118 int32_t errorCode = profile->GetDevicesByStates(states, devices);
119 NAPI_BT_ASSERT_RETURN(env, errorCode == BT_NO_ERROR, errorCode, ret);
120
121 vector<string> deviceVector;
122 for (auto &device : devices) {
123 deviceVector.push_back(device.GetDeviceAddr());
124 }
125
126 auto status = ConvertStringVectorToJS(env, ret, deviceVector);
127 NAPI_BT_ASSERT_RETURN(env, status == napi_ok, BT_ERR_INTERNAL_ERROR, ret);
128 return ret;
129 }
130
GetConnectionState(napi_env env,napi_callback_info info)131 napi_value NapiMapMse::GetConnectionState(napi_env env, napi_callback_info info)
132 {
133 HILOGI("enter");
134 std::string remoteAddr {};
135 bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
136 NAPI_BT_ASSERT_RETURN_UNDEF(env, checkRet, BT_ERR_INVALID_PARAM);
137
138 MapMse *profile = MapMse::GetProfile();
139 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
140 int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
141 int32_t errorCode = profile->GetDeviceState(device, state);
142 HILOGI("errorCode:%{public}s", GetErrorCode(errorCode).c_str());
143 NAPI_BT_ASSERT_RETURN_UNDEF(env, errorCode == BT_NO_ERROR, errorCode);
144
145 napi_value result = nullptr;
146 int32_t profileState = GetProfileConnectionState(state);
147 napi_create_int32(env, profileState, &result);
148 return result;
149 }
150
Disconnect(napi_env env,napi_callback_info info)151 napi_value NapiMapMse::Disconnect(napi_env env, napi_callback_info info)
152 {
153 HILOGD("enter");
154 std::string remoteAddr{};
155 bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
156 NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
157
158 MapMse *profile = MapMse::GetProfile();
159 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
160 int32_t errorCode = profile->Disconnect(device);
161 HILOGI("errorCode:%{public}s", GetErrorCode(errorCode).c_str());
162 NAPI_BT_ASSERT_RETURN_FALSE(env, errorCode == BT_NO_ERROR, errorCode);
163 return NapiGetBooleanTrue(env);
164 }
165
SetConnectionStrategy(napi_env env,napi_callback_info info)166 napi_value NapiMapMse::SetConnectionStrategy(napi_env env, napi_callback_info info)
167 {
168 HILOGD("enter");
169 std::string remoteAddr{};
170 int32_t strategy = 0;
171 auto status = CheckSetConnectStrategyParam(env, info, remoteAddr, strategy);
172 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
173
174 auto func = [remoteAddr, strategy]() {
175 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
176 MapMse *profile = MapMse::GetProfile();
177 int32_t errorCode = profile->SetConnectionStrategy(remoteDevice, strategy);
178 HILOGI("err: %{public}d", errorCode);
179 return NapiAsyncWorkRet(errorCode);
180 };
181 auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
182 NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
183 asyncWork->Run();
184 return asyncWork->GetRet();
185 }
186
GetConnectionStrategy(napi_env env,napi_callback_info info)187 napi_value NapiMapMse::GetConnectionStrategy(napi_env env, napi_callback_info info)
188 {
189 HILOGD("enter");
190 std::string remoteAddr{};
191 auto status = CheckDeviceAddressParam(env, info, remoteAddr);
192 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
193
194 auto func = [remoteAddr]() {
195 int32_t strategy = 0;
196 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
197 MapMse *profile = MapMse::GetProfile();
198 int32_t errorCode = profile->GetConnectionStrategy(remoteDevice, strategy);
199 HILOGI("errorCode: %{public}d, deviceName: %{public}d", errorCode, strategy);
200 auto object = std::make_shared<NapiNativeInt>(strategy);
201 return NapiAsyncWorkRet(errorCode, object);
202 };
203 auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
204 NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
205 asyncWork->Run();
206 return asyncWork->GetRet();
207 }
208
SetMessageAccessAuthorization(napi_env env,napi_callback_info info)209 napi_value NapiMapMse::SetMessageAccessAuthorization(napi_env env, napi_callback_info info)
210 {
211 std::string remoteAddr{};
212 int32_t accessAuthorization = 0;
213 auto status = CheckAccessAuthorizationParam(env, info, remoteAddr, accessAuthorization);
214 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
215
216 auto func = [remoteAddr, accessAuthorization]() {
217 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
218 MapMse *profile = MapMse::GetProfile();
219 int32_t errorCode = profile->SetMessageAccessAuthorization(remoteDevice, accessAuthorization);
220 HILOGI("errorCode: %{public}d", errorCode);
221 return NapiAsyncWorkRet(errorCode);
222 };
223 auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
224 NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
225 asyncWork->Run();
226 return asyncWork->GetRet();
227 }
228
GetMessageAccessAuthorization(napi_env env,napi_callback_info info)229 napi_value NapiMapMse::GetMessageAccessAuthorization(napi_env env, napi_callback_info info)
230 {
231 std::string remoteAddr{};
232 auto status = CheckDeviceAddressParam(env, info, remoteAddr);
233 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
234
235 auto func = [remoteAddr]() {
236 int32_t accessAuthorization = 0;
237 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
238 MapMse *profile = MapMse::GetProfile();
239 int32_t errorCode = profile->GetMessageAccessAuthorization(remoteDevice, accessAuthorization);
240 HILOGI("errorCode: %{public}d, accessAuthorization: %{public}d", errorCode, accessAuthorization);
241 auto object = std::make_shared<NapiNativeInt>(accessAuthorization);
242 return NapiAsyncWorkRet(errorCode, object);
243 };
244 auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NO_NEED_CALLBACK);
245 NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
246 asyncWork->Run();
247 return asyncWork->GetRet();
248 }
249
250 } // namespace Bluetooth
251 } // namespace OHOS