react-native-ble-nitro 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -20
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +140 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/margelo/nitro/co/zyke/ble/BleNitroBleManager.kt +899 -0
- package/android/src/main/java/com/margelo/nitro/co/zyke/ble/BleNitroPackage.kt +38 -0
- package/ios/BleNitroBleManager.swift +56 -17
- package/ios/BlePeripheralDelegate.swift +36 -8
- package/lib/commonjs/index.d.ts +22 -9
- package/lib/commonjs/index.d.ts.map +1 -1
- package/lib/commonjs/index.js +63 -12
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts +14 -5
- package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts.map +1 -1
- package/lib/commonjs/specs/NativeBleNitro.nitro.js +8 -1
- package/lib/commonjs/specs/NativeBleNitro.nitro.js.map +1 -1
- package/lib/index.d.ts +22 -9
- package/lib/index.js +61 -10
- package/lib/specs/NativeBleNitro.nitro.d.ts +14 -5
- package/lib/specs/NativeBleNitro.nitro.js +7 -0
- package/nitrogen/generated/android/BleNitroOnLoad.cpp +6 -6
- package/nitrogen/generated/android/c++/JAndroidScanMode.hpp +65 -0
- package/nitrogen/generated/android/c++/JBLEDevice.hpp +3 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool_std__shared_ptr_ArrayBuffer__std__string.hpp +78 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_BLEDevice__std__optional_std__string_.hpp +86 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string_std__shared_ptr_ArrayBuffer_.hpp +78 -0
- package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.cpp +29 -20
- package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.hpp +5 -4
- package/nitrogen/generated/android/c++/JManufacturerData.hpp +3 -0
- package/nitrogen/generated/android/c++/JManufacturerDataEntry.hpp +7 -15
- package/nitrogen/generated/android/c++/JScanFilter.hpp +8 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/AndroidScanMode.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{Func_void_bool_std__vector_double__std__string.kt → Func_void_bool_std__shared_ptr_ArrayBuffer__std__string.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{Func_void_BLEDevice.kt → Func_void_std__optional_BLEDevice__std__optional_std__string_.kt} +14 -14
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{Func_void_std__string_std__vector_double_.kt → Func_void_std__string_std__shared_ptr_ArrayBuffer_.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridNativeBleNitroSpec.kt +12 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ManufacturerDataEntry.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ScanFilter.kt +4 -1
- package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.cpp +15 -15
- package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.hpp +69 -56
- package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Umbrella.hpp +6 -0
- package/nitrogen/generated/ios/c++/HybridNativeBleNitroSpecSwift.hpp +23 -6
- package/nitrogen/generated/ios/swift/AndroidScanMode.swift +48 -0
- package/nitrogen/generated/ios/swift/{Func_void_bool_std__vector_double__std__string.swift → Func_void_bool_std__shared_ptr_ArrayBuffer__std__string.swift} +11 -11
- package/nitrogen/generated/ios/swift/Func_void_std__optional_BLEDevice__std__optional_std__string_.swift +59 -0
- package/nitrogen/generated/ios/swift/{Func_void_std__string_std__vector_double_.swift → Func_void_std__string_std__shared_ptr_ArrayBuffer_.swift} +11 -11
- package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec.swift +5 -4
- package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec_cxx.swift +41 -29
- package/nitrogen/generated/ios/swift/ManufacturerDataEntry.swift +5 -17
- package/nitrogen/generated/ios/swift/ScanFilter.swift +13 -2
- package/nitrogen/generated/shared/c++/AndroidScanMode.hpp +64 -0
- package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.hpp +10 -6
- package/nitrogen/generated/shared/c++/ManufacturerDataEntry.hpp +8 -7
- package/nitrogen/generated/shared/c++/ScanFilter.hpp +9 -3
- package/package.json +1 -1
- package/plugin/build/index.d.ts +2 -0
- package/plugin/build/index.js +2 -0
- package/plugin/build/withBleNitro.d.ts +5 -1
- package/plugin/build/withBleNitro.js +18 -7
- package/react-native.config.js +10 -2
- package/src/__tests__/index.test.ts +48 -13
- package/src/index.ts +74 -16
- package/src/specs/NativeBleNitro.nitro.ts +17 -5
- package/nitrogen/generated/android/c++/JFunc_void_BLEDevice.hpp +0 -82
- package/nitrogen/generated/android/c++/JFunc_void_bool_std__vector_double__std__string.hpp +0 -86
- package/nitrogen/generated/android/c++/JFunc_void_std__string_std__vector_double_.hpp +0 -86
- package/nitrogen/generated/ios/swift/Func_void_BLEDevice.swift +0 -47
|
@@ -110,12 +110,24 @@ open class HybridNativeBleNitroSpec_cxx {
|
|
|
110
110
|
|
|
111
111
|
// Methods
|
|
112
112
|
@inline(__always)
|
|
113
|
-
public final func startScan(filter: ScanFilter, callback: bridge.
|
|
113
|
+
public final func startScan(filter: ScanFilter, callback: bridge.Func_void_std__optional_BLEDevice__std__optional_std__string_) -> bridge.Result_void_ {
|
|
114
114
|
do {
|
|
115
|
-
try self.__implementation.startScan(filter: filter, callback: { () -> (BLEDevice) -> Void in
|
|
116
|
-
let __wrappedFunction = bridge.
|
|
117
|
-
return { (__device: BLEDevice) -> Void in
|
|
118
|
-
__wrappedFunction.call(
|
|
115
|
+
try self.__implementation.startScan(filter: filter, callback: { () -> (BLEDevice?, String?) -> Void in
|
|
116
|
+
let __wrappedFunction = bridge.wrap_Func_void_std__optional_BLEDevice__std__optional_std__string_(callback)
|
|
117
|
+
return { (__device: BLEDevice?, __error: String?) -> Void in
|
|
118
|
+
__wrappedFunction.call({ () -> bridge.std__optional_BLEDevice_ in
|
|
119
|
+
if let __unwrappedValue = __device {
|
|
120
|
+
return bridge.create_std__optional_BLEDevice_(__unwrappedValue)
|
|
121
|
+
} else {
|
|
122
|
+
return .init()
|
|
123
|
+
}
|
|
124
|
+
}(), { () -> bridge.std__optional_std__string_ in
|
|
125
|
+
if let __unwrappedValue = __error {
|
|
126
|
+
return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
|
|
127
|
+
} else {
|
|
128
|
+
return .init()
|
|
129
|
+
}
|
|
130
|
+
}())
|
|
119
131
|
}
|
|
120
132
|
}())
|
|
121
133
|
return bridge.create_Result_void_()
|
|
@@ -222,6 +234,18 @@ open class HybridNativeBleNitroSpec_cxx {
|
|
|
222
234
|
}
|
|
223
235
|
}
|
|
224
236
|
|
|
237
|
+
@inline(__always)
|
|
238
|
+
public final func requestMTU(deviceId: std.string, mtu: Double) -> bridge.Result_double_ {
|
|
239
|
+
do {
|
|
240
|
+
let __result = try self.__implementation.requestMTU(deviceId: String(deviceId), mtu: mtu)
|
|
241
|
+
let __resultCpp = __result
|
|
242
|
+
return bridge.create_Result_double_(__resultCpp)
|
|
243
|
+
} catch (let __error) {
|
|
244
|
+
let __exceptionPtr = __error.toCpp()
|
|
245
|
+
return bridge.create_Result_double_(__exceptionPtr)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
225
249
|
@inline(__always)
|
|
226
250
|
public final func discoverServices(deviceId: std.string, callback: bridge.Func_void_bool_std__string) -> bridge.Result_void_ {
|
|
227
251
|
do {
|
|
@@ -275,18 +299,12 @@ open class HybridNativeBleNitroSpec_cxx {
|
|
|
275
299
|
}
|
|
276
300
|
|
|
277
301
|
@inline(__always)
|
|
278
|
-
public final func readCharacteristic(deviceId: std.string, serviceId: std.string, characteristicId: std.string, callback: bridge.
|
|
302
|
+
public final func readCharacteristic(deviceId: std.string, serviceId: std.string, characteristicId: std.string, callback: bridge.Func_void_bool_std__shared_ptr_ArrayBuffer__std__string) -> bridge.Result_void_ {
|
|
279
303
|
do {
|
|
280
|
-
try self.__implementation.readCharacteristic(deviceId: String(deviceId), serviceId: String(serviceId), characteristicId: String(characteristicId), callback: { () -> (Bool,
|
|
281
|
-
let __wrappedFunction = bridge.
|
|
282
|
-
return { (__success: Bool, __data:
|
|
283
|
-
__wrappedFunction.call(__success,
|
|
284
|
-
var __vector = bridge.create_std__vector_double_(__data.count)
|
|
285
|
-
for __item in __data {
|
|
286
|
-
__vector.push_back(__item)
|
|
287
|
-
}
|
|
288
|
-
return __vector
|
|
289
|
-
}(), std.string(__error))
|
|
304
|
+
try self.__implementation.readCharacteristic(deviceId: String(deviceId), serviceId: String(serviceId), characteristicId: String(characteristicId), callback: { () -> (Bool, ArrayBuffer, String) -> Void in
|
|
305
|
+
let __wrappedFunction = bridge.wrap_Func_void_bool_std__shared_ptr_ArrayBuffer__std__string(callback)
|
|
306
|
+
return { (__success: Bool, __data: ArrayBuffer, __error: String) -> Void in
|
|
307
|
+
__wrappedFunction.call(__success, __data, std.string(__error))
|
|
290
308
|
}
|
|
291
309
|
}())
|
|
292
310
|
return bridge.create_Result_void_()
|
|
@@ -297,9 +315,9 @@ open class HybridNativeBleNitroSpec_cxx {
|
|
|
297
315
|
}
|
|
298
316
|
|
|
299
317
|
@inline(__always)
|
|
300
|
-
public final func writeCharacteristic(deviceId: std.string, serviceId: std.string, characteristicId: std.string, data:
|
|
318
|
+
public final func writeCharacteristic(deviceId: std.string, serviceId: std.string, characteristicId: std.string, data: ArrayBuffer, withResponse: Bool, callback: bridge.Func_void_bool_std__string) -> bridge.Result_void_ {
|
|
301
319
|
do {
|
|
302
|
-
try self.__implementation.writeCharacteristic(deviceId: String(deviceId), serviceId: String(serviceId), characteristicId: String(characteristicId), data: data
|
|
320
|
+
try self.__implementation.writeCharacteristic(deviceId: String(deviceId), serviceId: String(serviceId), characteristicId: String(characteristicId), data: data, withResponse: withResponse, callback: { () -> (Bool, String) -> Void in
|
|
303
321
|
let __wrappedFunction = bridge.wrap_Func_void_bool_std__string(callback)
|
|
304
322
|
return { (__success: Bool, __error: String) -> Void in
|
|
305
323
|
__wrappedFunction.call(__success, std.string(__error))
|
|
@@ -313,18 +331,12 @@ open class HybridNativeBleNitroSpec_cxx {
|
|
|
313
331
|
}
|
|
314
332
|
|
|
315
333
|
@inline(__always)
|
|
316
|
-
public final func subscribeToCharacteristic(deviceId: std.string, serviceId: std.string, characteristicId: std.string, updateCallback: bridge.
|
|
334
|
+
public final func subscribeToCharacteristic(deviceId: std.string, serviceId: std.string, characteristicId: std.string, updateCallback: bridge.Func_void_std__string_std__shared_ptr_ArrayBuffer_, resultCallback: bridge.Func_void_bool_std__string) -> bridge.Result_void_ {
|
|
317
335
|
do {
|
|
318
|
-
try self.__implementation.subscribeToCharacteristic(deviceId: String(deviceId), serviceId: String(serviceId), characteristicId: String(characteristicId), updateCallback: { () -> (String,
|
|
319
|
-
let __wrappedFunction = bridge.
|
|
320
|
-
return { (__characteristicId: String, __data:
|
|
321
|
-
__wrappedFunction.call(std.string(__characteristicId),
|
|
322
|
-
var __vector = bridge.create_std__vector_double_(__data.count)
|
|
323
|
-
for __item in __data {
|
|
324
|
-
__vector.push_back(__item)
|
|
325
|
-
}
|
|
326
|
-
return __vector
|
|
327
|
-
}())
|
|
336
|
+
try self.__implementation.subscribeToCharacteristic(deviceId: String(deviceId), serviceId: String(serviceId), characteristicId: String(characteristicId), updateCallback: { () -> (String, ArrayBuffer) -> Void in
|
|
337
|
+
let __wrappedFunction = bridge.wrap_Func_void_std__string_std__shared_ptr_ArrayBuffer_(updateCallback)
|
|
338
|
+
return { (__characteristicId: String, __data: ArrayBuffer) -> Void in
|
|
339
|
+
__wrappedFunction.call(std.string(__characteristicId), __data)
|
|
328
340
|
}
|
|
329
341
|
}(), resultCallback: { () -> (Bool, String) -> Void in
|
|
330
342
|
let __wrappedFunction = bridge.wrap_Func_void_bool_std__string(resultCallback)
|
|
@@ -18,14 +18,8 @@ public extension ManufacturerDataEntry {
|
|
|
18
18
|
/**
|
|
19
19
|
* Create a new instance of `ManufacturerDataEntry`.
|
|
20
20
|
*/
|
|
21
|
-
init(id: String, data:
|
|
22
|
-
self.init(std.string(id),
|
|
23
|
-
var __vector = bridge.create_std__vector_double_(data.count)
|
|
24
|
-
for __item in data {
|
|
25
|
-
__vector.push_back(__item)
|
|
26
|
-
}
|
|
27
|
-
return __vector
|
|
28
|
-
}())
|
|
21
|
+
init(id: String, data: ArrayBuffer) {
|
|
22
|
+
self.init(std.string(id), data.getArrayBuffer())
|
|
29
23
|
}
|
|
30
24
|
|
|
31
25
|
var id: String {
|
|
@@ -39,20 +33,14 @@ public extension ManufacturerDataEntry {
|
|
|
39
33
|
}
|
|
40
34
|
}
|
|
41
35
|
|
|
42
|
-
var data:
|
|
36
|
+
var data: ArrayBuffer {
|
|
43
37
|
@inline(__always)
|
|
44
38
|
get {
|
|
45
|
-
return self.__data
|
|
39
|
+
return ArrayBuffer(self.__data)
|
|
46
40
|
}
|
|
47
41
|
@inline(__always)
|
|
48
42
|
set {
|
|
49
|
-
self.__data =
|
|
50
|
-
var __vector = bridge.create_std__vector_double_(newValue.count)
|
|
51
|
-
for __item in newValue {
|
|
52
|
-
__vector.push_back(__item)
|
|
53
|
-
}
|
|
54
|
-
return __vector
|
|
55
|
-
}()
|
|
43
|
+
self.__data = newValue.getArrayBuffer()
|
|
56
44
|
}
|
|
57
45
|
}
|
|
58
46
|
}
|
|
@@ -18,14 +18,14 @@ public extension ScanFilter {
|
|
|
18
18
|
/**
|
|
19
19
|
* Create a new instance of `ScanFilter`.
|
|
20
20
|
*/
|
|
21
|
-
init(serviceUUIDs: [String], rssiThreshold: Double, allowDuplicates: Bool) {
|
|
21
|
+
init(serviceUUIDs: [String], rssiThreshold: Double, allowDuplicates: Bool, androidScanMode: AndroidScanMode) {
|
|
22
22
|
self.init({ () -> bridge.std__vector_std__string_ in
|
|
23
23
|
var __vector = bridge.create_std__vector_std__string_(serviceUUIDs.count)
|
|
24
24
|
for __item in serviceUUIDs {
|
|
25
25
|
__vector.push_back(std.string(__item))
|
|
26
26
|
}
|
|
27
27
|
return __vector
|
|
28
|
-
}(), rssiThreshold, allowDuplicates)
|
|
28
|
+
}(), rssiThreshold, allowDuplicates, androidScanMode)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
var serviceUUIDs: [String] {
|
|
@@ -66,4 +66,15 @@ public extension ScanFilter {
|
|
|
66
66
|
self.__allowDuplicates = newValue
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
var androidScanMode: AndroidScanMode {
|
|
71
|
+
@inline(__always)
|
|
72
|
+
get {
|
|
73
|
+
return self.__androidScanMode
|
|
74
|
+
}
|
|
75
|
+
@inline(__always)
|
|
76
|
+
set {
|
|
77
|
+
self.__androidScanMode = newValue
|
|
78
|
+
}
|
|
79
|
+
}
|
|
69
80
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// AndroidScanMode.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
namespace margelo::nitro::co::zyke::ble {
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* An enum which can be represented as a JavaScript enum (AndroidScanMode).
|
|
25
|
+
*/
|
|
26
|
+
enum class AndroidScanMode {
|
|
27
|
+
LOWLATENCY SWIFT_NAME(lowlatency) = 0,
|
|
28
|
+
BALANCED SWIFT_NAME(balanced) = 1,
|
|
29
|
+
LOWPOWER SWIFT_NAME(lowpower) = 2,
|
|
30
|
+
OPPORTUNISTIC SWIFT_NAME(opportunistic) = 3,
|
|
31
|
+
} CLOSED_ENUM;
|
|
32
|
+
|
|
33
|
+
} // namespace margelo::nitro::co::zyke::ble
|
|
34
|
+
|
|
35
|
+
namespace margelo::nitro {
|
|
36
|
+
|
|
37
|
+
// C++ AndroidScanMode <> JS AndroidScanMode (enum)
|
|
38
|
+
template <>
|
|
39
|
+
struct JSIConverter<margelo::nitro::co::zyke::ble::AndroidScanMode> final {
|
|
40
|
+
static inline margelo::nitro::co::zyke::ble::AndroidScanMode fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
41
|
+
int enumValue = JSIConverter<int>::fromJSI(runtime, arg);
|
|
42
|
+
return static_cast<margelo::nitro::co::zyke::ble::AndroidScanMode>(enumValue);
|
|
43
|
+
}
|
|
44
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::co::zyke::ble::AndroidScanMode arg) {
|
|
45
|
+
int enumValue = static_cast<int>(arg);
|
|
46
|
+
return JSIConverter<int>::toJSI(runtime, enumValue);
|
|
47
|
+
}
|
|
48
|
+
static inline bool canConvert(jsi::Runtime&, const jsi::Value& value) {
|
|
49
|
+
if (!value.isNumber()) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
double number = value.getNumber();
|
|
53
|
+
int integer = static_cast<int>(number);
|
|
54
|
+
if (number != integer) {
|
|
55
|
+
// The integer is not the same value as the double - we truncated floating points.
|
|
56
|
+
// Enums are all integers, so the input floating point number is obviously invalid.
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
// Check if we are within the bounds of the enum.
|
|
60
|
+
return integer >= 0 && integer <= 3;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
} // namespace margelo::nitro
|
|
@@ -21,6 +21,7 @@ namespace margelo::nitro::co::zyke::ble {
|
|
|
21
21
|
prototype.registerHybridMethod("connect", &HybridNativeBleNitroSpec::connect);
|
|
22
22
|
prototype.registerHybridMethod("disconnect", &HybridNativeBleNitroSpec::disconnect);
|
|
23
23
|
prototype.registerHybridMethod("isConnected", &HybridNativeBleNitroSpec::isConnected);
|
|
24
|
+
prototype.registerHybridMethod("requestMTU", &HybridNativeBleNitroSpec::requestMTU);
|
|
24
25
|
prototype.registerHybridMethod("discoverServices", &HybridNativeBleNitroSpec::discoverServices);
|
|
25
26
|
prototype.registerHybridMethod("getServices", &HybridNativeBleNitroSpec::getServices);
|
|
26
27
|
prototype.registerHybridMethod("getCharacteristics", &HybridNativeBleNitroSpec::getCharacteristics);
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
namespace margelo::nitro::co::zyke::ble { struct ScanFilter; }
|
|
18
18
|
// Forward declaration of `BLEDevice` to properly resolve imports.
|
|
19
19
|
namespace margelo::nitro::co::zyke::ble { struct BLEDevice; }
|
|
20
|
+
// Forward declaration of `ArrayBuffer` to properly resolve imports.
|
|
21
|
+
namespace NitroModules { class ArrayBuffer; }
|
|
20
22
|
// Forward declaration of `BLEState` to properly resolve imports.
|
|
21
23
|
namespace margelo::nitro::co::zyke::ble { enum class BLEState; }
|
|
22
24
|
// Forward declaration of `OperationResult` to properly resolve imports.
|
|
@@ -24,10 +26,11 @@ namespace margelo::nitro::co::zyke::ble { struct OperationResult; }
|
|
|
24
26
|
|
|
25
27
|
#include "ScanFilter.hpp"
|
|
26
28
|
#include "BLEDevice.hpp"
|
|
29
|
+
#include <optional>
|
|
30
|
+
#include <string>
|
|
27
31
|
#include <functional>
|
|
28
32
|
#include <vector>
|
|
29
|
-
#include <
|
|
30
|
-
#include <optional>
|
|
33
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
31
34
|
#include "BLEState.hpp"
|
|
32
35
|
#include "OperationResult.hpp"
|
|
33
36
|
#include <NitroModules/Promise.hpp>
|
|
@@ -63,19 +66,20 @@ namespace margelo::nitro::co::zyke::ble {
|
|
|
63
66
|
|
|
64
67
|
public:
|
|
65
68
|
// Methods
|
|
66
|
-
virtual void startScan(const ScanFilter& filter, const std::function<void(const BLEDevice
|
|
69
|
+
virtual void startScan(const ScanFilter& filter, const std::function<void(const std::optional<BLEDevice>& /* device */, const std::optional<std::string>& /* error */)>& callback) = 0;
|
|
67
70
|
virtual bool stopScan() = 0;
|
|
68
71
|
virtual bool isScanning() = 0;
|
|
69
72
|
virtual std::vector<BLEDevice> getConnectedDevices(const std::vector<std::string>& services) = 0;
|
|
70
73
|
virtual void connect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* deviceId */, const std::string& /* error */)>& callback, const std::optional<std::function<void(const std::string& /* deviceId */, bool /* interrupted */, const std::string& /* error */)>>& disconnectCallback) = 0;
|
|
71
74
|
virtual void disconnect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
|
|
72
75
|
virtual bool isConnected(const std::string& deviceId) = 0;
|
|
76
|
+
virtual double requestMTU(const std::string& deviceId, double mtu) = 0;
|
|
73
77
|
virtual void discoverServices(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
|
|
74
78
|
virtual std::vector<std::string> getServices(const std::string& deviceId) = 0;
|
|
75
79
|
virtual std::vector<std::string> getCharacteristics(const std::string& deviceId, const std::string& serviceId) = 0;
|
|
76
|
-
virtual void readCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(bool /* success */, const std::
|
|
77
|
-
virtual void writeCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::
|
|
78
|
-
virtual void subscribeToCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(const std::string& /* characteristicId */, const std::
|
|
80
|
+
virtual void readCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(bool /* success */, const std::shared_ptr<ArrayBuffer>& /* data */, const std::string& /* error */)>& callback) = 0;
|
|
81
|
+
virtual void writeCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::shared_ptr<ArrayBuffer>& data, bool withResponse, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
|
|
82
|
+
virtual void subscribeToCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(const std::string& /* characteristicId */, const std::shared_ptr<ArrayBuffer>& /* data */)>& updateCallback, const std::function<void(bool /* success */, const std::string& /* error */)>& resultCallback) = 0;
|
|
79
83
|
virtual void unsubscribeFromCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
|
|
80
84
|
virtual void requestBluetoothEnable(const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
|
|
81
85
|
virtual BLEState state() = 0;
|
|
@@ -18,10 +18,11 @@
|
|
|
18
18
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
19
|
#endif
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Forward declaration of `ArrayBuffer` to properly resolve imports.
|
|
22
|
+
namespace NitroModules { class ArrayBuffer; }
|
|
22
23
|
|
|
23
24
|
#include <string>
|
|
24
|
-
#include <
|
|
25
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
25
26
|
|
|
26
27
|
namespace margelo::nitro::co::zyke::ble {
|
|
27
28
|
|
|
@@ -31,11 +32,11 @@ namespace margelo::nitro::co::zyke::ble {
|
|
|
31
32
|
struct ManufacturerDataEntry {
|
|
32
33
|
public:
|
|
33
34
|
std::string id SWIFT_PRIVATE;
|
|
34
|
-
std::
|
|
35
|
+
std::shared_ptr<ArrayBuffer> data SWIFT_PRIVATE;
|
|
35
36
|
|
|
36
37
|
public:
|
|
37
38
|
ManufacturerDataEntry() = default;
|
|
38
|
-
explicit ManufacturerDataEntry(std::string id, std::
|
|
39
|
+
explicit ManufacturerDataEntry(std::string id, std::shared_ptr<ArrayBuffer> data): id(id), data(data) {}
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
} // namespace margelo::nitro::co::zyke::ble
|
|
@@ -49,13 +50,13 @@ namespace margelo::nitro {
|
|
|
49
50
|
jsi::Object obj = arg.asObject(runtime);
|
|
50
51
|
return margelo::nitro::co::zyke::ble::ManufacturerDataEntry(
|
|
51
52
|
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "id")),
|
|
52
|
-
JSIConverter<std::
|
|
53
|
+
JSIConverter<std::shared_ptr<ArrayBuffer>>::fromJSI(runtime, obj.getProperty(runtime, "data"))
|
|
53
54
|
);
|
|
54
55
|
}
|
|
55
56
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::co::zyke::ble::ManufacturerDataEntry& arg) {
|
|
56
57
|
jsi::Object obj(runtime);
|
|
57
58
|
obj.setProperty(runtime, "id", JSIConverter<std::string>::toJSI(runtime, arg.id));
|
|
58
|
-
obj.setProperty(runtime, "data", JSIConverter<std::
|
|
59
|
+
obj.setProperty(runtime, "data", JSIConverter<std::shared_ptr<ArrayBuffer>>::toJSI(runtime, arg.data));
|
|
59
60
|
return obj;
|
|
60
61
|
}
|
|
61
62
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -64,7 +65,7 @@ namespace margelo::nitro {
|
|
|
64
65
|
}
|
|
65
66
|
jsi::Object obj = value.getObject(runtime);
|
|
66
67
|
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "id"))) return false;
|
|
67
|
-
if (!JSIConverter<std::
|
|
68
|
+
if (!JSIConverter<std::shared_ptr<ArrayBuffer>>::canConvert(runtime, obj.getProperty(runtime, "data"))) return false;
|
|
68
69
|
return true;
|
|
69
70
|
}
|
|
70
71
|
};
|
|
@@ -18,10 +18,12 @@
|
|
|
18
18
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
19
|
#endif
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Forward declaration of `AndroidScanMode` to properly resolve imports.
|
|
22
|
+
namespace margelo::nitro::co::zyke::ble { enum class AndroidScanMode; }
|
|
22
23
|
|
|
23
24
|
#include <string>
|
|
24
25
|
#include <vector>
|
|
26
|
+
#include "AndroidScanMode.hpp"
|
|
25
27
|
|
|
26
28
|
namespace margelo::nitro::co::zyke::ble {
|
|
27
29
|
|
|
@@ -33,10 +35,11 @@ namespace margelo::nitro::co::zyke::ble {
|
|
|
33
35
|
std::vector<std::string> serviceUUIDs SWIFT_PRIVATE;
|
|
34
36
|
double rssiThreshold SWIFT_PRIVATE;
|
|
35
37
|
bool allowDuplicates SWIFT_PRIVATE;
|
|
38
|
+
AndroidScanMode androidScanMode SWIFT_PRIVATE;
|
|
36
39
|
|
|
37
40
|
public:
|
|
38
41
|
ScanFilter() = default;
|
|
39
|
-
explicit ScanFilter(std::vector<std::string> serviceUUIDs, double rssiThreshold, bool allowDuplicates): serviceUUIDs(serviceUUIDs), rssiThreshold(rssiThreshold), allowDuplicates(allowDuplicates) {}
|
|
42
|
+
explicit ScanFilter(std::vector<std::string> serviceUUIDs, double rssiThreshold, bool allowDuplicates, AndroidScanMode androidScanMode): serviceUUIDs(serviceUUIDs), rssiThreshold(rssiThreshold), allowDuplicates(allowDuplicates), androidScanMode(androidScanMode) {}
|
|
40
43
|
};
|
|
41
44
|
|
|
42
45
|
} // namespace margelo::nitro::co::zyke::ble
|
|
@@ -51,7 +54,8 @@ namespace margelo::nitro {
|
|
|
51
54
|
return margelo::nitro::co::zyke::ble::ScanFilter(
|
|
52
55
|
JSIConverter<std::vector<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "serviceUUIDs")),
|
|
53
56
|
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, "rssiThreshold")),
|
|
54
|
-
JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, "allowDuplicates"))
|
|
57
|
+
JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, "allowDuplicates")),
|
|
58
|
+
JSIConverter<margelo::nitro::co::zyke::ble::AndroidScanMode>::fromJSI(runtime, obj.getProperty(runtime, "androidScanMode"))
|
|
55
59
|
);
|
|
56
60
|
}
|
|
57
61
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::co::zyke::ble::ScanFilter& arg) {
|
|
@@ -59,6 +63,7 @@ namespace margelo::nitro {
|
|
|
59
63
|
obj.setProperty(runtime, "serviceUUIDs", JSIConverter<std::vector<std::string>>::toJSI(runtime, arg.serviceUUIDs));
|
|
60
64
|
obj.setProperty(runtime, "rssiThreshold", JSIConverter<double>::toJSI(runtime, arg.rssiThreshold));
|
|
61
65
|
obj.setProperty(runtime, "allowDuplicates", JSIConverter<bool>::toJSI(runtime, arg.allowDuplicates));
|
|
66
|
+
obj.setProperty(runtime, "androidScanMode", JSIConverter<margelo::nitro::co::zyke::ble::AndroidScanMode>::toJSI(runtime, arg.androidScanMode));
|
|
62
67
|
return obj;
|
|
63
68
|
}
|
|
64
69
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -69,6 +74,7 @@ namespace margelo::nitro {
|
|
|
69
74
|
if (!JSIConverter<std::vector<std::string>>::canConvert(runtime, obj.getProperty(runtime, "serviceUUIDs"))) return false;
|
|
70
75
|
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, "rssiThreshold"))) return false;
|
|
71
76
|
if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, "allowDuplicates"))) return false;
|
|
77
|
+
if (!JSIConverter<margelo::nitro::co::zyke::ble::AndroidScanMode>::canConvert(runtime, obj.getProperty(runtime, "androidScanMode"))) return false;
|
|
72
78
|
return true;
|
|
73
79
|
}
|
|
74
80
|
};
|
package/package.json
CHANGED
package/plugin/build/index.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ import withBleNitro, { withBleNitroAndroid, withBleNitroIOS, type BleNitroPlugin
|
|
|
15
15
|
* {
|
|
16
16
|
* "isBackgroundEnabled": true,
|
|
17
17
|
* "modes": ["peripheral", "central"],
|
|
18
|
+
* "neverForLocation": true,
|
|
19
|
+
* "androidAdvertisingEnabled": true,
|
|
18
20
|
* "bluetoothAlwaysPermission": "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
|
|
19
21
|
* }
|
|
20
22
|
* ]
|
package/plugin/build/index.js
CHANGED
|
@@ -53,6 +53,8 @@ Object.defineProperty(exports, "withBleNitroIOS", { enumerable: true, get: funct
|
|
|
53
53
|
* {
|
|
54
54
|
* "isBackgroundEnabled": true,
|
|
55
55
|
* "modes": ["peripheral", "central"],
|
|
56
|
+
* "neverForLocation": true,
|
|
57
|
+
* "androidAdvertisingEnabled": true,
|
|
56
58
|
* "bluetoothAlwaysPermission": "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
|
|
57
59
|
* }
|
|
58
60
|
* ]
|
|
@@ -11,7 +11,6 @@ export interface BleNitroPluginProps {
|
|
|
11
11
|
* physical location from Bluetooth scan results. The location permission
|
|
12
12
|
* will still be required on older Android devices.
|
|
13
13
|
* @default false
|
|
14
|
-
* @warning This parameter is experimental and BLE might not work. Test before releasing.
|
|
15
14
|
*/
|
|
16
15
|
neverForLocation?: boolean;
|
|
17
16
|
/**
|
|
@@ -24,6 +23,11 @@ export interface BleNitroPluginProps {
|
|
|
24
23
|
* @default "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
|
|
25
24
|
*/
|
|
26
25
|
bluetoothAlwaysPermission?: string | false;
|
|
26
|
+
/**
|
|
27
|
+
* Android advertising permission message. Set to false to skip adding the permission.
|
|
28
|
+
* @default "Allow $(PRODUCT_NAME) to advertise bluetooth devices"
|
|
29
|
+
*/
|
|
30
|
+
androidAdvertisingEnabled?: boolean;
|
|
27
31
|
}
|
|
28
32
|
export declare const withBleNitroAndroid: ConfigPlugin<BleNitroPluginProps>;
|
|
29
33
|
export declare const withBleNitroIOS: ConfigPlugin<BleNitroPluginProps>;
|
|
@@ -5,22 +5,26 @@ const config_plugins_1 = require("@expo/config-plugins");
|
|
|
5
5
|
const BLUETOOTH_PERMISSIONS = [
|
|
6
6
|
'android.permission.BLUETOOTH',
|
|
7
7
|
'android.permission.BLUETOOTH_ADMIN',
|
|
8
|
-
'android.permission.ACCESS_COARSE_LOCATION',
|
|
8
|
+
// 'android.permission.ACCESS_COARSE_LOCATION',
|
|
9
9
|
'android.permission.ACCESS_FINE_LOCATION',
|
|
10
10
|
];
|
|
11
11
|
const BLUETOOTH_PERMISSIONS_API_31 = [
|
|
12
12
|
'android.permission.BLUETOOTH_SCAN',
|
|
13
|
-
'android.permission.BLUETOOTH_ADVERTISE',
|
|
13
|
+
// 'android.permission.BLUETOOTH_ADVERTISE',
|
|
14
14
|
'android.permission.BLUETOOTH_CONNECT',
|
|
15
15
|
];
|
|
16
|
+
const BLUETOOTH_ADVERTISE_API_31 = [
|
|
17
|
+
'android.permission.BLUETOOTH_ADVERTISE',
|
|
18
|
+
];
|
|
16
19
|
const withBleNitroAndroid = (config, props = {}) => {
|
|
17
|
-
const { isBackgroundEnabled = false, neverForLocation = false } = props;
|
|
20
|
+
const { isBackgroundEnabled = false, neverForLocation = false, androidAdvertisingEnabled = false } = props;
|
|
18
21
|
return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
|
|
19
22
|
const androidManifest = config.modResults;
|
|
20
23
|
// Add required permissions
|
|
21
24
|
config_plugins_1.AndroidConfig.Permissions.ensurePermissions(config.modResults, [
|
|
22
25
|
...BLUETOOTH_PERMISSIONS,
|
|
23
26
|
...BLUETOOTH_PERMISSIONS_API_31,
|
|
27
|
+
...(androidAdvertisingEnabled ? BLUETOOTH_ADVERTISE_API_31 : []),
|
|
24
28
|
]);
|
|
25
29
|
// Add uses-feature for BLE
|
|
26
30
|
if (!androidManifest.manifest['uses-feature']) {
|
|
@@ -38,16 +42,23 @@ const withBleNitroAndroid = (config, props = {}) => {
|
|
|
38
42
|
usesFeatures.push(bleFeature);
|
|
39
43
|
}
|
|
40
44
|
// Handle location permission settings for Android 12+
|
|
45
|
+
const permissions = androidManifest.manifest['uses-permission'] || [];
|
|
41
46
|
if (neverForLocation) {
|
|
42
|
-
// Add neverForLocation attribute to location permissions for Android 12+
|
|
43
|
-
const permissions = androidManifest.manifest['uses-permission'] || [];
|
|
44
47
|
permissions.forEach((permission) => {
|
|
45
|
-
if (permission.$?.['android:name'] === 'android.permission.ACCESS_FINE_LOCATION'
|
|
46
|
-
permission
|
|
48
|
+
if (permission.$?.['android:name'] === 'android.permission.ACCESS_FINE_LOCATION') {
|
|
49
|
+
permission.$['android:maxSdkVersion'] = '30';
|
|
50
|
+
}
|
|
51
|
+
if (permission.$?.['android:name'] === 'android.permission.BLUETOOTH_SCAN') {
|
|
47
52
|
permission.$['android:usesPermissionFlags'] = 'neverForLocation';
|
|
48
53
|
}
|
|
49
54
|
});
|
|
50
55
|
}
|
|
56
|
+
permissions.forEach((permission) => {
|
|
57
|
+
if (permission.$?.['android:name'] === 'android.permission.BLUETOOTH' ||
|
|
58
|
+
permission.$?.['android:name'] === 'android.permission.BLUETOOTH_ADMIN') {
|
|
59
|
+
permission.$['android:maxSdkVersion'] = '30';
|
|
60
|
+
}
|
|
61
|
+
});
|
|
51
62
|
return config;
|
|
52
63
|
});
|
|
53
64
|
};
|
package/react-native.config.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
// https://github.com/react-native-community/cli/blob/main/docs/dependencies.md
|
|
2
|
+
|
|
1
3
|
module.exports = {
|
|
2
4
|
dependency: {
|
|
3
5
|
platforms: {
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @type {import('@react-native-community/cli-types').IOSDependencyParams}
|
|
8
|
+
*/
|
|
5
9
|
ios: {},
|
|
10
|
+
/**
|
|
11
|
+
* @type {import('@react-native-community/cli-types').AndroidDependencyParams}
|
|
12
|
+
*/
|
|
13
|
+
android: {},
|
|
6
14
|
},
|
|
7
15
|
},
|
|
8
|
-
}
|
|
16
|
+
}
|