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