feat: 支持外围设备接口,优化中心设备接口 (#18)

* 临时提交

* 临时提交

* 临时提交

* fix: 调整接口

* fix: 修复问题

* fix: 调整 iOS 实现

* fix: 添加注释

* fix: 修改预览版本号

* fix: 修复已知问题

* fix: 优化接口

* fix: 解决 32 位 UUID 报错问题

* fix: 修复问题

* fix: 修复依赖项

* fix: 移除多余代码

* fix: 修复已知问题

* fix: 修复问题

* fix: 修改版本号

* fix: 修复问题

* fix: 发布正式版本
This commit is contained in:
Mr剑侠客
2023-10-10 05:01:25 -05:00
committed by GitHub
parent 073c2b9a2e
commit 79c50d638d
113 changed files with 9125 additions and 4560 deletions

View File

@ -1,9 +1,9 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'src/my_central_controller.dart';
import 'src/my_bluetooth_low_energy.dart';
abstract class BluetoothLowEnergyDarwin {
static void registerWith() {
CentralController.instance = MyCentralController();
BluetoothLowEnergy.instance = MyBluetoothLowEnergy();
}
}

View File

@ -0,0 +1,224 @@
import 'dart:typed_data';
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_gatt_characteristic2.dart';
import 'my_gatt_descriptor2.dart';
import 'my_gatt_service2.dart';
export 'my_api.g.dart';
extension MyBluetoothLowEnergyStateArgsX on MyBluetoothLowEnergyStateArgs {
BluetoothLowEnergyState toState() {
return BluetoothLowEnergyState.values[index];
}
}
extension MyAdvertiseDataArgsX on MyAdvertiseDataArgs {
AdvertiseData toAdvertiseData() {
final name = nameArgs;
final serviceUUIDs = serviceUUIDsArgs
.cast<String>()
.map((args) => UUID.fromString(args))
.toList();
final serviceData = serviceDataArgs.cast<String, Uint8List>().map(
(uuidArgs, dataArgs) {
final uuid = UUID.fromString(uuidArgs);
final data = dataArgs;
return MapEntry(uuid, data);
},
);
final manufacturerSpecificData =
manufacturerSpecificDataArgs?.toManufacturerSpecificData();
return AdvertiseData(
name: name,
serviceUUIDs: serviceUUIDs,
serviceData: serviceData,
manufacturerSpecificData: manufacturerSpecificData,
);
}
}
extension MyManufacturerSpecificDataArgsX on MyManufacturerSpecificDataArgs {
ManufacturerSpecificData toManufacturerSpecificData() {
final id = idArgs;
final data = dataArgs;
return ManufacturerSpecificData(
id: id,
data: data,
);
}
}
extension MyGattCharacteristicPropertyArgsX
on MyGattCharacteristicPropertyArgs {
GattCharacteristicProperty toProperty() {
return GattCharacteristicProperty.values[index];
}
}
extension GattCharacteristicWriteTypeX on GattCharacteristicWriteType {
MyGattCharacteristicWriteTypeArgs toArgs() {
return MyGattCharacteristicWriteTypeArgs.values[index];
}
}
extension MyPeripheralArgsX on MyPeripheralArgs {
Peripheral toPeripheral() {
final hashCode = hashCodeArgs;
final uuid = UUID.fromString(uuidArgs);
return MyPeripheral(
hashCode: hashCode,
uuid: uuid,
);
}
}
extension MyGattServiceArgsX on MyGattServiceArgs {
MyGattService2 toService2() {
final hashCode = hashCodeArgs;
final uuid = UUID.fromString(uuidArgs);
final characteristics = characteristicsArgs
.cast<MyGattCharacteristicArgs>()
.map((args) => args.toCharacteristic2())
.toList();
return MyGattService2(
hashCode: hashCode,
uuid: uuid,
characteristics: characteristics,
);
}
}
extension MyGattCharacteristicArgsX on MyGattCharacteristicArgs {
MyGattCharacteristic2 toCharacteristic2() {
final hashCode = hashCodeArgs;
final uuid = UUID.fromString(uuidArgs);
final properties = propertyNumbersArgs.cast<int>().map(
(args) {
final propertyArgs = MyGattCharacteristicPropertyArgs.values[args];
return propertyArgs.toProperty();
},
).toList();
final descriptors = descriptorsArgs
.cast<MyGattDescriptorArgs>()
.map((args) => args.toDescriptor2())
.toList();
return MyGattCharacteristic2(
hashCode: hashCode,
uuid: uuid,
properties: properties,
descriptors: descriptors,
);
}
}
extension MyGattDescriptorArgsX on MyGattDescriptorArgs {
MyGattDescriptor2 toDescriptor2() {
final hashCode = hashCodeArgs;
final uuid = UUID.fromString(uuidArgs);
return MyGattDescriptor2(
hashCode: hashCode,
uuid: uuid,
);
}
}
extension MyCentralArgsX on MyCentralArgs {
MyCentral toCentral() {
final hashCode = hashCodeArgs;
final uuid = UUID.fromString(uuidArgs);
return MyCentral(
hashCode: hashCode,
uuid: uuid,
);
}
}
extension AdvertiseDataX on AdvertiseData {
MyAdvertiseDataArgs toArgs() {
final nameArgs = name;
final serviceUUIDsArgs =
serviceUUIDs.map((uuid) => uuid.toString()).toList();
final serviceDataArgs = serviceData.map((uuid, data) {
final uuidArgs = uuid.toString();
final dataArgs = data;
return MapEntry(uuidArgs, dataArgs);
});
final manufacturerSpecificDataArgs = manufacturerSpecificData?.toArgs();
return MyAdvertiseDataArgs(
nameArgs: nameArgs,
serviceUUIDsArgs: serviceUUIDsArgs,
serviceDataArgs: serviceDataArgs,
manufacturerSpecificDataArgs: manufacturerSpecificDataArgs,
);
}
}
extension ManufacturerSpecificDataX on ManufacturerSpecificData {
MyManufacturerSpecificDataArgs toArgs() {
final idArgs = id;
final dataArgs = data;
return MyManufacturerSpecificDataArgs(
idArgs: idArgs,
dataArgs: dataArgs,
);
}
}
extension MyGattServiceX on MyGattService {
MyGattServiceArgs toArgs() {
final hashCodeArgs = hashCode;
final uuidArgs = uuid.toString();
final characteristicsArgs = characteristics
.cast<MyGattCharacteristic>()
.map((characteristic) => characteristic.toArgs())
.toList();
return MyGattServiceArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs,
characteristicsArgs: characteristicsArgs,
);
}
}
extension MyGattCharacteristicX on MyGattCharacteristic {
MyGattCharacteristicArgs toArgs() {
final hashCodeArgs = hashCode;
final uuidArgs = uuid.toString();
final propertyNumbersArgs = properties.map((property) {
final propertyArgs = property.toArgs();
return propertyArgs.index;
}).toList();
final descriptorsArgs = descriptors
.cast<MyGattDescriptor>()
.map((descriptor) => descriptor.toArgs())
.toList();
return MyGattCharacteristicArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs,
propertyNumbersArgs: propertyNumbersArgs,
descriptorsArgs: descriptorsArgs,
);
}
}
extension MyGattDescriptorX on MyGattDescriptor {
MyGattDescriptorArgs toArgs() {
final hashCodeArgs = hashCode;
final uuidArgs = uuid.toString();
final valueArgs = value;
return MyGattDescriptorArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs,
valueArgs: valueArgs,
);
}
}
extension GattCharacteristicPropertyX on GattCharacteristicProperty {
MyGattCharacteristicPropertyArgs toArgs() {
return MyGattCharacteristicPropertyArgs.values[index];
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_central_manager.dart';
import 'my_peripheral_manager.dart';
class MyBluetoothLowEnergy extends BluetoothLowEnergy {
@override
final MyCentralManager centralManager;
@override
final MyPeripheralManager peripheralManager;
MyBluetoothLowEnergy()
: centralManager = MyCentralManager(),
peripheralManager = MyPeripheralManager();
}

View File

@ -0,0 +1,39 @@
import 'dart:async';
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'package:flutter/foundation.dart';
abstract class MyBluetoothLowEnergyManager extends BluetoothLowEnergyManager {
MyBluetoothLowEnergyManager()
: _state = BluetoothLowEnergyState.unknown,
_stateChangedController = StreamController.broadcast();
final StreamController<BluetoothLowEnergyStateChangedEventArgs>
_stateChangedController;
BluetoothLowEnergyState _state;
@override
BluetoothLowEnergyState get state => _state;
@protected
set state(BluetoothLowEnergyState value) {
if (_state == value) {
return;
}
_state = value;
final eventArgs = BluetoothLowEnergyStateChangedEventArgs(state);
_stateChangedController.add(eventArgs);
}
@override
Stream<BluetoothLowEnergyStateChangedEventArgs> get stateChanged =>
_stateChangedController.stream;
@protected
Future<void> throwWithoutState(BluetoothLowEnergyState state) async {
if (this.state != state) {
throw BluetoothLowEnergyError(
'$state is expected, but current state is ${this.state}.',
);
}
}
}

View File

@ -1,370 +0,0 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_gatt_characteristic.dart';
import 'my_gatt_descriptor.dart';
import 'my_gatt_service.dart';
import 'my_peripheral.dart';
class MyCentralController extends CentralController
implements MyCentralControllerFlutterApi {
MyCentralController()
: _myApi = MyCentralControllerHostApi(),
_stateChangedController = StreamController.broadcast(),
_discoveredController = StreamController.broadcast(),
_peripheralStateChangedController = StreamController.broadcast(),
_characteristicValueChangedController = StreamController.broadcast(),
_myPeripherals = {},
_myServices = {},
_myCharacteristics = {},
_myDescriptors = {},
_state = CentralState.unknown;
final MyCentralControllerHostApi _myApi;
final StreamController<CentralStateChangedEventArgs> _stateChangedController;
final StreamController<CentralDiscoveredEventArgs> _discoveredController;
final StreamController<PeripheralStateChangedEventArgs>
_peripheralStateChangedController;
final StreamController<GattCharacteristicValueChangedEventArgs>
_characteristicValueChangedController;
final Map<int, MyPeripheral> _myPeripherals;
final Map<int, MyGattService> _myServices;
final Map<int, MyGattCharacteristic> _myCharacteristics;
final Map<int, MyGattDescriptor> _myDescriptors;
CentralState _state;
@override
CentralState get state => _state;
@override
Stream<CentralStateChangedEventArgs> get stateChanged =>
_stateChangedController.stream;
@override
Stream<CentralDiscoveredEventArgs> get discovered =>
_discoveredController.stream;
@override
Stream<PeripheralStateChangedEventArgs> get peripheralStateChanged =>
_peripheralStateChangedController.stream;
@override
Stream<GattCharacteristicValueChangedEventArgs>
get characteristicValueChanged =>
_characteristicValueChangedController.stream;
Future<void> _throwWithState(CentralState state) async {
if (this.state == state) {
throw BluetoothLowEnergyError('$state is unexpected.');
}
}
Future<void> _throwWithoutState(CentralState state) async {
if (this.state != state) {
throw BluetoothLowEnergyError(
'$state is expected, but current state is ${this.state}.',
);
}
}
@override
Future<void> setUp() async {
await _throwWithoutState(CentralState.unknown);
final args = await _myApi.setUp();
final myStateArgs = MyCentralStateArgs.values[args.myStateNumber];
_state = myStateArgs.toState();
MyCentralControllerFlutterApi.setup(this);
}
@override
Future<void> tearDown() async {
await _throwWithState(CentralState.unknown);
await _myApi.tearDown();
MyCentralControllerFlutterApi.setup(null);
_myPeripherals.clear();
_myServices.clear();
_myCharacteristics.clear();
_myDescriptors.clear();
_state = CentralState.unknown;
}
@override
Future<void> startDiscovery() async {
await _throwWithoutState(CentralState.poweredOn);
await _myApi.startDiscovery();
}
@override
Future<void> stopDiscovery() async {
await _throwWithoutState(CentralState.poweredOn);
await _myApi.stopDiscovery();
}
@override
Future<void> connect(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
await _myApi.connect(myPeripheral.hashCode);
}
@override
Future<void> disconnect(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
await _myApi.disconnect(myPeripheral.hashCode);
}
@override
Future<int> getMaximumWriteLength(
Peripheral peripheral, {
required GattCharacteristicWriteType type,
}) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
final myTypeArgs = type.toMyArgs();
final myTypeNumber = myTypeArgs.index;
final maximumWriteLength = await _myApi.getMaximumWriteLength(
myPeripheral.hashCode,
myTypeNumber,
);
return maximumWriteLength;
}
@override
Future<void> discoverGATT(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
await _myApi.discoverGATT(myPeripheral.hashCode);
}
@override
Future<List<GattService>> getServices(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
final myServiceArgses = await _myApi.getServices(myPeripheral.hashCode);
return myServiceArgses.cast<MyGattServiceArgs>().map(
(myServiceArgs) {
final myService = MyGattService.fromMyArgs(
myPeripheral,
myServiceArgs,
);
_myServices[myService.hashCode] = myService;
return myService;
},
).toList();
}
@override
Future<List<GattCharacteristic>> getCharacteristics(
GattService service,
) async {
await _throwWithoutState(CentralState.poweredOn);
final myService = service as MyGattService;
final myCharactersiticArgses = await _myApi.getCharacteristics(
myService.hashCode,
);
return myCharactersiticArgses.cast<MyGattCharacteristicArgs>().map(
(myCharacteristicArgs) {
final myCharacteristic = MyGattCharacteristic.fromMyArgs(
myService,
myCharacteristicArgs,
);
_myCharacteristics[myCharacteristic.hashCode] = myCharacteristic;
return myCharacteristic;
},
).toList();
}
@override
Future<List<GattDescriptor>> getDescriptors(
GattCharacteristic characteristic,
) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myDescriptorArgses = await _myApi.getDescriptors(
myCharacteristic.hashCode,
);
return myDescriptorArgses.cast<MyGattDescriptorArgs>().map(
(myDescriptorArgs) {
final myDescriptor = MyGattDescriptor.fromMyArgs(
myCharacteristic,
myDescriptorArgs,
);
_myDescriptors[myDescriptor.hashCode] = myDescriptor;
return myDescriptor;
},
).toList();
}
@override
Future<Uint8List> readCharacteristic(
GattCharacteristic characteristic,
) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
final value = await _myApi.readCharacteristic(
myPeripheral.hashCode,
myService.hashCode,
myCharacteristic.hashCode,
);
return value;
}
@override
Future<void> writeCharacteristic(
GattCharacteristic characteristic, {
required Uint8List value,
required GattCharacteristicWriteType type,
}) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
final myTypeArgs = type.toMyArgs();
final myTypeNumber = myTypeArgs.index;
await _myApi.writeCharacteristic(
myPeripheral.hashCode,
myService.hashCode,
myCharacteristic.hashCode,
value,
myTypeNumber,
);
}
@override
Future<void> notifyCharacteristic(
GattCharacteristic characteristic, {
required bool state,
}) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
await _myApi.notifyCharacteristic(
myPeripheral.hashCode,
myService.hashCode,
myCharacteristic.hashCode,
state,
);
}
@override
Future<Uint8List> readDescriptor(GattDescriptor descriptor) async {
await _throwWithoutState(CentralState.poweredOn);
final myDescriptor = descriptor as MyGattDescriptor;
final myCharacteristic = myDescriptor.myCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
final value = await _myApi.readDescriptor(
myPeripheral.hashCode,
myCharacteristic.hashCode,
myDescriptor.hashCode,
);
return value;
}
@override
Future<void> writeDescriptor(
GattDescriptor descriptor, {
required Uint8List value,
}) async {
await _throwWithoutState(CentralState.poweredOn);
final myDescriptor = descriptor as MyGattDescriptor;
final myCharacteristic = myDescriptor.myCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
await _myApi.writeDescriptor(
myPeripheral.hashCode,
myCharacteristic.hashCode,
myDescriptor.hashCode,
value,
);
}
@override
void onStateChanged(int myStateNumber) {
final myStateArgs = MyCentralStateArgs.values[myStateNumber];
final state = myStateArgs.toState();
if (_state == state) {
return;
}
_state = state;
final eventArgs = CentralStateChangedEventArgs(state);
_stateChangedController.add(eventArgs);
}
@override
void onDiscovered(
MyPeripheralArgs myPeripheralArgs,
int rssi,
MyAdvertisementArgs myAdvertisementArgs,
) {
final myPeripheral = MyPeripheral.fromMyArgs(myPeripheralArgs);
_myPeripherals[myPeripheral.hashCode] = myPeripheral;
final advertisement = myAdvertisementArgs.toAdvertisement();
final eventArgs = CentralDiscoveredEventArgs(
myPeripheral,
rssi,
advertisement,
);
_discoveredController.add(eventArgs);
}
@override
void onPeripheralStateChanged(int myPeripheralKey, bool state) {
final myPeripheral = _myPeripherals[myPeripheralKey];
if (myPeripheral == null) {
return;
}
final eventArgs = PeripheralStateChangedEventArgs(myPeripheral, state);
_peripheralStateChangedController.add(eventArgs);
}
@override
void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value) {
final myCharacteristic =
_myCharacteristics[myCharacteristicKey] as MyGattCharacteristic;
final eventArgs = GattCharacteristicValueChangedEventArgs(
myCharacteristic,
value,
);
_characteristicValueChangedController.add(eventArgs);
}
}
extension on MyAdvertisementArgs {
Advertisement toAdvertisement() {
final serviceUUIDs = this
.serviceUUIDs
.cast<String>()
.map((uuid) => UUID.fromString(uuid))
.toList();
final serviceData = this.serviceData.cast<String, Uint8List>().map(
(uuid, data) {
final key = UUID.fromString(uuid);
final value = data;
return MapEntry(key, value);
},
);
return Advertisement(
name: name,
manufacturerSpecificData: manufacturerSpecificData.cast<int, Uint8List>(),
serviceUUIDs: serviceUUIDs,
serviceData: serviceData,
);
}
}
extension on MyCentralStateArgs {
CentralState toState() {
return CentralState.values[index];
}
}
extension on GattCharacteristicWriteType {
MyGattCharacteristicWriteTypeArgs toMyArgs() {
return MyGattCharacteristicWriteTypeArgs.values[index];
}
}

View File

@ -0,0 +1,272 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.dart';
import 'my_bluetooth_low_energy_manager.dart';
import 'my_gatt_characteristic2.dart';
import 'my_gatt_descriptor2.dart';
class MyCentralManager extends MyBluetoothLowEnergyManager
implements CentralManager, MyCentralManagerFlutterApi {
MyCentralManager()
: _api = MyCentralManagerHostApi(),
_discoveredController = StreamController.broadcast(),
_peripheralStateChangedController = StreamController.broadcast(),
_characteristicValueChangedController = StreamController.broadcast();
final MyCentralManagerHostApi _api;
final StreamController<DiscoveredEventArgs> _discoveredController;
final StreamController<PeripheralStateChangedEventArgs>
_peripheralStateChangedController;
final StreamController<GattCharacteristicValueChangedEventArgs>
_characteristicValueChangedController;
@override
Stream<DiscoveredEventArgs> get discovered => _discoveredController.stream;
@override
Stream<PeripheralStateChangedEventArgs> get peripheralStateChanged =>
_peripheralStateChangedController.stream;
@override
Stream<GattCharacteristicValueChangedEventArgs>
get characteristicValueChanged =>
_characteristicValueChangedController.stream;
@override
Future<void> setUp() async {
await throwWithoutState(BluetoothLowEnergyState.unknown);
final args = await _api.setUp();
final stateArgs =
MyBluetoothLowEnergyStateArgs.values[args.stateNumberArgs];
state = stateArgs.toState();
MyCentralManagerFlutterApi.setup(this);
}
@override
Future<void> startDiscovery() async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
await _api.startDiscovery();
}
@override
Future<void> stopDiscovery() async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
await _api.stopDiscovery();
}
@override
Future<void> connect(Peripheral peripheral) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final peripheralHashCodeArgs = peripheral.hashCode;
await _api.connect(peripheralHashCodeArgs);
}
@override
Future<void> disconnect(Peripheral peripheral) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final peripheralHashCodeArgs = peripheral.hashCode;
await _api.disconnect(peripheralHashCodeArgs);
}
@override
Future<int> getMaximumWriteLength(
Peripheral peripheral, {
required GattCharacteristicWriteType type,
}) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final peripheralHashCodeArgs = peripheral.hashCode;
final typeArgs = type.toArgs();
final typeNumberArgs = typeArgs.index;
final maximumWriteLength = await _api.getMaximumWriteLength(
peripheralHashCodeArgs,
typeNumberArgs,
);
return maximumWriteLength;
}
@override
Future<int> readRSSI(Peripheral peripheral) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final peripheralHashCodeArgs = peripheral.hashCode;
final rssi = await _api.readRSSI(peripheralHashCodeArgs);
return rssi;
}
@override
Future<List<GattService>> discoverGATT(Peripheral peripheral) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
if (peripheral is! MyPeripheral) {
throw TypeError();
}
final peripheralHashCodeArgs = peripheral.hashCode;
final servicesArgs = await _api.discoverGATT(peripheralHashCodeArgs);
final services = servicesArgs
.cast<MyGattServiceArgs>()
.map((args) => args.toService2())
.toList();
for (var service in services) {
for (var charactersitic in service.characteristics) {
for (var descriptor in charactersitic.descriptors) {
descriptor.characteristic = charactersitic;
}
charactersitic.service = service;
}
service.peripheral = peripheral;
}
return services;
}
@override
Future<Uint8List> readCharacteristic(
GattCharacteristic characteristic,
) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
if (characteristic is! MyGattCharacteristic2) {
throw TypeError();
}
final service = characteristic.service;
final peripheral = service.peripheral;
final peripheralHashCodeArgs = peripheral.hashCode;
final characteristicHashCodeArgs = characteristic.hashCode;
final value = await _api.readCharacteristic(
peripheralHashCodeArgs,
characteristicHashCodeArgs,
);
return value;
}
@override
Future<void> writeCharacteristic(
GattCharacteristic characteristic, {
required Uint8List value,
required GattCharacteristicWriteType type,
}) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
if (characteristic is! MyGattCharacteristic2) {
throw TypeError();
}
final service = characteristic.service;
final peripheral = service.peripheral;
final peripheralHashCodeArgs = peripheral.hashCode;
final characteristicHashCodeArgs = characteristic.hashCode;
final valueArgs = value;
final typeArgs = type.toArgs();
final typeNumberArgs = typeArgs.index;
await _api.writeCharacteristic(
peripheralHashCodeArgs,
characteristicHashCodeArgs,
valueArgs,
typeNumberArgs,
);
}
@override
Future<void> notifyCharacteristic(
GattCharacteristic characteristic, {
required bool state,
}) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
if (characteristic is! MyGattCharacteristic2) {
throw TypeError();
}
final service = characteristic.service;
final peripheral = service.peripheral;
final peripheralHashCodeArgs = peripheral.hashCode;
final characteristicHashCodeArgs = characteristic.hashCode;
final stateArgs = state;
await _api.notifyCharacteristic(
peripheralHashCodeArgs,
characteristicHashCodeArgs,
stateArgs,
);
}
@override
Future<Uint8List> readDescriptor(GattDescriptor descriptor) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
if (descriptor is! MyGattDescriptor2) {
throw TypeError();
}
final characteristic = descriptor.characteristic;
final service = characteristic.service;
final peripheral = service.peripheral;
final peripheralHashCodeArgs = peripheral.hashCode;
final descriptorHashCodeArgs = descriptor.hashCode;
final value = await _api.readDescriptor(
peripheralHashCodeArgs,
descriptorHashCodeArgs,
);
return value;
}
@override
Future<void> writeDescriptor(
GattDescriptor descriptor, {
required Uint8List value,
}) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
if (descriptor is! MyGattDescriptor2) {
throw TypeError();
}
final characteristic = descriptor.characteristic;
final service = characteristic.service;
final peripheral = service.peripheral;
final peripheralHashCodeArgs = peripheral.hashCode;
final descriptorHashCodeArgs = descriptor.hashCode;
final valueArgs = value;
await _api.writeDescriptor(
peripheralHashCodeArgs,
descriptorHashCodeArgs,
valueArgs,
);
}
@override
void onStateChanged(int stateNumberArgs) {
final stateArgs = MyBluetoothLowEnergyStateArgs.values[stateNumberArgs];
state = stateArgs.toState();
}
@override
void onDiscovered(
MyPeripheralArgs peripheralArgs,
int rssiArgs,
MyAdvertiseDataArgs advertiseDataArgs,
) {
final peripheral = peripheralArgs.toPeripheral();
final rssi = rssiArgs;
final advertiseData = advertiseDataArgs.toAdvertiseData();
final eventArgs = DiscoveredEventArgs(
peripheral,
rssi,
advertiseData,
);
_discoveredController.add(eventArgs);
}
@override
void onPeripheralStateChanged(
MyPeripheralArgs peripheralArgs,
bool stateArgs,
) {
final peripheral = peripheralArgs.toPeripheral();
final state = stateArgs;
final eventArgs = PeripheralStateChangedEventArgs(peripheral, state);
_peripheralStateChangedController.add(eventArgs);
}
@override
void onCharacteristicValueChanged(
MyGattCharacteristicArgs characteristicArgs,
Uint8List valueArgs,
) {
final characteristic = characteristicArgs.toCharacteristic2();
final value = valueArgs;
final eventArgs = GattCharacteristicValueChangedEventArgs(
characteristic,
value,
);
_characteristicValueChangedController.add(eventArgs);
}
}

View File

@ -1,42 +0,0 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_gatt_service.dart';
import 'my_object.dart';
class MyGattCharacteristic extends MyObject implements GattCharacteristic {
final MyGattService myService;
@override
final UUID uuid;
@override
final List<GattCharacteristicProperty> properties;
MyGattCharacteristic(
super.hashCode,
this.myService,
this.uuid,
this.properties,
);
factory MyGattCharacteristic.fromMyArgs(
MyGattService myService,
MyGattCharacteristicArgs myArgs,
) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
final properties = myArgs.myPropertyNumbers.cast<int>().map(
(myPropertyNumber) {
final myPropertyArgs =
MyGattCharacteristicPropertyArgs.values[myPropertyNumber];
return myPropertyArgs.toProperty();
},
).toList();
return MyGattCharacteristic(hashCode, myService, uuid, properties);
}
}
extension on MyGattCharacteristicPropertyArgs {
GattCharacteristicProperty toProperty() {
return GattCharacteristicProperty.values[index];
}
}

View File

@ -0,0 +1,19 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_gatt_descriptor2.dart';
import 'my_gatt_service2.dart';
class MyGattCharacteristic2 extends MyGattCharacteristic {
late final MyGattService2 service;
MyGattCharacteristic2({
super.hashCode,
required super.uuid,
required super.properties,
required List<MyGattDescriptor2> descriptors,
}) : super(descriptors: descriptors);
@override
List<MyGattDescriptor2> get descriptors =>
super.descriptors.cast<MyGattDescriptor2>();
}

View File

@ -1,22 +0,0 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_gatt_characteristic.dart';
import 'my_object.dart';
class MyGattDescriptor extends MyObject implements GattDescriptor {
final MyGattCharacteristic myCharacteristic;
@override
final UUID uuid;
MyGattDescriptor(super.hashCode, this.myCharacteristic, this.uuid);
factory MyGattDescriptor.fromMyArgs(
MyGattCharacteristic myCharacteristic,
MyGattDescriptorArgs myArgs,
) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
return MyGattDescriptor(hashCode, myCharacteristic, uuid);
}
}

View File

@ -0,0 +1,12 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_gatt_characteristic2.dart';
class MyGattDescriptor2 extends MyGattDescriptor {
late final MyGattCharacteristic2 characteristic;
MyGattDescriptor2({
super.hashCode,
required super.uuid,
});
}

View File

@ -1,22 +0,0 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_object.dart';
import 'my_peripheral.dart';
class MyGattService extends MyObject implements GattService {
final MyPeripheral myPeripheral;
@override
final UUID uuid;
MyGattService(super.hashCode, this.myPeripheral, this.uuid);
factory MyGattService.fromMyArgs(
MyPeripheral myPeripheral,
MyGattServiceArgs myArgs,
) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
return MyGattService(hashCode, myPeripheral, uuid);
}
}

View File

@ -0,0 +1,17 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_gatt_characteristic2.dart';
class MyGattService2 extends MyGattService {
late final MyPeripheral peripheral;
MyGattService2({
super.hashCode,
required super.uuid,
required List<MyGattCharacteristic2> characteristics,
}) : super(characteristics: characteristics);
@override
List<MyGattCharacteristic2> get characteristics =>
super.characteristics.cast<MyGattCharacteristic2>();
}

View File

@ -1,11 +0,0 @@
abstract class MyObject {
@override
final int hashCode;
MyObject(this.hashCode);
@override
bool operator ==(Object other) {
return other is MyObject && other.hashCode == hashCode;
}
}

View File

@ -1,17 +0,0 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_object.dart';
class MyPeripheral extends MyObject implements Peripheral {
@override
final UUID uuid;
MyPeripheral(super.hashCode, this.uuid);
factory MyPeripheral.fromMyArgs(MyPeripheralArgs myArgs) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
return MyPeripheral(hashCode, uuid);
}
}

View File

@ -0,0 +1,228 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.dart';
import 'my_bluetooth_low_energy_manager.dart';
class MyPeripheralManager extends MyBluetoothLowEnergyManager
implements PeripheralManager, MyPeripheralManagerFlutterApi {
final MyPeripheralManagerHostApi _api;
final StreamController<ReadGattCharacteristicCommandEventArgs>
_readCharacteristicCommandReceivedController;
final StreamController<WriteGattCharacteristicCommandEventArgs>
_writeCharacteristicCommandReceivedController;
final StreamController<NotifyGattCharacteristicCommandEventArgs>
_notifyCharacteristicCommandReceivedController;
MyPeripheralManager()
: _api = MyPeripheralManagerHostApi(),
_readCharacteristicCommandReceivedController =
StreamController.broadcast(),
_writeCharacteristicCommandReceivedController =
StreamController.broadcast(),
_notifyCharacteristicCommandReceivedController =
StreamController.broadcast();
@override
Stream<ReadGattCharacteristicCommandEventArgs>
get readCharacteristicCommandReceived =>
_readCharacteristicCommandReceivedController.stream;
@override
Stream<WriteGattCharacteristicCommandEventArgs>
get writeCharacteristicCommandReceived =>
_writeCharacteristicCommandReceivedController.stream;
@override
Stream<NotifyGattCharacteristicCommandEventArgs>
get notifyCharacteristicCommandReceived =>
_notifyCharacteristicCommandReceivedController.stream;
@override
Future<void> setUp() async {
final args = await _api.setUp();
final stateArgs =
MyBluetoothLowEnergyStateArgs.values[args.stateNumberArgs];
state = stateArgs.toState();
MyPeripheralManagerFlutterApi.setup(this);
}
@override
Future<void> addService(GattService service) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
if (service is! MyGattService) {
throw TypeError();
}
final serviceArgs = service.toArgs();
await _api.addService(serviceArgs);
}
@override
Future<void> removeService(GattService service) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final serviceHashCodeArgs = service.hashCode;
await _api.removeService(serviceHashCodeArgs);
}
@override
Future<void> clearServices() async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
await _api.clearServices();
}
@override
Future<void> startAdvertising(AdvertiseData advertiseData) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final advertiseDataArgs = advertiseData.toArgs();
await _api.startAdvertising(advertiseDataArgs);
}
@override
Future<void> stopAdvertising() async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
await _api.stopAdvertising();
}
@override
Future<int> getMaximumWriteLength(Central central) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final centralHashCodeArgs = central.hashCode;
final maximumWriteLength =
await _api.getMaximumWriteLength(centralHashCodeArgs);
return maximumWriteLength;
}
@override
Future<void> sendReadCharacteristicReply(
Central central,
GattCharacteristic characteristic,
int id,
int offset,
bool status,
Uint8List value,
) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final centralHashCodeArgs = central.hashCode;
final characteristicHashCodeArgs = characteristic.hashCode;
final idArgs = id;
final offsetArgs = offset;
final statusArgs = status;
final valueArgs = value;
await _api.sendReadCharacteristicReply(
centralHashCodeArgs,
characteristicHashCodeArgs,
idArgs,
offsetArgs,
statusArgs,
valueArgs,
);
}
@override
Future<void> sendWriteCharacteristicReply(
Central central,
GattCharacteristic characteristic,
int id,
int offset,
bool status,
) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final centralHashCodeArgs = central.hashCode;
final characteristicHashCodeArgs = characteristic.hashCode;
final idArgs = id;
final offsetArgs = offset;
final statusArgs = status;
await _api.sendWriteCharacteristicReply(
centralHashCodeArgs,
characteristicHashCodeArgs,
idArgs,
offsetArgs,
statusArgs,
);
}
@override
Future<void> notifyCharacteristicValueChanged(
Central central,
GattCharacteristic characteristic,
Uint8List value,
) async {
await throwWithoutState(BluetoothLowEnergyState.poweredOn);
final centralHashCodeArgs = central.hashCode;
final characteristicHashCodeArgs = characteristic.hashCode;
final valueArgs = value;
await _api.notifyCharacteristicValueChanged(
centralHashCodeArgs,
characteristicHashCodeArgs,
valueArgs,
);
}
@override
void onStateChanged(int stateNumberArgs) {
final stateArgs = MyBluetoothLowEnergyStateArgs.values[stateNumberArgs];
state = stateArgs.toState();
}
@override
void onReadCharacteristicCommandReceived(
MyCentralArgs centralArgs,
MyGattCharacteristicArgs characteristicArgs,
int idArgs,
int offsetArgs,
) {
final central = centralArgs.toCentral();
final characteristic = characteristicArgs.toCharacteristic2();
final id = idArgs;
final offset = offsetArgs;
final eventArgs = ReadGattCharacteristicCommandEventArgs(
central,
characteristic,
id,
offset,
);
_readCharacteristicCommandReceivedController.add(eventArgs);
}
@override
void onWriteCharacteristicCommandReceived(
MyCentralArgs centralArgs,
MyGattCharacteristicArgs characteristicArgs,
int idArgs,
int offsetArgs,
Uint8List valueArgs,
) {
final central = centralArgs.toCentral();
final characteristic = characteristicArgs.toCharacteristic2();
final id = idArgs;
final offset = offsetArgs;
final value = valueArgs;
final eventArgs = WriteGattCharacteristicCommandEventArgs(
central,
characteristic,
id,
offset,
value,
);
_writeCharacteristicCommandReceivedController.add(eventArgs);
}
@override
void onNotifyCharacteristicCommandReceived(
MyCentralArgs centralArgs,
MyGattCharacteristicArgs characteristicArgs,
bool stateArgs,
) {
final central = centralArgs.toCentral();
final characteristic = characteristicArgs.toCharacteristic2();
final state = stateArgs;
final eventArgs = NotifyGattCharacteristicCommandEventArgs(
central,
characteristic,
state,
);
_notifyCharacteristicCommandReceivedController.add(eventArgs);
}
}