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 = static_cast<int>(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 char * const REGISTER_STATE_CHANGE_TYPE = "stateChange";
91
92 const char * const 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, int cause);
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 napi_status ConvertOppTransferInformationToJS(napi_env env,
105 napi_value result, const BluetoothOppTransferInformation& transferInformation);
106
107 std::shared_ptr<SppOption> GetSppOptionFromJS(napi_env env, napi_value object);
108
109 void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName);
110 void SetNamedPropertyByString(napi_env env, napi_value dstObj, const std::string &strValue, const char *propName);
111 napi_value NapiGetNull(napi_env env);
112 napi_value NapiGetBooleanFalse(napi_env env);
113 napi_value NapiGetBooleanTrue(napi_env env);
114 napi_value NapiGetBooleanRet(napi_env env, bool ret);
115 napi_value NapiGetUndefinedRet(napi_env env);
116 napi_value NapiGetInt32Ret(napi_env env, int32_t res);
117
118 int GetProfileConnectionState(int state);
119 int GetScoConnectionState(int state);
120 uint32_t GetProfileId(int profile);
121
122 struct AsyncCallbackInfo {
123 napi_env env_;
124 napi_async_work asyncWork_;
125 napi_deferred deferred_;
126 napi_ref callback_ = 0;
127 int errorCode_ = 0;
128 };
129
130 struct BluetoothCallbackInfo {
131 napi_env env_;
132 napi_ref callback_ = 0;
133 int state_;
134 std::string deviceId_;
135 int info_;
136 };
137
138 struct PairConfirmedCallBackInfo {
139 int number;
140 int pinType;
141 std::string deviceAddr;
142
PairConfirmedCallBackInfoPairConfirmedCallBackInfo143 PairConfirmedCallBackInfo(int number, int pinType, std::string deviceAddr)
144 {
145 this->number = number;
146 this->pinType = pinType;
147 this->deviceAddr = deviceAddr;
148 }
149 };
150
151 struct TransforInformationCallbackInfo : public BluetoothCallbackInfo {
152 std::shared_ptr<BluetoothOppTransferInformation> information_;
153 };
154
155 namespace {
156 using sysBLEMap = std::map<std::string, std::array<std::shared_ptr<BluetoothCallbackInfo>, ARGS_SIZE_THREE>>;
157 sysBLEMap g_sysBLEObserver;
158 std::mutex g_sysBLEObserverMutex;
159 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> g_Observer;
160 std::mutex g_observerMutex;
161 } // namespace
162 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> GetObserver();
163 const sysBLEMap &GetSysBLEObserver();
164
165 void RegisterSysBLEObserver(const std::shared_ptr<BluetoothCallbackInfo> &, int32_t, const std::string &);
166 void UnregisterSysBLEObserver(const std::string &);
167 std::shared_ptr<BluetoothCallbackInfo> GetCallbackInfoByType(const std::string &type);
168
169 struct ScanFilter {
170 std::string deviceId; // The name of a BLE peripheral device
171 std::string name; // The name of a BLE peripheral device
172 UUID serviceUuid; // The service UUID of a BLE peripheral device
173 UUID serviceUuidMask;
174 UUID serviceSolicitationUuid;
175 UUID serviceSolicitationUuidMask;
176
177 std::vector<uint8_t> serviceData;
178 std::vector<uint8_t> serviceDataMask;
179
180 uint16_t manufacturerId = 0;
181 std::vector<uint8_t> manufactureData;
182 std::vector<uint8_t> manufactureDataMask;
183 };
184
185 enum MatchMode {
186 MATCH_MODE_AGGRESSIVE = 1, // aggressive mode
187 MATCH_MODE_STICKY = 2 // sticky mode
188 };
189
190 enum class ScanDuty {
191 SCAN_MODE_LOW_POWER = 0, // low power mode */
192 SCAN_MODE_BALANCED = 1, // balanced power mode
193 SCAN_MODE_LOW_LATENCY = 2 // Scan using highest duty cycle
194 };
195
196 enum class PhyType {
197 PHY_LE_1M = 1, // phy 1M
198 PHY_LE_2M = 2, // phy 2M
199 PHY_LE_CODED = 3, // phy coded
200 PHY_LE_ALL_SUPPORTED = 255 // phy coded
201 };
202
203 enum class AdvertisingState {
204 STARTED = 1, // advertiser started
205 ENABLED = 2, // advertiser temporarily enabled
206 DISABLED = 3, // advertiser temporarily disabled
207 STOPPED = 4 // advertiser stopped
208 };
209
210 struct ScanOptions {
211 int32_t interval = 0; // Time of delay for reporting the scan result
212 ScanDuty dutyMode = ScanDuty::SCAN_MODE_LOW_POWER; // Bluetooth LE scan mode
213 MatchMode matchMode = MatchMode::MATCH_MODE_AGGRESSIVE; // Match mode for Bluetooth LE scan filters hardware match
214 PhyType phyType = PhyType::PHY_LE_1M; // Phy for Bluetooth LE scan
215 };
216
217 struct ScanResult {
218 std::string deviceId; // Address of the scanned device
219 int32_t rssi; // RSSI of the remote device
220 std::vector<uint8_t> data; // The raw data of broadcast packet
221 };
222
223 struct NapiAdvManufactureData {
224 uint16_t id = 0;
225 std::string value {};
226 };
227
228 struct NapiAdvServiceData {
229 std::string uuid {};
230 std::vector<uint8_t> value {};
231 };
232
233 struct NapiNotifyCharacteristic {
234 UUID serviceUuid;
235 UUID characterUuid;
236 std::vector<uint8_t> characterValue {};
237 bool confirm;
238 };
239
240 struct NapiGattsServerResponse {
241 std::string deviceId {};
242 int transId;
243 int status;
244 int offset;
245 std::vector<uint8_t> value;
246 };
247
248 enum ProfileConnectionState {
249 STATE_DISCONNECTED = 0, // the current profile is disconnected
250 STATE_CONNECTING = 1, // the current profile is being connected
251 STATE_CONNECTED = 2, // the current profile is connected
252 STATE_DISCONNECTING = 3 // the current profile is being disconnected
253 };
254
255 enum ScoState {
256 SCO_DISCONNECTED,
257 SCO_CONNECTING,
258 SCO_DISCONNECTING,
259 SCO_CONNECTED
260 };
261
262 enum ConnectionStrategy {
263 CONNECTION_UNKNOWN = 0,
264 CONNECTION_ALLOWED = 1,
265 CONNECTION_FORBIDDEN = 2,
266 };
267
268 enum MajorClass {
269 MAJOR_MISC = 0x0000,
270 MAJOR_COMPUTER = 0x0100,
271 MAJOR_PHONE = 0x0200,
272 MAJOR_NETWORKING = 0x0300,
273 MAJOR_AUDIO_VIDEO = 0x0400,
274 MAJOR_PERIPHERAL = 0x0500,
275 MAJOR_IMAGING = 0x0600,
276 MAJOR_WEARABLE = 0x0700,
277 MAJOR_TOY = 0x0800,
278 MAJOR_HEALTH = 0x0900,
279 MAJOR_UNCATEGORIZED = 0x1F00
280 };
281
282 enum MajorMinorClass {
283 // The Minor Device Class field
284 // Computer Major Class
285 COMPUTER_UNCATEGORIZED = 0x0100,
286 COMPUTER_DESKTOP = 0x0104,
287 COMPUTER_SERVER = 0x0108,
288 COMPUTER_LAPTOP = 0x010C,
289 COMPUTER_HANDHELD_PC_PDA = 0x0110,
290 COMPUTER_PALM_SIZE_PC_PDA = 0x0114,
291 COMPUTER_WEARABLE = 0x0118,
292 COMPUTER_TABLET = 0x011C,
293
294 // Phone Major Class
295 PHONE_UNCATEGORIZED = 0x0200,
296 PHONE_CELLULAR = 0x0204,
297 PHONE_CORDLESS = 0x0208,
298 PHONE_SMART = 0x020C,
299 PHONE_MODEM_OR_GATEWAY = 0x0210,
300 PHONE_ISDN = 0x0214,
301
302 // LAN/Network Access Point Major Class
303 NETWORK_FULLY_AVAILABLE = 0x0300,
304 NETWORK_1_TO_17_UTILIZED = 0x0320,
305 NETWORK_17_TO_33_UTILIZED = 0x0340,
306 NETWORK_33_TO_50_UTILIZED = 0x0360,
307 NETWORK_60_TO_67_UTILIZED = 0x0380,
308 NETWORK_67_TO_83_UTILIZED = 0x03A0,
309 NETWORK_83_TO_99_UTILIZED = 0x03C0,
310 NETWORK_NO_SERVICE = 0x03E0,
311
312 // Audio/Video Major Class
313 AUDIO_VIDEO_UNCATEGORIZED = 0x0400,
314 AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404,
315 AUDIO_VIDEO_HANDSFREE = 0x0408,
316 AUDIO_VIDEO_MICROPHONE = 0x0410,
317 AUDIO_VIDEO_LOUDSPEAKER = 0x0414,
318 AUDIO_VIDEO_HEADPHONES = 0x0418,
319 AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C,
320 AUDIO_VIDEO_CAR_AUDIO = 0x0420,
321 AUDIO_VIDEO_SET_TOP_BOX = 0x0424,
322 AUDIO_VIDEO_HIFI_AUDIO = 0x0428,
323 AUDIO_VIDEO_VCR = 0x042C,
324 AUDIO_VIDEO_VIDEO_CAMERA = 0x0430,
325 AUDIO_VIDEO_CAMCORDER = 0x0434,
326 AUDIO_VIDEO_VIDEO_MONITOR = 0x0438,
327 AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C,
328 AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440,
329 AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448,
330
331 // Peripheral Major Class
332 PERIPHERAL_NON_KEYBOARD_NON_POINTING = 0x0500,
333 PERIPHERAL_KEYBOARD = 0x0540,
334 PERIPHERAL_POINTING_DEVICE = 0x0580,
335 PERIPHERAL_KEYBOARD_POINTING = 0x05C0,
336 PERIPHERAL_UNCATEGORIZED = 0x0500,
337 PERIPHERAL_JOYSTICK = 0x0504,
338 PERIPHERAL_GAMEPAD = 0x0508,
339 PERIPHERAL_REMOTE_CONTROL = 0x05C0,
340 PERIPHERAL_SENSING_DEVICE = 0x0510,
341 PERIPHERAL_DIGITIZER_TABLET = 0x0514,
342 PERIPHERAL_CARD_READER = 0x0518,
343 PERIPHERAL_DIGITAL_PEN = 0x051C,
344 PERIPHERAL_SCANNER_RFID = 0x0520,
345 PERIPHERAL_GESTURAL_INPUT = 0x0522,
346
347 // Imaging Major Class
348 IMAGING_UNCATEGORIZED = 0x0600,
349 IMAGING_DISPLAY = 0x0610,
350 IMAGING_CAMERA = 0x0620,
351 IMAGING_SCANNER = 0x0640,
352 IMAGING_PRINTER = 0x0680,
353
354 // Wearable Major Class
355 WEARABLE_UNCATEGORIZED = 0x0700,
356 WEARABLE_WRIST_WATCH = 0x0704,
357 WEARABLE_PAGER = 0x0708,
358 WEARABLE_JACKET = 0x070C,
359 WEARABLE_HELMET = 0x0710,
360 WEARABLE_GLASSES = 0x0714,
361
362 // Minor Device Class field - Toy Major Class
363 TOY_UNCATEGORIZED = 0x0800,
364 TOY_ROBOT = 0x0804,
365 TOY_VEHICLE = 0x0808,
366 TOY_DOLL_ACTION_FIGURE = 0x080C,
367 TOY_CONTROLLER = 0x0810,
368 TOY_GAME = 0x0814,
369
370 // Minor Device Class field - Health
371 HEALTH_UNCATEGORIZED = 0x0900,
372 HEALTH_BLOOD_PRESSURE = 0x0904,
373 HEALTH_THERMOMETER = 0x0908,
374 HEALTH_WEIGHING = 0x090C,
375 HEALTH_GLUCOSE = 0x0910,
376 HEALTH_PULSE_OXIMETER = 0x0914,
377 HEALTH_PULSE_RATE = 0x0918,
378 HEALTH_DATA_DISPLAY = 0x091C,
379 HEALTH_STEP_COUNTER = 0x0920,
380 HEALTH_BODY_COMPOSITION_ANALYZER = 0x0924,
381 HEALTH_PEAK_FLOW_MOITOR = 0x0928, // HEALTH_PEAK_FLOW_MOITOR is compatible with api8.
382 HEALTH_PEAK_FLOW_MONITOR = 0x0928,
383 HEALTH_MEDICATION_MONITOR = 0x092C,
384 HEALTH_KNEE_PROSTHESIS = 0x0930,
385 HEALTH_ANKLE_PROSTHESIS = 0x0934,
386 HEALTH_GENERIC_HEALTH_MANAGER = 0x0938,
387 HEALTH_PERSONAL_MOBILITY_DEVICE = 0x093C,
388 };
389
390 enum SppType {
391 /** RFCOMM */
392 SPP_RFCOMM = 0
393 };
394
395 enum PlayingState {
396 STATE_NOT_PLAYING = 0,
397 STATE_PLAYING = 1
398 };
399
400 enum ProfileId {
401 PROFILE_A2DP_SINK = 0,
402 PROFILE_A2DP_SOURCE = 1,
403 PROFILE_AVRCP_CT = 2,
404 PROFILE_AVRCP_TG = 3,
405 PROFILE_HANDS_FREE_AUDIO_GATEWAY = 4,
406 PROFILE_HANDS_FREE_UNIT = 5,
407 PROFILE_HID_HOST = 6,
408 PROFILE_PAN_NETWORK = 7,
409 PROFILE_PBAP_CLIENT = 8,
410 PROFILE_PBAP_SERVER = 9,
411 PROFILE_OPP = 10
412 };
413
414 enum AccessAuthorization {
415 UNKNOWN = 0,
416 ALLOWED = 1,
417 REJECTED = 2,
418 };
419
420 template<typename T1, typename T2, typename T3>
421 struct AfterWorkCallbackData {
422 T1* object;
423 T2 function;
424 napi_env env;
425 napi_ref callback;
426 T3 data;
427 };
428
429 template<typename T>
AfterWorkCallback(uv_work_t * work,int status)430 void AfterWorkCallback(uv_work_t *work, int status)
431 {
432 if (work == nullptr) {
433 return;
434 }
435 T data = static_cast<T>(work->data);
436 if (data == nullptr) {
437 return;
438 }
439 (data->object->*(data->function))(work, data->data);
440 if (work->data != nullptr) {
441 delete data;
442 work->data = nullptr;
443 }
444 delete work;
445 work = nullptr;
446 }
447
448 #define NAPI_BT_CALL_RETURN(func) \
449 do { \
450 napi_status ret = (func); \
451 if (ret != napi_ok) { \
452 HILOGE("napi call function failed. ret:%{public}d", ret); \
453 return ret; \
454 } \
455 } while (0)
456
457 #define NAPI_BT_RETURN_IF(condition, msg, ret) \
458 do { \
459 if ((condition)) { \
460 HILOGE(msg); \
461 return (ret); \
462 } \
463 } while (0)
464
465 int DoInJsMainThread(napi_env env, std::function<void(void)> func);
466
467 bool IsValidAddress(std::string bdaddr);
468 bool IsValidTransport(int transport);
469 bool IsValidConnectStrategy(int strategy);
470 napi_status NapiIsBoolean(napi_env env, napi_value value);
471 napi_status NapiIsNumber(napi_env env, napi_value value);
472 napi_status NapiIsString(napi_env env, napi_value value);
473 napi_status NapiIsFunction(napi_env env, napi_value value);
474 napi_status NapiIsArray(napi_env env, napi_value value);
475 napi_status NapiIsArrayBuffer(napi_env env, napi_value value);
476 napi_status NapiIsObject(napi_env env, napi_value value);
477 napi_status ParseNumberParams(napi_env env, napi_value object, const char *name, bool &outExist, napi_value &outParam);
478 napi_status ParseInt32Params(napi_env env, napi_value object, const char *name, bool &outExist, int32_t &outParam);
479 napi_status ParseUint32Params(napi_env env, napi_value object, const char *name, bool &outExist, uint32_t &outParam);
480 napi_status ParseBooleanParams(napi_env env, napi_value object, const char *name, bool &outExist, bool &outParam);
481 napi_status ParseStringParams(napi_env env, napi_value object, const char *name, bool &outExist,
482 std::string &outParam);
483 napi_status ParseArrayBufferParams(napi_env env, napi_value object, const char *name, bool &outExist,
484 std::vector<uint8_t> &outParam);
485 napi_status ParseUuidParams(napi_env env, napi_value object, const char *name, bool &outExist, UUID &outUuid);
486
487 bool CheckDeivceIdParam(napi_env env, napi_callback_info info, std::string &addr);
488 bool CheckProfileIdParam(napi_env env, napi_callback_info info, int &profileId);
489 bool CheckProfileIdParamEx(napi_env env, napi_callback_info info, int &profileId, size_t &argc);
490 bool CheckSetDevicePairingConfirmationParam(napi_env env, napi_callback_info info, std::string &addr, bool &accept);
491 bool CheckLocalNameParam(napi_env env, napi_callback_info info, std::string &name);
492 bool CheckSetBluetoothScanModeParam(napi_env env, napi_callback_info info, int32_t &mode, int32_t &duration);
493 napi_status CheckEmptyParam(napi_env env, napi_callback_info info);
494 napi_status NapiCheckObjectPropertiesName(napi_env env, napi_value object, const std::vector<std::string> &names);
495 napi_status CheckSetConnectStrategyParam(napi_env env, napi_callback_info info, std::string &addr, int32_t &strategy);
496 napi_status CheckDeviceAddressParam(napi_env env, napi_callback_info info, std::string &addr);
497 napi_status CheckAccessAuthorizationParam(napi_env env, napi_callback_info info, std::string &addr,
498 int32_t &accessAuthorization);
499 napi_status NapiGetOnOffCallbackName(napi_env env, napi_callback_info info, std::string &name);
500 } // namespace Bluetooth
501 } // namespace OHOS
502 #endif // NAPI_BLUETOOTH_UTILS_H
503