Files
universal_ble/pigeon/universal_ble.dart
T
Foti Dim 8557a46d05 Add auto-connect support (#206)
* Add autoConnect support

* Enhance autoConnect functionality for Bluetooth devices

- Added support for managing a set of auto-connect devices in both Android and iOS implementations.
- Updated connection and disconnection logic to handle auto-reconnect scenarios appropriately.
- Improved cleanup processes to prevent unwanted reconnections when devices are manually disconnected.

* Refactor connection button and add auto-reconnect toggle

- Updated the connection button layout for better UI consistency.
- Introduced an auto-reconnect toggle to manage automatic reconnections when devices become available.
- Enhanced connection and disconnection logic to respect the auto-connect setting.

* Update version to 1.2.0 and add CHANGELOG for new features

- Bumped version to 1.2.0.
- Added CHANGELOG.md detailing new features including support for `autoConnect` and UI updates for automatic reconnection.

* Improve readme

* Refactor variable naming for clarity in Bluetooth connection logic

- Changed variable name from `isAutoConnect` to `shouldAutoConnect` for better readability and understanding of its purpose in the connection state handling.

* Refactor connection handling in UniversalBlePlugin

- Simplified connection logic by always cleaning up internal state before sending connection change callbacks.
- Ensured GATT resources are only closed when autoConnect is disabled, allowing for better management of Bluetooth connections.

* Refactor disconnection handling in UniversalBlePlugin

- Introduced a new method `handlePeripheralDisconnection` to encapsulate disconnection logic, improving code readability and maintainability.
- Updated the `centralManager` methods to utilize the new disconnection handler, ensuring consistent behavior across connection state changes.

* Update darwin/Classes/UniversalBlePlugin.swift

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Foti Dim <fotios.dimanidis@a2zebra.de>
Co-authored-by: Navideck Labs <130186950+navidecklabs@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-16 11:36:24 +05:30

289 lines
5.9 KiB
Dart

import 'package:pigeon/pigeon.dart';
// dart run pigeon --input pigeon/universal_ble.dart
@ConfigurePigeon(
PigeonOptions(
dartPackageName: 'universal_ble',
dartOut: 'lib/src/universal_ble_pigeon/universal_ble.g.dart',
dartOptions: DartOptions(),
kotlinOut:
'android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt',
swiftOut: 'darwin/Classes/UniversalBle.g.swift',
kotlinOptions: KotlinOptions(package: 'com.navideck.universal_ble'),
swiftOptions: SwiftOptions(),
cppOptions: CppOptions(namespace: 'universal_ble'),
cppHeaderOut: 'windows/src/generated/universal_ble.g.h',
cppSourceOut: 'windows/src/generated/universal_ble.g.cpp',
debugGenerators: true,
),
)
/// Flutter -> Native
@HostApi()
abstract class UniversalBlePlatformChannel {
@async
int getBluetoothAvailabilityState();
bool hasPermissions(bool withAndroidFineLocation);
@async
void requestPermissions(bool withAndroidFineLocation);
@async
bool enableBluetooth();
@async
bool disableBluetooth();
void startScan(UniversalScanFilter? filter);
void stopScan();
bool isScanning();
void connect(String deviceId, {bool? autoConnect});
void disconnect(String deviceId);
@async
void setNotifiable(
String deviceId,
String service,
String characteristic,
int bleInputProperty,
);
@async
List<UniversalBleService> discoverServices(
String deviceId,
bool withDescriptors,
);
@async
Uint8List readValue(
String deviceId,
String service,
String characteristic,
);
@async
int requestMtu(String deviceId, int expectedMtu);
@async
void writeValue(
String deviceId,
String service,
String characteristic,
Uint8List value,
int bleOutputProperty,
);
@async
bool isPaired(String deviceId);
@async
bool pair(String deviceId);
void unPair(String deviceId);
@async
List<UniversalBleScanResult> getSystemDevices(
List<String> withServices,
);
int getConnectionState(String deviceId);
@async
int readRssi(String deviceId);
void setLogLevel(UniversalBleLogLevel logLevel);
}
/// Native -> Flutter
@FlutterApi()
abstract class UniversalBleCallbackChannel {
void onAvailabilityChanged(int state);
void onPairStateChange(String deviceId, bool isPaired, String? error);
void onScanResult(UniversalBleScanResult result);
void onValueChanged(
String deviceId,
String characteristicId,
Uint8List value,
int? timestamp,
);
void onConnectionChanged(
String deviceId,
bool connected,
String? error,
);
}
class UniversalBleScanResult {
final String deviceId;
final String? name;
final bool? isPaired;
final int? rssi;
final List<UniversalManufacturerData>? manufacturerDataList;
final List<String>? services;
final int? timestamp;
UniversalBleScanResult({
required this.name,
required this.deviceId,
required this.isPaired,
required this.rssi,
required this.manufacturerDataList,
required this.services,
required this.timestamp,
});
}
enum UniversalBleLogLevel {
none,
error,
warning,
info,
debug,
verbose,
}
class UniversalBleService {
String uuid;
List<UniversalBleCharacteristic>? characteristics;
UniversalBleService(this.uuid, this.characteristics);
}
class UniversalBleCharacteristic {
String uuid;
List<int> properties;
List<UniversalBleDescriptor> descriptors;
UniversalBleCharacteristic(this.uuid, this.properties, this.descriptors);
}
class UniversalBleDescriptor {
String uuid;
UniversalBleDescriptor(this.uuid);
}
/// Scan Filters
class UniversalScanFilter {
final List<String> withServices;
final List<String> withNamePrefix;
final List<UniversalManufacturerDataFilter> withManufacturerData;
UniversalScanFilter(
this.withServices,
this.withNamePrefix,
this.withManufacturerData,
);
}
class UniversalManufacturerDataFilter {
int companyIdentifier;
Uint8List? data;
Uint8List? mask;
UniversalManufacturerDataFilter({
required this.companyIdentifier,
this.data,
this.mask,
});
}
class UniversalManufacturerData {
final int companyIdentifier;
final Uint8List data;
UniversalManufacturerData({
required this.companyIdentifier,
required this.data,
});
}
/// Unified error codes for all platforms
enum UniversalBleErrorCode {
// General errors
unknownError,
failed,
notSupported,
notImplemented,
channelError,
// Bluetooth availability errors
bluetoothNotAvailable,
bluetoothNotEnabled,
bluetoothNotAllowed,
bluetoothUnauthorized,
// Connection errors
deviceDisconnected,
connectionTimeout,
connectionFailed,
connectionRejected,
connectionLimitExceeded,
connectionAlreadyExists,
connectionTerminated,
connectionInProgress,
// Device/Service/Characteristic errors
illegalArgument,
deviceNotFound,
serviceNotFound,
characteristicNotFound,
invalidServiceUuid,
invalidCharacteristicUuid,
invalidOffset,
invalidAttributeLength,
invalidPdu,
invalidHandle,
// Operation errors
readFailed,
readNotPermitted,
writeFailed,
writeNotPermitted,
writeRequestBusy,
invalidAction,
operationNotSupported,
operationTimeout,
operationCancelled,
operationInProgress,
// Characteristic property errors
characteristicDoesNotSupportRead,
characteristicDoesNotSupportWrite,
characteristicDoesNotSupportWriteWithoutResponse,
characteristicDoesNotSupportNotify,
characteristicDoesNotSupportIndicate,
// Pairing errors
notPaired,
notPairable,
alreadyPaired,
pairingFailed,
pairingCancelled,
pairingTimeout,
pairingNotAllowed,
authenticationFailure,
insufficientAuthentication,
insufficientAuthorization,
insufficientEncryption,
insufficientKeySize,
protectionLevelNotMet,
accessDenied,
// Unpairing errors
unpairingFailed,
alreadyUnpaired,
// Scan errors
scanFailed,
stoppingScanInProgress,
// Web-specific errors
webBluetoothGloballyDisabled,
}