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 #ifndef NAPI_BLUETOOTH_UTILS_H
16 #define NAPI_BLUETOOTH_UTILS_H
17
18 #include "bluetooth_gatt_characteristic.h"
19 #include "bluetooth_gatt_client.h"
20 #include "bluetooth_gatt_descriptor.h"
21 #include "bluetooth_gatt_server.h"
22 #include "bluetooth_gatt_service.h"
23 #include "bluetooth_log.h"
24 #include "bluetooth_remote_device.h"
25 #include "napi/native_api.h"
26 #include "napi/native_node_api.h"
27
28 #include <condition_variable>
29 #include <mutex>
30 #include <stdint.h>
31 #include <string>
32 #include <vector>
33
34 #include "uv.h"
35
36 #include "bluetooth_socket.h"
37
38 namespace OHOS {
39 namespace Bluetooth {
40 constexpr size_t CALLBACK_SIZE = 1;
41 constexpr size_t ARGS_SIZE_ONE = 1;
42 constexpr size_t ARGS_SIZE_TWO = 2;
43 constexpr size_t ARGS_SIZE_THREE = 3;
44 constexpr size_t ARGS_SIZE_FOUR = 4;
45 constexpr int32_t DEFAULT_INT32 = 0;
46 constexpr int32_t PARAM0 = 0;
47 constexpr int32_t PARAM1 = 1;
48 constexpr int32_t PARAM2 = 2;
49 constexpr int32_t CODE_SUCCESS = 0;
50 constexpr int32_t CODE_FAILED = -1;
51 constexpr int ASYNC_IDLE = 0;
52 constexpr int ASYNC_START = 1;
53 constexpr int ASYNC_DONE = 2;
54 constexpr int32_t THREAD_WAIT_TIMEOUT = 5;
55
56 struct ServerResponse {
57 std::string deviceId = "";
58 int transId = 0;
59 int status = 0;
60 int offset = 0;
61 uint8_t *value = nullptr;
62 int length = 0;
SetValueServerResponse63 void SetValue(uint8_t *values, size_t len)
64 {
65 HILOGI("GattCharacteristic::SetValue starts");
66 if (value != nullptr) {
67 value = nullptr;
68 }
69
70 length = len;
71 value = values;
72 }
73 };
74
75 struct SppOption {
76 std::string uuid_ = "";
77 bool secure_ = false;
78 SppSocketType type_;
79 };
80
81 const std::string REGISTER_DEVICE_FIND_TYPE = "bluetoothDeviceFind";
82 const std::string REGISTER_STATE_CHANGE_TYPE = "stateChange";
83 const std::string REGISTER_PIN_REQUEST_TYPE = "pinRequired";
84 const std::string REGISTER_BONE_STATE_TYPE = "bondStateChange";
85 const std::string REGISTER_BLE_FIND_DEVICE_TYPE = "BLEDeviceFind";
86 const std::string REGISTER_SYS_BLE_SCAN_TYPE = "sysBLEScan";
87 const std::string REGISTER_SYS_BLE_FIND_DEVICE_TYPE = "sysBLEDeviceFonud";
88
89 bool ParseString(napi_env env, std::string ¶m, napi_value args);
90 bool ParseInt32(napi_env env, int32_t ¶m, napi_value args);
91 bool ParseBool(napi_env env, bool ¶m, napi_value args);
92 bool ParseArrayBuffer(napi_env env, uint8_t **data, size_t &size, napi_value args);
93 napi_value GetCallbackErrorValue(napi_env env, int errCode);
94
95 void ConvertStringVectorToJS(napi_env env, napi_value result, std::vector<std::string> &stringVector);
96
97 void ConvertGattServiceToJS(napi_env env, napi_value result, GattService &service);
98 void ConvertGattServiceVectorToJS(napi_env env, napi_value result, std::vector<GattService> &services);
99
100 void ConvertBLECharacteristicToJS(napi_env env, napi_value result, GattCharacteristic &characteristic);
101 void ConvertBLECharacteristicVectorToJS(
102 napi_env env, napi_value result, std::vector<GattCharacteristic> &characteristics);
103
104 void ConvertBLEDescriptorToJS(napi_env env, napi_value result, GattDescriptor &descriptor);
105 void ConvertBLEDescriptorVectorToJS(napi_env env, napi_value result, std::vector<GattDescriptor> &descriptors);
106
107 void ConvertCharacteristicReadReqToJS(napi_env env, napi_value result, const std::string &device,
108 GattCharacteristic &characteristic, int requestId);
109
110 void ConvertCharacteristicWriteReqToJS(napi_env env, napi_value result, const std::string &device,
111 GattCharacteristic &characteristic, int requestId);
112
113 void ConvertDescriptorReadReqToJS(
114 napi_env env, napi_value result, const std::string &device, GattDescriptor &descriptor, int requestId);
115
116 void ConvertDescriptorWriteReqToJS(
117 napi_env env, napi_value result, const std::string &device, GattDescriptor &descriptor, int requestId);
118 void ConvertStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state);
119 void ConvertScoStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state);
120
121 void GetServiceVectorFromJS(napi_env env, napi_value object, std::vector<GattService> &services,
122 std::shared_ptr<GattServer> server, std::shared_ptr<GattClient> client);
123 GattService *GetServiceFromJS(
124 napi_env env, napi_value object, std::shared_ptr<GattServer> server, std::shared_ptr<GattClient> client);
125
126 void GetCharacteristicVectorFromJS(napi_env env, napi_value object, std::vector<GattCharacteristic> &characteristics,
127 std::shared_ptr<GattServer> server, std::shared_ptr<GattClient> client);
128 GattCharacteristic *GetCharacteristicFromJS(
129 napi_env env, napi_value object, std::shared_ptr<GattServer> server, std::shared_ptr<GattClient> client);
130
131 void GetDescriptorVectorFromJS(napi_env env, napi_value object, std::vector<GattDescriptor> &descriptors);
132 GattDescriptor *GetDescriptorFromJS(
133 napi_env env, napi_value object, std::shared_ptr<GattServer> server, std::shared_ptr<GattClient> client);
134
135 ServerResponse GetServerResponseFromJS(napi_env env, napi_value object);
136 std::shared_ptr<SppOption> GetSppOptionFromJS(napi_env env, napi_value object);
137
138 void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName);
139 napi_value NapiGetNull(napi_env env);
140 napi_value RegisterObserver(napi_env env, napi_callback_info info);
141 napi_value DeregisterObserver(napi_env env, napi_callback_info info);
142
143 int GetProfileConnectionState(int state);
144 int GetScoConnectionState(int state);
145
146 struct AsyncCallbackInfo {
147 napi_env env_;
148 napi_async_work asyncWork_;
149 napi_deferred deferred_;
150 napi_ref callback_ = 0;
151 int errorCode_ = 0;
152 };
153
154 struct ReadCharacteristicValueCallbackInfo : public AsyncCallbackInfo {
155 GattCharacteristic *inputCharacteristic_ = nullptr;
156 const GattCharacteristic *outputCharacteristic_ = nullptr;
157 int ret = -1;
158 std::shared_ptr<GattClient> client_ = nullptr;
159 int asyncState_ = ASYNC_IDLE;
160 };
161
162 struct ReadDescriptorValueCallbackInfo : public AsyncCallbackInfo {
163 // std::shared_ptr<GattDescriptor> inputDescriptor_ = nullptr;
164 GattDescriptor *inputDescriptor_ = nullptr;
165 const GattDescriptor *outputDescriptor_ = nullptr;
166 int ret = -1;
167 std::shared_ptr<GattClient> client_ = nullptr;
168 int asyncState_ = ASYNC_IDLE;
169 };
170
171 struct GetServiceCallbackInfo : public AsyncCallbackInfo {
172 std::vector<GattService> services_;
173 std::shared_ptr<GattClient> client_ = nullptr;
174 };
175
176 struct SppListenCallbackInfo : public AsyncCallbackInfo {
177 std::shared_ptr<SppServerSocket> server_ = nullptr;
178 std::string name_ = "";
179 std::shared_ptr<SppOption> sppOption_;
180 };
181
182 struct SppAcceptCallbackInfo : public AsyncCallbackInfo {
183 std::shared_ptr<SppServerSocket> server_ = nullptr;
184 std::shared_ptr<SppClientSocket> client_ = nullptr;
185 };
186
187 struct SppConnectCallbackInfo : public AsyncCallbackInfo {
188 std::shared_ptr<SppClientSocket> client_ = nullptr;
189 std::string deviceId_ = "";
190 std::shared_ptr<BluetoothRemoteDevice> device_ = nullptr;
191 std::shared_ptr<SppOption> sppOption_ = nullptr;
192 };
193
194 struct CallbackPromiseInfo {
195 napi_ref callback = nullptr;
196 napi_deferred deferred = nullptr;
197 bool isCallback = false;
198 int errorCode = 0;
199 };
200
201 struct GattGetDeviceNameCallbackInfo {
202 napi_env env = nullptr;
203 napi_async_work asyncWork = nullptr;
204 napi_value result = nullptr;
205 std::string deviceId = "";
206 CallbackPromiseInfo promise;
207 };
208
209 struct GattGetRssiValueCallbackInfo {
210 napi_env env = nullptr;
211 napi_async_work asyncWork = nullptr;
212 napi_value result = nullptr;
213 int32_t rssi = 0;
214 std::mutex mutexRssi {};
215 std::condition_variable cvfull {};
216 CallbackPromiseInfo promise;
217 };
218
219 struct DiscoverServicesCallbackInfo {
220 int asyncState_ = ASYNC_IDLE;
221 int status_;
222 };
223
224 struct BluetoothCallbackInfo {
225 napi_env env_;
226 napi_ref callback_ = 0;
227 int state_;
228 std::string deviceId_;
229 int info_;
230 };
231
232 struct GattCharacteristicCallbackInfo : public BluetoothCallbackInfo {
233 GattCharacteristic characteristic_ = {UUID::FromString("0"), 0, 0};
234 };
235
236 struct GattDescriptorCallbackInfo : public BluetoothCallbackInfo {
237 GattDescriptor descriptor_ = {UUID::FromString("0"), 0};
238 };
239
240 struct BufferCallbackInfo : public BluetoothCallbackInfo {
241 char buffer_[1024];
242 };
243
244 namespace {
245 using sysBLEMap = std::map<std::string, std::array<std::shared_ptr<BluetoothCallbackInfo>, ARGS_SIZE_THREE>>;
246 sysBLEMap g_sysBLEObserver;
247 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> g_Observer;
248 std::shared_ptr<GattGetRssiValueCallbackInfo> callbackInfo = nullptr;
249 std::string deviceAddr;
250 } // namespace
251 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> GetObserver();
252 const sysBLEMap &GetSysBLEObserver();
253 void SetGattClinetDeviceId(const std::string &deviceId);
254 std::string GetGattClientDeviceId();
255
256 void SetRssiValueCallbackInfo(std::shared_ptr<GattGetRssiValueCallbackInfo> &callback);
257 std::shared_ptr<GattGetRssiValueCallbackInfo> GetRssiValueCallbackInfo();
258
259 void RegisterSysBLEObserver(const std::shared_ptr<BluetoothCallbackInfo> &, int32_t, const std::string &);
260 void UnregisterSysBLEObserver(const std::string &);
261 struct ScanFilter {
262 std::string deviceId; // The name of a BLE peripheral device
263 std::string name; // The name of a BLE peripheral device
264 std::string serviceUuid; // The service UUID of a BLE peripheral device
265 };
266
267 enum MatchMode {
268 MATCH_MODE_AGGRESSIVE = 1, // aggressive mode
269 MATCH_MODE_STICKY = 2 // sticky mode
270 };
271
272 enum class ScanDuty {
273 SCAN_MODE_LOW_POWER = 0, // low power mode */
274 SCAN_MODE_BALANCED = 1, // balanced power mode
275 SCAN_MODE_LOW_LATENCY = 2 // Scan using highest duty cycle
276 };
277
278 struct ScanOptions {
279 int32_t interval; // Time of delay for reporting the scan result
280 ScanDuty dutyMode = ScanDuty::SCAN_MODE_LOW_POWER; // Bluetooth LE scan mode
281 MatchMode MatchMode = MatchMode::MATCH_MODE_AGGRESSIVE; // Match mode for Bluetooth LE scan filters hardware match
282 };
283
284 struct ScanResult {
285 std::string deviceId; // Address of the scanned device
286 int32_t rssi; // RSSI of the remote device
287 std::vector<uint8_t> data; // The raw data of broadcast packet
288 };
289
290 enum ProfileConnectionState {
291 STATE_DISCONNECTED = 0, // the current profile is disconnected
292 STATE_CONNECTING = 1, // the current profile is being connected
293 STATE_CONNECTED = 2, // the current profile is connected
294 STATE_DISCONNECTING = 3 // the current profile is being disconnected
295 };
296
297 enum ScoState {
298 SCO_DISCONNECTED,
299 SCO_CONNECTING,
300 SCO_DISCONNECTING,
301 SCO_CONNECTED
302 };
303
304 enum class BluetoothState {
305 /** Indicates the local Bluetooth is off */
306 STATE_OFF = 0,
307 /** Indicates the local Bluetooth is turning on */
308 STATE_TURNING_ON = 1,
309 /** Indicates the local Bluetooth is on, and ready for use */
310 STATE_ON = 2,
311 /** Indicates the local Bluetooth is turning off */
312 STATE_TURNING_OFF = 3,
313 /** Indicates the local Bluetooth is turning LE mode on */
314 STATE_BLE_TURNING_ON = 4,
315 /** Indicates the local Bluetooth is in LE only mode */
316 STATE_BLE_ON = 5,
317 /** Indicates the local Bluetooth is turning off LE only mode */
318 STATE_BLE_TURNING_OFF = 6
319 };
320
321 enum BondState {
322 BOND_STATE_INVALID = 0,
323 BOND_STATE_BONDING = 1,
324 BOND_STATE_BONDED = 2
325 };
326
327 enum class ScanMode {
328 SCAN_MODE_NONE = 0,
329 SCAN_MODE_CONNECTABLE = 1,
330 SCAN_MODE_GENERAL_DISCOVERABLE = 2,
331 SCAN_MODE_LIMITED_DISCOVERABLE = 3,
332 SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE = 4,
333 SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE = 5
334 };
335
336 enum MajorClass {
337 MAJOR_MISC = 0x0000,
338 MAJOR_COMPUTER = 0x0100,
339 MAJOR_PHONE = 0x0200,
340 MAJOR_NETWORKING = 0x0300,
341 MAJOR_AUDIO_VIDEO = 0x0400,
342 MAJOR_PERIPHERAL = 0x0500,
343 MAJOR_IMAGING = 0x0600,
344 MAJOR_WEARABLE = 0x0700,
345 MAJOR_TOY = 0x0800,
346 MAJOR_HEALTH = 0x0900,
347 MAJOR_UNCATEGORIZED = 0x1F00
348 };
349
350 enum MajorMinorClass {
351 // The Minor Device Class field
352 // Computer Major Class
353 COMPUTER_UNCATEGORIZED = 0x0100,
354 COMPUTER_DESKTOP = 0x0104,
355 COMPUTER_SERVER = 0x0108,
356 COMPUTER_LAPTOP = 0x010C,
357 COMPUTER_HANDHELD_PC_PDA = 0x0110,
358 COMPUTER_PALM_SIZE_PC_PDA = 0x0114,
359 COMPUTER_WEARABLE = 0x0118,
360 COMPUTER_TABLET = 0x011C,
361
362 // Phone Major Class
363 PHONE_UNCATEGORIZED = 0x0200,
364 PHONE_CELLULAR = 0x0204,
365 PHONE_CORDLESS = 0x0208,
366 PHONE_SMART = 0x020C,
367 PHONE_MODEM_OR_GATEWAY = 0x0210,
368 PHONE_ISDN = 0x0214,
369
370 // LAN/Network Access Point Major Class
371 NETWORK_FULLY_AVAILABLE = 0x0300,
372 NETWORK_1_TO_17_UTILIZED = 0x0320,
373 NETWORK_17_TO_33_UTILIZED = 0x0340,
374 NETWORK_33_TO_50_UTILIZED = 0x0360,
375 NETWORK_60_TO_67_UTILIZED = 0x0380,
376 NETWORK_67_TO_83_UTILIZED = 0x03A0,
377 NETWORK_83_TO_99_UTILIZED = 0x03C0,
378 NETWORK_NO_SERVICE = 0x03E0,
379
380 // Audio/Video Major Class
381 AUDIO_VIDEO_UNCATEGORIZED = 0x0400,
382 AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404,
383 AUDIO_VIDEO_HANDSFREE = 0x0408,
384 AUDIO_VIDEO_MICROPHONE = 0x0410,
385 AUDIO_VIDEO_LOUDSPEAKER = 0x0414,
386 AUDIO_VIDEO_HEADPHONES = 0x0418,
387 AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C,
388 AUDIO_VIDEO_CAR_AUDIO = 0x0420,
389 AUDIO_VIDEO_SET_TOP_BOX = 0x0424,
390 AUDIO_VIDEO_HIFI_AUDIO = 0x0428,
391 AUDIO_VIDEO_VCR = 0x042C,
392 AUDIO_VIDEO_VIDEO_CAMERA = 0x0430,
393 AUDIO_VIDEO_CAMCORDER = 0x0434,
394 AUDIO_VIDEO_VIDEO_MONITOR = 0x0438,
395 AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C,
396 AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440,
397 AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448,
398
399 // Peripheral Major Class
400 PERIPHERAL_NON_KEYBOARD_NON_POINTING = 0x0500,
401 PERIPHERAL_KEYBOARD = 0x0540,
402 PERIPHERAL_POINTING_DEVICE = 0x0580,
403 PERIPHERAL_KEYBOARD_POINTING = 0x05C0,
404 PERIPHERAL_UNCATEGORIZED = 0x0500,
405 PERIPHERAL_JOYSTICK = 0x0504,
406 PERIPHERAL_GAMEPAD = 0x0508,
407 PERIPHERAL_REMOTE_CONTROL = 0x05C0,
408 PERIPHERAL_SENSING_DEVICE = 0x0510,
409 PERIPHERAL_DIGITIZER_TABLET = 0x0514,
410 PERIPHERAL_CARD_READER = 0x0518,
411 PERIPHERAL_DIGITAL_PEN = 0x051C,
412 PERIPHERAL_SCANNER_RFID = 0x0520,
413 PERIPHERAL_GESTURAL_INPUT = 0x0522,
414
415 // Imaging Major Class
416 IMAGING_UNCATEGORIZED = 0x0600,
417 IMAGING_DISPLAY = 0x0610,
418 IMAGING_CAMERA = 0x0620,
419 IMAGING_SCANNER = 0x0640,
420 IMAGING_PRINTER = 0x0680,
421
422 // Wearable Major Class
423 WEARABLE_UNCATEGORIZED = 0x0700,
424 WEARABLE_WRIST_WATCH = 0x0704,
425 WEARABLE_PAGER = 0x0708,
426 WEARABLE_JACKET = 0x070C,
427 WEARABLE_HELMET = 0x0710,
428 WEARABLE_GLASSES = 0x0714,
429
430 // Minor Device Class field - Toy Major Class
431 TOY_UNCATEGORIZED = 0x0800,
432 TOY_ROBOT = 0x0804,
433 TOY_VEHICLE = 0x0808,
434 TOY_DOLL_ACTION_FIGURE = 0x080C,
435 TOY_CONTROLLER = 0x0810,
436 TOY_GAME = 0x0814,
437
438 // Minor Device Class field - Health
439 HEALTH_UNCATEGORIZED = 0x0900,
440 HEALTH_BLOOD_PRESSURE = 0x0904,
441 HEALTH_THERMOMETER = 0x0908,
442 HEALTH_WEIGHING = 0x090C,
443 HEALTH_GLUCOSE = 0x0910,
444 HEALTH_PULSE_OXIMETER = 0x0914,
445 HEALTH_PULSE_RATE = 0x0918,
446 HEALTH_DATA_DISPLAY = 0x091C,
447 HEALTH_STEP_COUNTER = 0x0920,
448 HEALTH_BODY_COMPOSITION_ANALYZER = 0x0924,
449 HEALTH_PEAK_FLOW_MOITOR = 0x0928,
450 HEALTH_MEDICATION_MONITOR = 0x092C,
451 HEALTH_KNEE_PROSTHESIS = 0x0930,
452 HEALTH_ANKLE_PROSTHESIS = 0x0934,
453 HEALTH_GENERIC_HEALTH_MANAGER = 0x0938,
454 HEALTH_PERSONAL_MOBILITY_DEVICE = 0x093C,
455 };
456
457 template<typename T1, typename T2, typename T3>
458 struct AfterWorkCallbackData {
459 T1* object;
460 T2 function;
461 napi_env env;
462 napi_ref callback;
463 T3 data;
464 };
465
466 template<typename T>
AfterWorkCallback(uv_work_t * work,int status)467 void AfterWorkCallback(uv_work_t *work, int status)
468 {
469 T data = static_cast<T>(work->data);
470 (data->object->*(data->function))(work, data->data);
471 if (work != nullptr) {
472 if (work->data != nullptr) {
473 delete data;
474 work->data = nullptr;
475 }
476 delete work;
477 work = nullptr;
478 }
479 }
480 } // namespace Bluetooth
481 } // namespace OHOS
482 #endif // NAPI_BLUETOOTH_UTILS_H
483