• 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 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 &param, napi_value args);
95 bool ParseInt32(napi_env env, int32_t &param, napi_value args);
96 bool ParseBool(napi_env env, bool &param, 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