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 <uv.h>
16 #include "bluetooth_log.h"
17 #include "napi_bluetooth_gatt_server.h"
18 #include "napi_bluetooth_gatt_server_callback.h"
19
20 namespace OHOS {
21 namespace Bluetooth {
22 using namespace std;
23
OnCharacteristicReadRequest(const BluetoothRemoteDevice & device,GattCharacteristic & characteristic,int requestId)24 void NapiGattServerCallback::OnCharacteristicReadRequest(
25 const BluetoothRemoteDevice &device, GattCharacteristic &characteristic, int requestId)
26 {
27 HILOGI("NapiGattServerCallback::OnCharacteristicReadRequest called");
28 if (!callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_READ]) {
29 HILOGW("NapiGattServerCallback::OnCharacteristicReadRequest: This callback is not registered by ability.");
30 return;
31 }
32 HILOGI("NapiGattServerCallback::OnCharacteristicReadRequest: %{public}s is registered by ability",
33 STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_READ.c_str());
34 std::shared_ptr<GattCharacteristicCallbackInfo> callbackInfo =
35 std::static_pointer_cast<GattCharacteristicCallbackInfo>(callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_READ]);
36
37 callbackInfo->info_ = requestId;
38 callbackInfo->deviceId_ = device.GetDeviceAddr();
39 callbackInfo->characteristic_ = characteristic;
40
41 uv_loop_s *loop = nullptr;
42 napi_get_uv_event_loop(callbackInfo->env_, &loop);
43 uv_work_t *work = new uv_work_t;
44 work->data = (void*)callbackInfo.get();
45
46 uv_queue_work(
47 loop,
48 work,
49 [](uv_work_t *work) {},
50 [](uv_work_t *work, int status) {
51 GattCharacteristicCallbackInfo *callbackInfo = (GattCharacteristicCallbackInfo *)work->data;
52 napi_value result = nullptr;
53 napi_create_object(callbackInfo->env_, &result);
54 ConvertCharacteristicReadReqToJS(callbackInfo->env_, result, callbackInfo->deviceId_,
55 callbackInfo->characteristic_, callbackInfo->info_);
56
57 napi_value callback = nullptr;
58 napi_value undefined = nullptr;
59 napi_value callResult = nullptr;
60 napi_get_undefined(callbackInfo->env_, &undefined);
61 napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback);
62 napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
63 delete work;
64 work = nullptr;
65 }
66 );
67 }
68
OnCharacteristicWriteRequest(const BluetoothRemoteDevice & device,GattCharacteristic & characteristic,int requestId)69 void NapiGattServerCallback::OnCharacteristicWriteRequest(const BluetoothRemoteDevice &device,
70 GattCharacteristic &characteristic, int requestId)
71 {
72 HILOGI("NapiGattServerCallback::OnCharacteristicWriteRequest called");
73 if (!callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_WRITE]) {
74 HILOGW("NapiGattServerCallback::OnCharacteristicWriteRequest: This callback is not registered by ability.");
75 return;
76 }
77 HILOGI("NapiGattServerCallback::OnCharacteristicWriteRequest: %{public}s is registered by ability",
78 STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_WRITE.c_str());
79
80 std::shared_ptr<GattCharacteristicCallbackInfo> callbackInfo =
81 std::static_pointer_cast<GattCharacteristicCallbackInfo>(callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_WRITE]);
82
83 callbackInfo->info_ = requestId;
84 callbackInfo->deviceId_ = device.GetDeviceAddr();
85 callbackInfo->characteristic_ = characteristic;
86
87 uv_loop_s *loop = nullptr;
88 napi_get_uv_event_loop(callbackInfo->env_, &loop);
89 uv_work_t *work = new uv_work_t;
90 work->data = (void*)callbackInfo.get();
91
92 uv_queue_work(
93 loop,
94 work,
95 [](uv_work_t *work) {},
96 [](uv_work_t *work, int status) {
97 GattCharacteristicCallbackInfo *callbackInfo = (GattCharacteristicCallbackInfo *)work->data;
98 napi_value result = nullptr;
99 napi_create_object(callbackInfo->env_, &result);
100 ConvertCharacteristicWriteReqToJS(callbackInfo->env_, result, callbackInfo->deviceId_,
101 callbackInfo->characteristic_, callbackInfo->info_);
102
103 napi_value callback = nullptr;
104 napi_value undefined = nullptr;
105 napi_value callResult = nullptr;
106 napi_get_undefined(callbackInfo->env_, &undefined);
107 napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback);
108 napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
109 delete work;
110 work = nullptr;
111 }
112 );
113 }
114
115
OnConnectionStateUpdate(const BluetoothRemoteDevice & device,int state)116 void NapiGattServerCallback::OnConnectionStateUpdate(const BluetoothRemoteDevice &device, int state)
117 {
118 HILOGI("NapiGattServerCallback::OnConnectionStateUpdate called");
119
120 if (state == static_cast<int>(BTConnectState::CONNECTED)) {
121 HILOGI("NapiGattServerCallback::OnConnectionStateUpdate connected");
122 bool hasAddr = false;
123 for (auto it = NapiGattServer::deviceList.begin(); it != NapiGattServer::deviceList.end(); ++it) {
124 if (*it == device.GetDeviceAddr()) {
125 hasAddr = true;
126 break;
127 }
128 }
129 if (!hasAddr) {
130 HILOGI("NapiGattServerCallback::OnConnectionStateUpdate add devices");
131 NapiGattServer::deviceList.push_back(device.GetDeviceAddr());
132 }
133 } else if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
134 HILOGI("NapiGattServerCallback::OnConnectionStateUpdate disconnected");
135 for (auto it = NapiGattServer::deviceList.begin(); it != NapiGattServer::deviceList.end(); ++it) {
136 if (*it == device.GetDeviceAddr()) {
137 HILOGI("NapiGattServerCallback::OnConnectionStateUpdate romove devices start");
138 NapiGattServer::deviceList.erase(it);
139 HILOGI("NapiGattServerCallback::OnConnectionStateUpdate romove devices end");
140 break;
141 }
142 }
143 }
144
145 if (!callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_CONNECT_STATE_CHANGE]) {
146 HILOGW("NapiGattServerCallback::OnConnectionStateUpdate: This callback is not registered by ability.");
147 return;
148 }
149 HILOGI("NapiGattServerCallback::OnConnectionStateUpdate: %{public}s is registered by ability",
150 STR_BT_GATT_SERVER_CALLBACK_CONNECT_STATE_CHANGE.c_str());
151 std::shared_ptr<BluetoothCallbackInfo> callbackInfo =
152 callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_CONNECT_STATE_CHANGE];
153
154 callbackInfo->state_ = state;
155 callbackInfo->deviceId_ = device.GetDeviceAddr();
156 uv_loop_s *loop = nullptr;
157 napi_get_uv_event_loop(callbackInfo->env_, &loop);
158 uv_work_t *work = new uv_work_t;
159 work->data = (void*)callbackInfo.get();
160
161 uv_queue_work(
162 loop,
163 work,
164 [](uv_work_t *work) {},
165 [](uv_work_t *work, int status) {
166 BluetoothCallbackInfo *callbackInfo = (BluetoothCallbackInfo *)work->data;
167 napi_value result = nullptr;
168 napi_create_object(callbackInfo->env_, &result);
169 ConvertStateChangeParamToJS(callbackInfo->env_, result, callbackInfo->deviceId_, callbackInfo->state_);
170 napi_value callback = nullptr;
171 napi_value undefined = nullptr;
172 napi_value callResult = nullptr;
173 napi_get_undefined(callbackInfo->env_, &undefined);
174 napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback);
175 napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
176 delete work;
177 work = nullptr;
178 }
179 );
180 }
181
OnDescriptorWriteRequest(const BluetoothRemoteDevice & device,GattDescriptor & descriptor,int requestId)182 void NapiGattServerCallback::OnDescriptorWriteRequest(const BluetoothRemoteDevice &device,
183 GattDescriptor &descriptor, int requestId)
184 {
185 HILOGI("NapiGattServerCallback::OnDescriptorWriteRequest called");
186
187 if (!callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_WRITE]) {
188 HILOGW("NapiGattServerCallback::OnDescriptorWriteRequest: This callback is not registered by ability.");
189 return;
190 }
191 HILOGI("NapiGattServerCallback::OnDescriptorWriteRequest: %{public}s is registered by ability",
192 STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_WRITE.c_str());
193 std::shared_ptr<GattDescriptorCallbackInfo> callbackInfo =
194 std::static_pointer_cast<GattDescriptorCallbackInfo>(callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_WRITE]);
195
196 callbackInfo->info_ = requestId;
197 callbackInfo->deviceId_ = device.GetDeviceAddr();
198 callbackInfo->descriptor_ = descriptor;
199
200 uv_loop_s *loop = nullptr;
201 napi_get_uv_event_loop(callbackInfo->env_, &loop);
202 uv_work_t *work = new uv_work_t;
203 work->data = (void*)callbackInfo.get();
204
205 uv_queue_work(
206 loop,
207 work,
208 [](uv_work_t *work) {},
209 [](uv_work_t *work, int status) {
210 GattDescriptorCallbackInfo *callbackInfo = (GattDescriptorCallbackInfo *)work->data;
211 napi_value result = nullptr;
212 napi_create_object(callbackInfo->env_, &result);
213 ConvertDescriptorWriteReqToJS(callbackInfo->env_, result, callbackInfo->deviceId_,
214 callbackInfo->descriptor_, callbackInfo->info_);
215
216 napi_value callback = nullptr;
217 napi_value undefined = nullptr;
218 napi_value callResult = nullptr;
219 napi_get_undefined(callbackInfo->env_, &undefined);
220 napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback);
221 napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
222 delete work;
223 work = nullptr;
224 }
225 );
226 }
227
OnDescriptorReadRequest(const BluetoothRemoteDevice & device,GattDescriptor & descriptor,int requestId)228 void NapiGattServerCallback::OnDescriptorReadRequest(const BluetoothRemoteDevice &device,
229 GattDescriptor &descriptor, int requestId)
230 {
231 HILOGI("NapiGattServerCallback::OnDescriptorReadRequest called");
232
233 if (!callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_READ]) {
234 HILOGW("NapiGattServerCallback::OnDescriptorReadRequest: This callback is not registered by ability.");
235 return;
236 }
237 HILOGI("NapiGattServerCallback::OnDescriptorReadRequest: %{public}s is registered by ability",
238 STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_READ.c_str());
239 std::shared_ptr<GattDescriptorCallbackInfo> callbackInfo =
240 std::static_pointer_cast<GattDescriptorCallbackInfo>(callbackInfos_[STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_READ]);
241
242 callbackInfo->info_ = requestId;
243 callbackInfo->deviceId_ = device.GetDeviceAddr();
244 callbackInfo->descriptor_ = descriptor;
245
246 uv_loop_s *loop = nullptr;
247 napi_get_uv_event_loop(callbackInfo->env_, &loop);
248 uv_work_t *work = new uv_work_t;
249 work->data = (void*)callbackInfo.get();
250
251 uv_queue_work(
252 loop,
253 work,
254 [](uv_work_t *work) {},
255 [](uv_work_t *work, int status) {
256 GattDescriptorCallbackInfo *callbackInfo = (GattDescriptorCallbackInfo *)work->data;
257 napi_value result = nullptr;
258 napi_create_object(callbackInfo->env_, &result);
259 ConvertDescriptorReadReqToJS(callbackInfo->env_, result, callbackInfo->deviceId_, callbackInfo->descriptor_,
260 callbackInfo->info_);
261
262 napi_value callback = nullptr;
263 napi_value undefined = nullptr;
264 napi_value callResult = nullptr;
265 napi_get_undefined(callbackInfo->env_, &undefined);
266 napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback);
267 napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
268 delete work;
269 work = nullptr;
270 }
271 );
272 }
273 } // namespace Bluetooth
274 } // namespace OHOS
275