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