react-native-ble-nitro 1.0.0-alpha.1
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/LICENSE +21 -0
- package/README.md +298 -0
- package/android/build.gradle +55 -0
- package/android/src/main/AndroidManifest.xml +23 -0
- package/android/src/main/kotlin/co/zyke/ble/BleNitroBleManager.kt +651 -0
- package/android/src/main/kotlin/co/zyke/ble/BleNitroPackage.kt +37 -0
- package/ios/BleNitro.podspec +37 -0
- package/ios/BleNitroBleManager.swift +509 -0
- package/ios/BleNitroModule.swift +31 -0
- package/lib/BleManagerCompatFactory.d.ts +53 -0
- package/lib/BleManagerCompatFactory.js +191 -0
- package/lib/BleManagerFactory.d.ts +12 -0
- package/lib/BleManagerFactory.js +22 -0
- package/lib/compatibility/constants.d.ts +49 -0
- package/lib/compatibility/constants.js +50 -0
- package/lib/compatibility/deviceWrapper.d.ts +99 -0
- package/lib/compatibility/deviceWrapper.js +259 -0
- package/lib/compatibility/enums.d.ts +43 -0
- package/lib/compatibility/enums.js +124 -0
- package/lib/compatibility/index.d.ts +11 -0
- package/lib/compatibility/index.js +12 -0
- package/lib/compatibility/serviceData.d.ts +51 -0
- package/lib/compatibility/serviceData.js +70 -0
- package/lib/errors/BleError.d.ts +59 -0
- package/lib/errors/BleError.js +120 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +12 -0
- package/lib/specs/BleManager.nitro.d.ts +36 -0
- package/lib/specs/BleManager.nitro.js +1 -0
- package/lib/specs/Characteristic.nitro.d.ts +26 -0
- package/lib/specs/Characteristic.nitro.js +1 -0
- package/lib/specs/Descriptor.nitro.d.ts +17 -0
- package/lib/specs/Descriptor.nitro.js +1 -0
- package/lib/specs/Device.nitro.d.ts +37 -0
- package/lib/specs/Device.nitro.js +1 -0
- package/lib/specs/Service.nitro.d.ts +19 -0
- package/lib/specs/Service.nitro.js +1 -0
- package/lib/specs/types.d.ts +228 -0
- package/lib/specs/types.js +146 -0
- package/lib/utils/base64.d.ts +25 -0
- package/lib/utils/base64.js +80 -0
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/uuid.d.ts +9 -0
- package/lib/utils/uuid.js +37 -0
- package/nitro.json +15 -0
- package/package.json +102 -0
- package/plugin/build/index.d.ts +28 -0
- package/plugin/build/index.js +29 -0
- package/plugin/build/withBleNitro.d.ts +31 -0
- package/plugin/build/withBleNitro.js +87 -0
- package/react-native.config.js +13 -0
- package/src/BleManagerCompatFactory.ts +373 -0
- package/src/BleManagerFactory.ts +30 -0
- package/src/__tests__/BleManager.test.ts +327 -0
- package/src/__tests__/compatibility/deviceWrapper.test.ts +563 -0
- package/src/__tests__/compatibility/enums.test.ts +254 -0
- package/src/compatibility/constants.ts +71 -0
- package/src/compatibility/deviceWrapper.ts +427 -0
- package/src/compatibility/enums.ts +160 -0
- package/src/compatibility/index.ts +24 -0
- package/src/compatibility/serviceData.ts +85 -0
- package/src/errors/BleError.ts +193 -0
- package/src/index.ts +30 -0
- package/src/specs/BleManager.nitro.ts +152 -0
- package/src/specs/Characteristic.nitro.ts +61 -0
- package/src/specs/Descriptor.nitro.ts +28 -0
- package/src/specs/Device.nitro.ts +104 -0
- package/src/specs/Service.nitro.ts +64 -0
- package/src/specs/types.ts +259 -0
- package/src/utils/base64.ts +80 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/uuid.ts +45 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
|
+
import withBleNitro, { withBleNitroAndroid, withBleNitroIOS, type BleNitroPluginProps } from './withBleNitro';
|
|
3
|
+
/**
|
|
4
|
+
* Expo Config Plugin for react-native-ble-nitro
|
|
5
|
+
*
|
|
6
|
+
* Configures iOS and Android permissions and settings for BLE operations
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```json
|
|
10
|
+
* {
|
|
11
|
+
* "expo": {
|
|
12
|
+
* "plugins": [
|
|
13
|
+
* [
|
|
14
|
+
* "react-native-ble-nitro",
|
|
15
|
+
* {
|
|
16
|
+
* "isBackgroundEnabled": true,
|
|
17
|
+
* "modes": ["peripheral", "central"],
|
|
18
|
+
* "bluetoothAlwaysPermission": "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
|
|
19
|
+
* }
|
|
20
|
+
* ]
|
|
21
|
+
* ]
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare const plugin: ConfigPlugin<BleNitroPluginProps | void>;
|
|
27
|
+
export default plugin;
|
|
28
|
+
export { withBleNitro, withBleNitroAndroid, withBleNitroIOS, type BleNitroPluginProps };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import withBleNitro, { withBleNitroAndroid, withBleNitroIOS } from './withBleNitro';
|
|
2
|
+
/**
|
|
3
|
+
* Expo Config Plugin for react-native-ble-nitro
|
|
4
|
+
*
|
|
5
|
+
* Configures iOS and Android permissions and settings for BLE operations
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```json
|
|
9
|
+
* {
|
|
10
|
+
* "expo": {
|
|
11
|
+
* "plugins": [
|
|
12
|
+
* [
|
|
13
|
+
* "react-native-ble-nitro",
|
|
14
|
+
* {
|
|
15
|
+
* "isBackgroundEnabled": true,
|
|
16
|
+
* "modes": ["peripheral", "central"],
|
|
17
|
+
* "bluetoothAlwaysPermission": "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
|
|
18
|
+
* }
|
|
19
|
+
* ]
|
|
20
|
+
* ]
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
const plugin = (config, props) => {
|
|
26
|
+
return withBleNitro(config, props || {});
|
|
27
|
+
};
|
|
28
|
+
export default plugin;
|
|
29
|
+
export { withBleNitro, withBleNitroAndroid, withBleNitroIOS };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
|
+
export interface BleNitroPluginProps {
|
|
3
|
+
/**
|
|
4
|
+
* Enable background BLE support on Android.
|
|
5
|
+
* Adds required permissions and features to AndroidManifest.xml
|
|
6
|
+
* @default false
|
|
7
|
+
*/
|
|
8
|
+
isBackgroundEnabled?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Set to true only if you can strongly assert that your app never derives
|
|
11
|
+
* physical location from Bluetooth scan results. The location permission
|
|
12
|
+
* will still be required on older Android devices.
|
|
13
|
+
* @default false
|
|
14
|
+
* @warning This parameter is experimental and BLE might not work. Test before releasing.
|
|
15
|
+
*/
|
|
16
|
+
neverForLocation?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* iOS background modes for BLE operations
|
|
19
|
+
* @default undefined
|
|
20
|
+
*/
|
|
21
|
+
modes?: ('peripheral' | 'central')[];
|
|
22
|
+
/**
|
|
23
|
+
* iOS Bluetooth permission message. Set to false to skip adding the permission.
|
|
24
|
+
* @default "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
|
|
25
|
+
*/
|
|
26
|
+
bluetoothAlwaysPermission?: string | false;
|
|
27
|
+
}
|
|
28
|
+
export declare const withBleNitroAndroid: ConfigPlugin<BleNitroPluginProps>;
|
|
29
|
+
export declare const withBleNitroIOS: ConfigPlugin<BleNitroPluginProps>;
|
|
30
|
+
declare const withBleNitro: ConfigPlugin<BleNitroPluginProps>;
|
|
31
|
+
export default withBleNitro;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { AndroidConfig, WarningAggregator, withAndroidManifest, withInfoPlist, } from 'expo/config-plugins';
|
|
2
|
+
const BLUETOOTH_PERMISSIONS = [
|
|
3
|
+
'android.permission.BLUETOOTH',
|
|
4
|
+
'android.permission.BLUETOOTH_ADMIN',
|
|
5
|
+
'android.permission.ACCESS_COARSE_LOCATION',
|
|
6
|
+
'android.permission.ACCESS_FINE_LOCATION',
|
|
7
|
+
];
|
|
8
|
+
const BLUETOOTH_PERMISSIONS_API_31 = [
|
|
9
|
+
'android.permission.BLUETOOTH_SCAN',
|
|
10
|
+
'android.permission.BLUETOOTH_ADVERTISE',
|
|
11
|
+
'android.permission.BLUETOOTH_CONNECT',
|
|
12
|
+
];
|
|
13
|
+
export const withBleNitroAndroid = (config, props = {}) => {
|
|
14
|
+
const { isBackgroundEnabled = false, neverForLocation = false } = props;
|
|
15
|
+
return withAndroidManifest(config, (config) => {
|
|
16
|
+
const androidManifest = config.modResults;
|
|
17
|
+
// Add required permissions
|
|
18
|
+
AndroidConfig.Permissions.ensurePermissions(config.modResults, [
|
|
19
|
+
...BLUETOOTH_PERMISSIONS,
|
|
20
|
+
...BLUETOOTH_PERMISSIONS_API_31,
|
|
21
|
+
]);
|
|
22
|
+
// Add uses-feature for BLE
|
|
23
|
+
if (!androidManifest.manifest['uses-feature']) {
|
|
24
|
+
androidManifest.manifest['uses-feature'] = [];
|
|
25
|
+
}
|
|
26
|
+
const usesFeatures = androidManifest.manifest['uses-feature'];
|
|
27
|
+
// Add BLE feature requirement
|
|
28
|
+
const bleFeature = {
|
|
29
|
+
$: {
|
|
30
|
+
'android:name': 'android.hardware.bluetooth_le',
|
|
31
|
+
'android:required': (isBackgroundEnabled ? 'true' : 'false'),
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
if (!usesFeatures.find((f) => f.$?.['android:name'] === 'android.hardware.bluetooth_le')) {
|
|
35
|
+
usesFeatures.push(bleFeature);
|
|
36
|
+
}
|
|
37
|
+
// Handle location permission settings for Android 12+
|
|
38
|
+
if (neverForLocation) {
|
|
39
|
+
// Add neverForLocation attribute to location permissions for Android 12+
|
|
40
|
+
const permissions = androidManifest.manifest['uses-permission'] || [];
|
|
41
|
+
permissions.forEach((permission) => {
|
|
42
|
+
if (permission.$?.['android:name'] === 'android.permission.ACCESS_FINE_LOCATION' ||
|
|
43
|
+
permission.$?.['android:name'] === 'android.permission.ACCESS_COARSE_LOCATION') {
|
|
44
|
+
permission.$['android:usesPermissionFlags'] = 'neverForLocation';
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return config;
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
export const withBleNitroIOS = (config, props = {}) => {
|
|
52
|
+
const { modes, bluetoothAlwaysPermission = 'Allow $(PRODUCT_NAME) to connect to bluetooth devices' } = props;
|
|
53
|
+
return withInfoPlist(config, (config) => {
|
|
54
|
+
// Add NSBluetoothAlwaysUsageDescription
|
|
55
|
+
if (bluetoothAlwaysPermission !== false) {
|
|
56
|
+
config.modResults.NSBluetoothAlwaysUsageDescription = bluetoothAlwaysPermission;
|
|
57
|
+
}
|
|
58
|
+
// Add background modes if specified
|
|
59
|
+
if (modes && modes.length > 0) {
|
|
60
|
+
const backgroundModes = modes.map(mode => `bluetooth-${mode}`);
|
|
61
|
+
if (!config.modResults.UIBackgroundModes) {
|
|
62
|
+
config.modResults.UIBackgroundModes = [];
|
|
63
|
+
}
|
|
64
|
+
backgroundModes.forEach(mode => {
|
|
65
|
+
if (!config.modResults.UIBackgroundModes.includes(mode)) {
|
|
66
|
+
config.modResults.UIBackgroundModes.push(mode);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return config;
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
const withBleNitro = (config, props = {}) => {
|
|
74
|
+
// Validate props
|
|
75
|
+
if (props.neverForLocation && !props.isBackgroundEnabled) {
|
|
76
|
+
WarningAggregator.addWarningForPlatform('android', 'react-native-ble-nitro', 'neverForLocation is set to true but isBackgroundEnabled is false. ' +
|
|
77
|
+
'This might cause issues with BLE scanning on some Android devices.');
|
|
78
|
+
}
|
|
79
|
+
if (props.modes && props.modes.some(mode => !['peripheral', 'central'].includes(mode))) {
|
|
80
|
+
WarningAggregator.addWarningForPlatform('ios', 'react-native-ble-nitro', 'Invalid background mode specified. Only "peripheral" and "central" are supported.');
|
|
81
|
+
}
|
|
82
|
+
// Apply platform-specific configurations
|
|
83
|
+
config = withBleNitroAndroid(config, props);
|
|
84
|
+
config = withBleNitroIOS(config, props);
|
|
85
|
+
return config;
|
|
86
|
+
};
|
|
87
|
+
export default withBleNitro;
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BleManager Compatibility Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates BleManager instances with full react-native-ble-plx compatibility
|
|
5
|
+
* by wrapping the Nitro implementation with compatibility shims
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createBleManager } from './BleManagerFactory';
|
|
9
|
+
import type { BleManager as BleManagerInterface } from './specs/BleManager.nitro';
|
|
10
|
+
import type {
|
|
11
|
+
BleManagerOptions,
|
|
12
|
+
UUID,
|
|
13
|
+
DeviceId,
|
|
14
|
+
TransactionId,
|
|
15
|
+
ConnectionPriority,
|
|
16
|
+
ConnectionOptions,
|
|
17
|
+
ScanOptions,
|
|
18
|
+
NativeDevice,
|
|
19
|
+
NativeService,
|
|
20
|
+
NativeCharacteristic,
|
|
21
|
+
NativeDescriptor,
|
|
22
|
+
LogLevel,
|
|
23
|
+
State,
|
|
24
|
+
Subscription
|
|
25
|
+
} from './specs/types';
|
|
26
|
+
import { DeviceWrapper } from './compatibility/deviceWrapper';
|
|
27
|
+
import {
|
|
28
|
+
stateToString,
|
|
29
|
+
stringToState,
|
|
30
|
+
logLevelToString,
|
|
31
|
+
stringToLogLevel,
|
|
32
|
+
normalizeLogLevel,
|
|
33
|
+
normalizeCharacteristicSubscriptionType,
|
|
34
|
+
characteristicSubscriptionTypeToString
|
|
35
|
+
} from './compatibility/enums';
|
|
36
|
+
import { serviceDataMapToArray } from './compatibility/serviceData';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* BleManager wrapper that provides react-native-ble-plx compatibility
|
|
40
|
+
*/
|
|
41
|
+
export class BleManagerCompat {
|
|
42
|
+
private bleManager: BleManagerInterface;
|
|
43
|
+
|
|
44
|
+
constructor(options?: BleManagerOptions) {
|
|
45
|
+
this.bleManager = createBleManager(options);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Lifecycle
|
|
49
|
+
async destroy(): Promise<void> {
|
|
50
|
+
return await this.bleManager.destroy();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Common operations with compatibility
|
|
54
|
+
async setLogLevel(logLevel: LogLevel | string): Promise<string> {
|
|
55
|
+
const normalizedLogLevel = normalizeLogLevel(logLevel);
|
|
56
|
+
const result = await this.bleManager.setLogLevel(normalizedLogLevel);
|
|
57
|
+
return logLevelToString(result);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async logLevel(): Promise<string> {
|
|
61
|
+
const result = await this.bleManager.logLevel();
|
|
62
|
+
return logLevelToString(result);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async cancelTransaction(transactionId: TransactionId): Promise<void> {
|
|
66
|
+
return await this.bleManager.cancelTransaction(transactionId);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// State management with string conversion
|
|
70
|
+
async enable(transactionId?: TransactionId): Promise<BleManagerCompat> {
|
|
71
|
+
await this.bleManager.enable(transactionId);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async disable(transactionId?: TransactionId): Promise<BleManagerCompat> {
|
|
76
|
+
await this.bleManager.disable(transactionId);
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async state(): Promise<string> {
|
|
81
|
+
const result = await this.bleManager.state();
|
|
82
|
+
return stateToString(result);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
onStateChange(
|
|
86
|
+
listener: (newState: string) => void,
|
|
87
|
+
emitCurrentState?: boolean
|
|
88
|
+
): Subscription {
|
|
89
|
+
return this.bleManager.onStateChange((state) => {
|
|
90
|
+
listener(stateToString(state));
|
|
91
|
+
}, emitCurrentState);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Device scanning with compatibility wrappers
|
|
95
|
+
async startDeviceScan(
|
|
96
|
+
uuids: UUID[] | null,
|
|
97
|
+
options: ScanOptions | null,
|
|
98
|
+
listener: (error: any | null, scannedDevice: DeviceWrapper | null) => void
|
|
99
|
+
): Promise<void> {
|
|
100
|
+
return await this.bleManager.startDeviceScan(uuids, options, (error, device) => {
|
|
101
|
+
listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async stopDeviceScan(): Promise<void> {
|
|
106
|
+
return await this.bleManager.stopDeviceScan();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Connection management
|
|
110
|
+
async connectToDevice(
|
|
111
|
+
deviceIdentifier: DeviceId,
|
|
112
|
+
options?: Partial<ConnectionOptions>
|
|
113
|
+
): Promise<DeviceWrapper> {
|
|
114
|
+
// Provide defaults for Nitro's required fields
|
|
115
|
+
const connectionOptions: ConnectionOptions = {
|
|
116
|
+
autoConnect: options?.autoConnect ?? false,
|
|
117
|
+
requestMTU: options?.requestMTU ?? 23,
|
|
118
|
+
timeout: options?.timeout ?? 0,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const result = await this.bleManager.connectToDevice(deviceIdentifier, connectionOptions);
|
|
122
|
+
return new DeviceWrapper(this.createDeviceFromNative(result));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async cancelDeviceConnection(deviceIdentifier: DeviceId): Promise<DeviceWrapper> {
|
|
126
|
+
const result = await this.bleManager.cancelDeviceConnection(deviceIdentifier);
|
|
127
|
+
return new DeviceWrapper(this.createDeviceFromNative(result));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async isDeviceConnected(deviceIdentifier: DeviceId): Promise<boolean> {
|
|
131
|
+
return await this.bleManager.isDeviceConnected(deviceIdentifier);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
onDeviceDisconnected(
|
|
135
|
+
deviceIdentifier: DeviceId,
|
|
136
|
+
listener: (error: any | null, device: DeviceWrapper | null) => void
|
|
137
|
+
): Subscription {
|
|
138
|
+
return this.bleManager.onDeviceDisconnected(deviceIdentifier, (error, device) => {
|
|
139
|
+
listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Device discovery
|
|
144
|
+
async devices(deviceIdentifiers: DeviceId[]): Promise<DeviceWrapper[]> {
|
|
145
|
+
const result = await this.bleManager.devices(deviceIdentifiers);
|
|
146
|
+
return result.map(device => new DeviceWrapper(this.createDeviceFromNative(device)));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async connectedDevices(serviceUUIDs: UUID[]): Promise<DeviceWrapper[]> {
|
|
150
|
+
const result = await this.bleManager.connectedDevices(serviceUUIDs);
|
|
151
|
+
return result.map(device => new DeviceWrapper(this.createDeviceFromNative(device)));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// RSSI and MTU operations
|
|
155
|
+
async readRSSIForDevice(
|
|
156
|
+
deviceIdentifier: DeviceId,
|
|
157
|
+
transactionId?: TransactionId
|
|
158
|
+
): Promise<DeviceWrapper> {
|
|
159
|
+
const result = await this.bleManager.readRSSIForDevice(deviceIdentifier, transactionId);
|
|
160
|
+
return new DeviceWrapper(this.createDeviceFromNative(result));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async requestMTUForDevice(
|
|
164
|
+
deviceIdentifier: DeviceId,
|
|
165
|
+
mtu: number,
|
|
166
|
+
transactionId?: TransactionId
|
|
167
|
+
): Promise<DeviceWrapper> {
|
|
168
|
+
const result = await this.bleManager.requestMTUForDevice(deviceIdentifier, mtu, transactionId);
|
|
169
|
+
return new DeviceWrapper(this.createDeviceFromNative(result));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async requestConnectionPriorityForDevice(
|
|
173
|
+
deviceIdentifier: DeviceId,
|
|
174
|
+
connectionPriority: ConnectionPriority,
|
|
175
|
+
transactionId?: TransactionId
|
|
176
|
+
): Promise<DeviceWrapper> {
|
|
177
|
+
const result = await this.bleManager.requestConnectionPriorityForDevice(
|
|
178
|
+
deviceIdentifier,
|
|
179
|
+
connectionPriority,
|
|
180
|
+
transactionId
|
|
181
|
+
);
|
|
182
|
+
return new DeviceWrapper(this.createDeviceFromNative(result));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Service discovery
|
|
186
|
+
async discoverAllServicesAndCharacteristicsForDevice(
|
|
187
|
+
deviceIdentifier: DeviceId,
|
|
188
|
+
transactionId?: TransactionId
|
|
189
|
+
): Promise<DeviceWrapper> {
|
|
190
|
+
const result = await this.bleManager.discoverAllServicesAndCharacteristicsForDevice(
|
|
191
|
+
deviceIdentifier,
|
|
192
|
+
transactionId
|
|
193
|
+
);
|
|
194
|
+
return new DeviceWrapper(this.createDeviceFromNative(result));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Service operations
|
|
198
|
+
async servicesForDevice(deviceIdentifier: DeviceId): Promise<NativeService[]> {
|
|
199
|
+
return await this.bleManager.servicesForDevice(deviceIdentifier);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Characteristic operations
|
|
203
|
+
async characteristicsForDevice(
|
|
204
|
+
deviceIdentifier: DeviceId,
|
|
205
|
+
serviceUUID: UUID
|
|
206
|
+
): Promise<NativeCharacteristic[]> {
|
|
207
|
+
return await this.bleManager.characteristicsForDevice(deviceIdentifier, serviceUUID);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async readCharacteristicForDevice(
|
|
211
|
+
deviceIdentifier: DeviceId,
|
|
212
|
+
serviceUUID: UUID,
|
|
213
|
+
characteristicUUID: UUID,
|
|
214
|
+
transactionId?: TransactionId
|
|
215
|
+
): Promise<NativeCharacteristic> {
|
|
216
|
+
return await this.bleManager.readCharacteristicForDevice(
|
|
217
|
+
deviceIdentifier,
|
|
218
|
+
serviceUUID,
|
|
219
|
+
characteristicUUID,
|
|
220
|
+
transactionId
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async writeCharacteristicWithResponseForDevice(
|
|
225
|
+
deviceIdentifier: DeviceId,
|
|
226
|
+
serviceUUID: UUID,
|
|
227
|
+
characteristicUUID: UUID,
|
|
228
|
+
base64Value: string,
|
|
229
|
+
transactionId?: TransactionId
|
|
230
|
+
): Promise<NativeCharacteristic> {
|
|
231
|
+
return await this.bleManager.writeCharacteristicWithResponseForDevice(
|
|
232
|
+
deviceIdentifier,
|
|
233
|
+
serviceUUID,
|
|
234
|
+
characteristicUUID,
|
|
235
|
+
base64Value,
|
|
236
|
+
transactionId
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async writeCharacteristicWithoutResponseForDevice(
|
|
241
|
+
deviceIdentifier: DeviceId,
|
|
242
|
+
serviceUUID: UUID,
|
|
243
|
+
characteristicUUID: UUID,
|
|
244
|
+
base64Value: string,
|
|
245
|
+
transactionId?: TransactionId
|
|
246
|
+
): Promise<NativeCharacteristic> {
|
|
247
|
+
return await this.bleManager.writeCharacteristicWithoutResponseForDevice(
|
|
248
|
+
deviceIdentifier,
|
|
249
|
+
serviceUUID,
|
|
250
|
+
characteristicUUID,
|
|
251
|
+
base64Value,
|
|
252
|
+
transactionId
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
monitorCharacteristicForDevice(
|
|
257
|
+
deviceIdentifier: DeviceId,
|
|
258
|
+
serviceUUID: UUID,
|
|
259
|
+
characteristicUUID: UUID,
|
|
260
|
+
listener: (error: any | null, characteristic: NativeCharacteristic | null) => void,
|
|
261
|
+
transactionId?: TransactionId,
|
|
262
|
+
subscriptionType?: 'notification' | 'indication'
|
|
263
|
+
): Subscription {
|
|
264
|
+
const nitroSubscriptionType = subscriptionType
|
|
265
|
+
? normalizeCharacteristicSubscriptionType(subscriptionType)
|
|
266
|
+
: undefined;
|
|
267
|
+
|
|
268
|
+
return this.bleManager.monitorCharacteristicForDevice(
|
|
269
|
+
deviceIdentifier,
|
|
270
|
+
serviceUUID,
|
|
271
|
+
characteristicUUID,
|
|
272
|
+
listener,
|
|
273
|
+
transactionId,
|
|
274
|
+
nitroSubscriptionType
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Descriptor operations
|
|
279
|
+
async descriptorsForDevice(
|
|
280
|
+
deviceIdentifier: DeviceId,
|
|
281
|
+
serviceUUID: UUID,
|
|
282
|
+
characteristicUUID: UUID
|
|
283
|
+
): Promise<NativeDescriptor[]> {
|
|
284
|
+
return await this.bleManager.descriptorsForDevice(
|
|
285
|
+
deviceIdentifier,
|
|
286
|
+
serviceUUID,
|
|
287
|
+
characteristicUUID
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async readDescriptorForDevice(
|
|
292
|
+
deviceIdentifier: DeviceId,
|
|
293
|
+
serviceUUID: UUID,
|
|
294
|
+
characteristicUUID: UUID,
|
|
295
|
+
descriptorUUID: UUID,
|
|
296
|
+
transactionId?: TransactionId
|
|
297
|
+
): Promise<NativeDescriptor> {
|
|
298
|
+
return await this.bleManager.readDescriptorForDevice(
|
|
299
|
+
deviceIdentifier,
|
|
300
|
+
serviceUUID,
|
|
301
|
+
characteristicUUID,
|
|
302
|
+
descriptorUUID,
|
|
303
|
+
transactionId
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async writeDescriptorForDevice(
|
|
308
|
+
deviceIdentifier: DeviceId,
|
|
309
|
+
serviceUUID: UUID,
|
|
310
|
+
characteristicUUID: UUID,
|
|
311
|
+
descriptorUUID: UUID,
|
|
312
|
+
valueBase64: string,
|
|
313
|
+
transactionId?: TransactionId
|
|
314
|
+
): Promise<NativeDescriptor> {
|
|
315
|
+
return await this.bleManager.writeDescriptorForDevice(
|
|
316
|
+
deviceIdentifier,
|
|
317
|
+
serviceUUID,
|
|
318
|
+
characteristicUUID,
|
|
319
|
+
descriptorUUID,
|
|
320
|
+
valueBase64,
|
|
321
|
+
transactionId
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Helper method to create a Device wrapper from NativeDevice data
|
|
327
|
+
* This is a temporary method until we have proper Device Nitro objects
|
|
328
|
+
*/
|
|
329
|
+
private createDeviceFromNative(nativeDevice: NativeDevice): any {
|
|
330
|
+
// This is a placeholder - in the actual implementation, we'd need to create
|
|
331
|
+
// proper Nitro Device objects, but for now we'll work with the native data
|
|
332
|
+
return {
|
|
333
|
+
id: nativeDevice.id,
|
|
334
|
+
deviceName: nativeDevice.name,
|
|
335
|
+
rssi: nativeDevice.rssi,
|
|
336
|
+
mtu: nativeDevice.mtu,
|
|
337
|
+
manufacturerData: nativeDevice.manufacturerData,
|
|
338
|
+
rawScanRecord: nativeDevice.rawScanRecord,
|
|
339
|
+
serviceData: nativeDevice.serviceData,
|
|
340
|
+
serviceUUIDs: nativeDevice.serviceUUIDs,
|
|
341
|
+
localName: nativeDevice.localName,
|
|
342
|
+
txPowerLevel: nativeDevice.txPowerLevel,
|
|
343
|
+
solicitedServiceUUIDs: nativeDevice.solicitedServiceUUIDs,
|
|
344
|
+
isConnectable: nativeDevice.isConnectable,
|
|
345
|
+
overflowServiceUUIDs: nativeDevice.overflowServiceUUIDs,
|
|
346
|
+
// Add placeholder methods - these would be implemented in the actual Device class
|
|
347
|
+
requestConnectionPriority: async () => this.createDeviceFromNative(nativeDevice),
|
|
348
|
+
readRSSI: async () => this.createDeviceFromNative(nativeDevice),
|
|
349
|
+
requestMTU: async () => this.createDeviceFromNative(nativeDevice),
|
|
350
|
+
connect: async () => this.createDeviceFromNative(nativeDevice),
|
|
351
|
+
cancelConnection: async () => this.createDeviceFromNative(nativeDevice),
|
|
352
|
+
isConnected: async () => false,
|
|
353
|
+
onDisconnected: () => ({ remove: () => {} }),
|
|
354
|
+
discoverAllServicesAndCharacteristics: async () => this.createDeviceFromNative(nativeDevice),
|
|
355
|
+
services: async () => [],
|
|
356
|
+
characteristicsForService: async () => [],
|
|
357
|
+
readCharacteristicForService: async () => ({}),
|
|
358
|
+
writeCharacteristicWithResponseForService: async () => ({}),
|
|
359
|
+
writeCharacteristicWithoutResponseForService: async () => ({}),
|
|
360
|
+
monitorCharacteristicForService: () => ({ remove: () => {} }),
|
|
361
|
+
descriptorsForService: async () => [],
|
|
362
|
+
readDescriptorForService: async () => ({}),
|
|
363
|
+
writeDescriptorForService: async () => ({}),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Factory function to create a compatibility BleManager
|
|
370
|
+
*/
|
|
371
|
+
export function createBleManagerCompat(options?: BleManagerOptions): BleManagerCompat {
|
|
372
|
+
return new BleManagerCompat(options);
|
|
373
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NitroModules } from 'react-native-nitro-modules';
|
|
2
|
+
import type { BleManager as BleManagerInterface } from './specs/BleManager.nitro';
|
|
3
|
+
import type { BleManagerOptions } from './specs/types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a BleManager instance using Nitro Modules
|
|
7
|
+
* This function maintains compatibility with react-native-ble-plx's BleManager constructor
|
|
8
|
+
*/
|
|
9
|
+
export function createBleManager(options?: BleManagerOptions): BleManagerInterface {
|
|
10
|
+
const BleManagerModule = NitroModules.createHybridObject<BleManagerInterface>('BleManager');
|
|
11
|
+
|
|
12
|
+
if (!BleManagerModule) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
'Failed to create BleManager: Nitro module not found. ' +
|
|
15
|
+
'Make sure react-native-ble-nitro is properly installed and linked.'
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// If options are provided, we could initialize with them
|
|
20
|
+
// For now, we return the module directly as Nitro handles the native initialization
|
|
21
|
+
return BleManagerModule;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Legacy compatibility: Export a BleManager constructor function
|
|
26
|
+
* This maintains compatibility with code that imports { BleManager } from 'react-native-ble-plx'
|
|
27
|
+
*/
|
|
28
|
+
export const BleManager = function(options?: BleManagerOptions): BleManagerInterface {
|
|
29
|
+
return createBleManager(options);
|
|
30
|
+
} as any;
|