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_client.h"
19 #include "bluetooth_gatt_descriptor.h"
20 #include "bluetooth_gatt_server.h"
21 #include "bluetooth_gatt_service.h"
22 #include "bluetooth_log.h"
23 #include "bluetooth_opp.h"
24 #include "bluetooth_remote_device.h"
25 #include "napi/native_api.h"
26 #include "napi/native_node_api.h"
27
28 #include <atomic>
29 #include <condition_variable>
30 #include <mutex>
31 #include <cstdint>
32 #include <string>
33 #include <vector>
34
35 #include "uv.h"
36
37 #include "bluetooth_socket.h"
38
39 namespace OHOS {
40 namespace Bluetooth {
41 constexpr size_t CALLBACK_SIZE = 1;
42 constexpr size_t ARGS_SIZE_ZERO = 0;
43 constexpr size_t ARGS_SIZE_ONE = 1;
44 constexpr size_t ARGS_SIZE_TWO = 2;
45 constexpr size_t ARGS_SIZE_THREE = 3;
46 constexpr size_t ARGS_SIZE_FOUR = 4;
47 constexpr int32_t DEFAULT_INT32 = 0;
48 constexpr int32_t PARAM0 = 0;
49 constexpr int32_t PARAM1 = 1;
50 constexpr int32_t PARAM2 = 2;
51 constexpr int32_t CODE_SUCCESS = 0;
52 constexpr int32_t CODE_FAILED = -1;
53 constexpr int ASYNC_IDLE = 0;
54 constexpr int ASYNC_START = 1;
55 constexpr int ASYNC_DONE = 2;
56 constexpr int32_t THREAD_WAIT_TIMEOUT = 5;
57 constexpr int32_t BLUETOOTH_DEVICE_FIND_TYPE = 1;
58 constexpr int32_t STATE_CHANGE_TYPE = 2;
59 constexpr int32_t PIN_REQUEST_TYPE = 3;
60 constexpr int32_t BOND_STATE_CHANGE_TYPE = 4;
61 constexpr int32_t BLE_DEVICE_FIND_TYPE = 5;
62
63 constexpr uint32_t INVALID_REF_COUNT = 0xFF;
64
65 struct ServerResponse {
66 std::string deviceId = "";
67 int transId = 0;
68 int status = 0;
69 int offset = 0;
70 uint8_t *value = nullptr;
71 int length = 0;
SetValueServerResponse72 void SetValue(uint8_t *values, size_t len)
73 {
74 HILOGI("GattCharacteristic::SetValue starts");
75 if (value != nullptr) {
76 value = nullptr;
77 }
78
79 length = len;
80 value = values;
81 }
82 };
83
84 struct SppOption {
85 std::string uuid_ = "";
86 bool secure_ = false;
87 BtSocketType type_;
88 };
89
90 const std::string REGISTER_STATE_CHANGE_TYPE = "stateChange";
91
92 const std::string INVALID_DEVICE_ID = "00:00:00:00:00:00";
93
94 bool ParseString(napi_env env, std::string ¶m, napi_value args);
95 bool ParseInt32(napi_env env, int32_t ¶m, napi_value args);
96 bool ParseBool(napi_env env, bool ¶m, napi_value args);
97 bool ParseArrayBuffer(napi_env env, uint8_t **data, size_t &size, napi_value args);
98 napi_value GetCallbackErrorValue(napi_env env, int errCode);
99
100 napi_status ConvertStringVectorToJS(napi_env env, napi_value result, std::vector<std::string> &stringVector);
101 void ConvertStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state);
102 void ConvertScoStateChangeParamToJS(napi_env env, napi_value result, const std::string &device, int state);
103 void ConvertUuidsVectorToJS(napi_env env, napi_value result, const std::vector<std::string> &uuids);
104
105 void ConvertOppTransferInformationToJS(napi_env env,
106 napi_value result, BluetoothOppTransferInformation& transferInformation);
107
108 std::shared_ptr<SppOption> GetSppOptionFromJS(napi_env env, napi_value object);
109
110 void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName);
111 void SetNamedPropertyByString(napi_env env, napi_value dstObj, const std::string &strValue, const char *propName);
112 napi_value NapiGetNull(napi_env env);
113 napi_value NapiGetBooleanFalse(napi_env env);
114 napi_value NapiGetBooleanTrue(napi_env env);
115 napi_value NapiGetBooleanRet(napi_env env, bool ret);
116 napi_value NapiGetUndefinedRet(napi_env env);
117 napi_value NapiGetInt32Ret(napi_env env, int32_t res);
118
119 int GetProfileConnectionState(int state);
120 int GetScoConnectionState(int state);
121 uint32_t GetProfileId(int profile);
122
123 struct AsyncCallbackInfo {
124 napi_env env_;
125 napi_async_work asyncWork_;
126 napi_deferred deferred_;
127 napi_ref callback_ = 0;
128 int errorCode_ = 0;
129 };
130
131 struct CallbackPromiseInfo {
132 napi_ref callback = nullptr;
133 napi_deferred deferred = nullptr;
134 bool isCallback = false;
135 int errorCode = CODE_FAILED;
136 };
137
138 struct SetDevicePinCodeCallbackInfo {
139 napi_env env = nullptr;
140 napi_async_work asyncWork = nullptr;
141 std::string deviceId = "";
142 std::string pinCode = "";
143 CallbackPromiseInfo promise;
144 };
145
146 struct BluetoothCallbackInfo {
147 napi_env env_;
148 napi_ref callback_ = 0;
149 int state_;
150 std::string deviceId_;
151 int info_;
152 };
153
154 struct PairConfirmedCallBackInfo {
155 int number;
156 int pinType;
157 std::string deviceAddr;
158
PairConfirmedCallBackInfoPairConfirmedCallBackInfo159 PairConfirmedCallBackInfo(int number, int pinType, std::string deviceAddr)
160 {
161 this->number = number;
162 this->pinType = pinType;
163 this->deviceAddr = deviceAddr;
164 }
165 };
166
167 struct TransforInformationCallbackInfo : public BluetoothCallbackInfo {
168 BluetoothOppTransferInformation information_;
169 };
170
171 namespace {
172 using sysBLEMap = std::map<std::string, std::array<std::shared_ptr<BluetoothCallbackInfo>, ARGS_SIZE_THREE>>;
173 sysBLEMap g_sysBLEObserver;
174 std::mutex g_sysBLEObserverMutex;
175 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> g_Observer;
176 std::mutex g_observerMutex;
177 std::atomic<bool> isCurrentAppOperate(false);
178 } // namespace
179 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> GetObserver();
180 const sysBLEMap &GetSysBLEObserver();
181
182 void SetCurrentAppOperate(const bool &isCurrentApp);
183 bool GetCurrentAppOperate();
184 void RegisterSysBLEObserver(const std::shared_ptr<BluetoothCallbackInfo> &, int32_t, const std::string &);
185 void UnregisterSysBLEObserver(const std::string &);
186 std::shared_ptr<BluetoothCallbackInfo> GetCallbackInfoByType(const std::string &type);
187
188 struct ScanFilter {
189 std::string deviceId; // The name of a BLE peripheral device
190 std::string name; // The name of a BLE peripheral device
191 UUID serviceUuid; // The service UUID of a BLE peripheral device
192 UUID serviceUuidMask;
193 UUID serviceSolicitationUuid;
194 UUID serviceSolicitationUuidMask;
195
196 std::vector<uint8_t> serviceData;
197 std::vector<uint8_t> serviceDataMask;
198
199 uint16_t manufacturerId = 0;
200 std::vector<uint8_t> manufactureData;
201 std::vector<uint8_t> manufactureDataMask;
202 };
203
204 enum MatchMode {
205 MATCH_MODE_AGGRESSIVE = 1, // aggressive mode
206 MATCH_MODE_STICKY = 2 // sticky mode
207 };
208
209 enum class ScanDuty {
210 SCAN_MODE_LOW_POWER = 0, // low power mode */
211 SCAN_MODE_BALANCED = 1, // balanced power mode
212 SCAN_MODE_LOW_LATENCY = 2 // Scan using highest duty cycle
213 };
214
215 struct ScanOptions {
216 int32_t interval; // Time of delay for reporting the scan result
217 ScanDuty dutyMode = ScanDuty::SCAN_MODE_LOW_POWER; // Bluetooth LE scan mode
218 MatchMode MatchMode = MatchMode::MATCH_MODE_AGGRESSIVE; // Match mode for Bluetooth LE scan filters hardware match
219 };
220
221 struct ScanResult {
222 std::string deviceId; // Address of the scanned device
223 int32_t rssi; // RSSI of the remote device
224 std::vector<uint8_t> data; // The raw data of broadcast packet
225 };
226
227 struct NapiAdvManufactureData {
228 uint16_t id = 0;
229 std::string value {};
230 };
231
232 struct NapiAdvServiceData {
233 std::string uuid {};
234 std::vector<uint8_t> value {};
235 };
236
237 struct NapiNotifyCharacteristic {
238 UUID serviceUuid;
239 UUID characterUuid;
240 std::vector<uint8_t> characterValue {};
241 bool confirm;
242 };
243
244 struct NapiGattsServerResponse {
245 std::string deviceId {};
246 int transId;
247 int status;
248 int offset;
249 std::vector<uint8_t> value;
250 };
251
252 enum ProfileConnectionState {
253 STATE_DISCONNECTED = 0, // the current profile is disconnected
254 STATE_CONNECTING = 1, // the current profile is being connected
255 STATE_CONNECTED = 2, // the current profile is connected
256 STATE_DISCONNECTING = 3 // the current profile is being disconnected
257 };
258
259 enum ScoState {
260 SCO_DISCONNECTED,
261 SCO_CONNECTING,
262 SCO_DISCONNECTING,
263 SCO_CONNECTED
264 };
265
266 enum class BluetoothState {
267 /** Indicates the local Bluetooth is off */
268 STATE_OFF = 0,
269 /** Indicates the local Bluetooth is turning on */
270 STATE_TURNING_ON = 1,
271 /** Indicates the local Bluetooth is on, and ready for use */
272 STATE_ON = 2,
273 /** Indicates the local Bluetooth is turning off */
274 STATE_TURNING_OFF = 3,
275 /** Indicates the local Bluetooth is turning LE mode on */
276 STATE_BLE_TURNING_ON = 4,
277 /** Indicates the local Bluetooth is in LE only mode */
278 STATE_BLE_ON = 5,
279 /** Indicates the local Bluetooth is turning off LE only mode */
280 STATE_BLE_TURNING_OFF = 6
281 };
282 enum ConnectionStrategy {
283 CONNECTION_UNKNOWN = 0,
284 CONNECTION_ALLOWED = 1,
285 CONNECTION_FORBIDDEN =2,
286 };
287
288 enum MajorClass {
289 MAJOR_MISC = 0x0000,
290 MAJOR_COMPUTER = 0x0100,
291 MAJOR_PHONE = 0x0200,
292 MAJOR_NETWORKING = 0x0300,
293 MAJOR_AUDIO_VIDEO = 0x0400,
294 MAJOR_PERIPHERAL = 0x0500,
295 MAJOR_IMAGING = 0x0600,
296 MAJOR_WEARABLE = 0x0700,
297 MAJOR_TOY = 0x0800,
298 MAJOR_HEALTH = 0x0900,
299 MAJOR_UNCATEGORIZED = 0x1F00
300 };
301
302 enum MajorMinorClass {
303 // The Minor Device Class field
304 // Computer Major Class
305 COMPUTER_UNCATEGORIZED = 0x0100,
306 COMPUTER_DESKTOP = 0x0104,
307 COMPUTER_SERVER = 0x0108,
308 COMPUTER_LAPTOP = 0x010C,
309 COMPUTER_HANDHELD_PC_PDA = 0x0110,
310 COMPUTER_PALM_SIZE_PC_PDA = 0x0114,
311 COMPUTER_WEARABLE = 0x0118,
312 COMPUTER_TABLET = 0x011C,
313
314 // Phone Major Class
315 PHONE_UNCATEGORIZED = 0x0200,
316 PHONE_CELLULAR = 0x0204,
317 PHONE_CORDLESS = 0x0208,
318 PHONE_SMART = 0x020C,
319 PHONE_MODEM_OR_GATEWAY = 0x0210,
320 PHONE_ISDN = 0x0214,
321
322 // LAN/Network Access Point Major Class
323 NETWORK_FULLY_AVAILABLE = 0x0300,
324 NETWORK_1_TO_17_UTILIZED = 0x0320,
325 NETWORK_17_TO_33_UTILIZED = 0x0340,
326 NETWORK_33_TO_50_UTILIZED = 0x0360,
327 NETWORK_60_TO_67_UTILIZED = 0x0380,
328 NETWORK_67_TO_83_UTILIZED = 0x03A0,
329 NETWORK_83_TO_99_UTILIZED = 0x03C0,
330 NETWORK_NO_SERVICE = 0x03E0,
331
332 // Audio/Video Major Class
333 AUDIO_VIDEO_UNCATEGORIZED = 0x0400,
334 AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404,
335 AUDIO_VIDEO_HANDSFREE = 0x0408,
336 AUDIO_VIDEO_MICROPHONE = 0x0410,
337 AUDIO_VIDEO_LOUDSPEAKER = 0x0414,
338 AUDIO_VIDEO_HEADPHONES = 0x0418,
339 AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C,
340 AUDIO_VIDEO_CAR_AUDIO = 0x0420,
341 AUDIO_VIDEO_SET_TOP_BOX = 0x0424,
342 AUDIO_VIDEO_HIFI_AUDIO = 0x0428,
343 AUDIO_VIDEO_VCR = 0x042C,
344 AUDIO_VIDEO_VIDEO_CAMERA = 0x0430,
345 AUDIO_VIDEO_CAMCORDER = 0x0434,
346 AUDIO_VIDEO_VIDEO_MONITOR = 0x0438,
347 AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C,
348 AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440,
349 AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448,
350
351 // Peripheral Major Class
352 PERIPHERAL_NON_KEYBOARD_NON_POINTING = 0x0500,
353 PERIPHERAL_KEYBOARD = 0x0540,
354 PERIPHERAL_POINTING_DEVICE = 0x0580,
355 PERIPHERAL_KEYBOARD_POINTING = 0x05C0,
356 PERIPHERAL_UNCATEGORIZED = 0x0500,
357 PERIPHERAL_JOYSTICK = 0x0504,
358 PERIPHERAL_GAMEPAD = 0x0508,
359 PERIPHERAL_REMOTE_CONTROL = 0x05C0,
360 PERIPHERAL_SENSING_DEVICE = 0x0510,
361 PERIPHERAL_DIGITIZER_TABLET = 0x0514,
362 PERIPHERAL_CARD_READER = 0x0518,
363 PERIPHERAL_DIGITAL_PEN = 0x051C,
364 PERIPHERAL_SCANNER_RFID = 0x0520,
365 PERIPHERAL_GESTURAL_INPUT = 0x0522,
366
367 // Imaging Major Class
368 IMAGING_UNCATEGORIZED = 0x0600,
369 IMAGING_DISPLAY = 0x0610,
370 IMAGING_CAMERA = 0x0620,
371 IMAGING_SCANNER = 0x0640,
372 IMAGING_PRINTER = 0x0680,
373
374 // Wearable Major Class
375 WEARABLE_UNCATEGORIZED = 0x0700,
376 WEARABLE_WRIST_WATCH = 0x0704,
377 WEARABLE_PAGER = 0x0708,
378 WEARABLE_JACKET = 0x070C,
379 WEARABLE_HELMET = 0x0710,
380 WEARABLE_GLASSES = 0x0714,
381
382 // Minor Device Class field - Toy Major Class
383 TOY_UNCATEGORIZED = 0x0800,
384 TOY_ROBOT = 0x0804,
385 TOY_VEHICLE = 0x0808,
386 TOY_DOLL_ACTION_FIGURE = 0x080C,
387 TOY_CONTROLLER = 0x0810,
388 TOY_GAME = 0x0814,
389
390 // Minor Device Class field - Health
391 HEALTH_UNCATEGORIZED = 0x0900,
392 HEALTH_BLOOD_PRESSURE = 0x0904,
393 HEALTH_THERMOMETER = 0x0908,
394 HEALTH_WEIGHING = 0x090C,
395 HEALTH_GLUCOSE = 0x0910,
396 HEALTH_PULSE_OXIMETER = 0x0914,
397 HEALTH_PULSE_RATE = 0x0918,
398 HEALTH_DATA_DISPLAY = 0x091C,
399 HEALTH_STEP_COUNTER = 0x0920,
400 HEALTH_BODY_COMPOSITION_ANALYZER = 0x0924,
401 HEALTH_PEAK_FLOW_MOITOR = 0x0928,
402 HEALTH_MEDICATION_MONITOR = 0x092C,
403 HEALTH_KNEE_PROSTHESIS = 0x0930,
404 HEALTH_ANKLE_PROSTHESIS = 0x0934,
405 HEALTH_GENERIC_HEALTH_MANAGER = 0x0938,
406 HEALTH_PERSONAL_MOBILITY_DEVICE = 0x093C,
407 };
408
409 enum SppType {
410 /** RFCOMM */
411 SPP_RFCOMM = 0
412 };
413
414 enum PlayingState {
415 STATE_NOT_PLAYING = 0,
416 STATE_PLAYING = 1
417 };
418
419 enum ProfileId {
420 PROFILE_A2DP_SINK = 0,
421 PROFILE_A2DP_SOURCE = 1,
422 PROFILE_AVRCP_CT = 2,
423 PROFILE_AVRCP_TG = 3,
424 PROFILE_HANDS_FREE_AUDIO_GATEWAY = 4,
425 PROFILE_HANDS_FREE_UNIT = 5,
426 PROFILE_HID_HOST = 6,
427 PROFILE_PAN_NETWORK = 7,
428 PROFILE_PBAP_CLIENT = 8,
429 PROFILE_PBAP_SERVER = 9,
430 PROFILE_OPP = 10
431 };
432
433 template<typename T1, typename T2, typename T3>
434 struct AfterWorkCallbackData {
435 T1* object;
436 T2 function;
437 napi_env env;
438 napi_ref callback;
439 T3 data;
440 };
441
442 template<typename T>
AfterWorkCallback(uv_work_t * work,int status)443 void AfterWorkCallback(uv_work_t *work, int status)
444 {
445 if (work == nullptr) {
446 return;
447 }
448 T data = static_cast<T>(work->data);
449 (data->object->*(data->function))(work, data->data);
450 if (work->data != nullptr) {
451 delete data;
452 work->data = nullptr;
453 }
454 delete work;
455 work = nullptr;
456 }
457
458 #define NAPI_BT_CALL_RETURN(func) \
459 do { \
460 napi_status ret = (func); \
461 if (ret != napi_ok) { \
462 HILOGE("napi call function failed. ret:%{public}d", ret); \
463 return ret; \
464 } \
465 } while (0)
466
467 #define NAPI_BT_RETURN_IF(condition, msg, ret) \
468 do { \
469 if ((condition)) { \
470 HILOGE(msg); \
471 return (ret); \
472 } \
473 } while (0)
474
475 int DoInJsMainThread(napi_env env, std::function<void(void)> func);
476
477 bool IsValidAddress(std::string bdaddr);
478 bool IsValidUuid(std::string uuid);
479 bool IsValidTransport(int transport);
480 bool IsValidConnectStrategy(int strategy);
481 napi_status NapiIsBoolean(napi_env env, napi_value value);
482 napi_status NapiIsNumber(napi_env env, napi_value value);
483 napi_status NapiIsString(napi_env env, napi_value value);
484 napi_status NapiIsFunction(napi_env env, napi_value value);
485 napi_status NapiIsArray(napi_env env, napi_value value);
486 napi_status NapiIsArrayBuffer(napi_env env, napi_value value);
487 napi_status NapiIsObject(napi_env env, napi_value value);
488 napi_status ParseNumberParams(napi_env env, napi_value object, const char *name, bool &outExist, napi_value &outParam);
489 napi_status ParseInt32Params(napi_env env, napi_value object, const char *name, bool &outExist, int32_t &outParam);
490 napi_status ParseUint32Params(napi_env env, napi_value object, const char *name, bool &outExist, uint32_t &outParam);
491 napi_status ParseBooleanParams(napi_env env, napi_value object, const char *name, bool &outExist, bool &outParam);
492 napi_status ParseStringParams(napi_env env, napi_value object, const char *name, bool &outExist,
493 std::string &outParam);
494 napi_status ParseArrayBufferParams(napi_env env, napi_value object, const char *name, bool &outExist,
495 std::vector<uint8_t> &outParam);
496 napi_status ParseUuidParams(napi_env env, napi_value object, const char *name, bool &outExist, UUID &outUuid);
497
498 bool CheckDeivceIdParam(napi_env env, napi_callback_info info, std::string &addr);
499 bool CheckProfileIdParam(napi_env env, napi_callback_info info, int &profileId);
500 bool CheckSetDevicePairingConfirmationParam(napi_env env, napi_callback_info info, std::string &addr, bool &accept);
501 bool CheckLocalNameParam(napi_env env, napi_callback_info info, std::string &name);
502 bool CheckSetBluetoothScanModeParam(napi_env env, napi_callback_info info, int32_t &mode, int32_t &duration);
503 napi_status CheckEmptyParam(napi_env env, napi_callback_info info);
504 napi_status NapiCheckObjectPropertiesName(napi_env env, napi_value object, const std::vector<std::string> &names);
505 napi_status CheckSetConnectStrategyParam(napi_env env, napi_callback_info info, std::string &addr, int32_t &strategy);
506 napi_status CheckDeviceAddressParam(napi_env env, napi_callback_info info, std::string &addr);
507 } // namespace Bluetooth
508 } // namespace OHOS
509 #endif // NAPI_BLUETOOTH_UTILS_H
510