feat: 重构项目 2.0.0 (#6)

* feat: 重构项目

* feat: 添加 bluez_central_manager

* feat: 联合插件

* feat: 拆分项目

* feat: 实现 linux 部分接口

* feat: 重新创建项目

* feat: 定义接口

* feat: 实现接入插件

* feat: 清空接入插件示例代码

* feat: 开发 linux 插件

* feat: 调整接口

* 临时提交

* feat: 实现 Android 接口

* fix: 修复 Android 问题

* fix: 移除多余文件

* feat: 重构项目 (#5)

* fix: 移除多余的状态判断

* fix: 外围设备断开时检查是否存在未完成的操作

* feat: 尝试使用 win32 实现接口

* fix: 修复大小写问题

* feat: 实现 macOS 接口

* feat: 实现 macOS 接口

* fix:支持使用16位短字符串生成UUID

* fix: 修复未清理已完成操作的问题

* fix: 规范命名

* 添加蓝牙使用描述

* fix: 更新 README.md
This commit is contained in:
Mr剑侠客
2023-08-17 17:49:26 +08:00
committed by GitHub
parent 3abe9d5b3d
commit d1726b52fa
371 changed files with 15666 additions and 15993 deletions

View File

@ -0,0 +1,12 @@
export 'src/errors.dart';
export 'src/event_args.dart';
export 'src/central_controller.dart';
export 'src/central_state.dart';
export 'src/peripheral.dart';
export 'src/uuid.dart';
export 'src/advertisement.dart';
export 'src/gatt_service.dart';
export 'src/gatt_characteristic.dart';
export 'src/gatt_characteristic_property.dart';
export 'src/gatt_characteristic_write_type.dart';
export 'src/gatt_descriptor.dart';

View File

@ -0,0 +1,17 @@
import 'dart:typed_data';
import 'uuid.dart';
class Advertisement {
final String? name;
final Map<int, Uint8List> manufacturerSpecificData;
final List<UUID> serviceUUIDs;
final Map<UUID, Uint8List> serviceData;
Advertisement({
this.name,
this.manufacturerSpecificData = const {},
this.serviceUUIDs = const [],
this.serviceData = const {},
});
}

View File

@ -0,0 +1,74 @@
import 'dart:typed_data';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'central_state.dart';
import 'event_args.dart';
import 'gatt_characteristic.dart';
import 'gatt_characteristic_write_type.dart';
import 'gatt_descriptor.dart';
import 'gatt_service.dart';
import 'peripheral.dart';
abstract class CentralController extends PlatformInterface {
/// Constructs a [CentralController].
CentralController() : super(token: _token);
static final Object _token = Object();
static CentralController? _instance;
/// The default instance of [CentralController] to use.
static CentralController get instance {
final instance = _instance;
if (instance == null) {
const message =
'`BluetoothLowEnergy` is not implemented on this platform.';
throw UnimplementedError(message);
}
return instance;
}
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [CentralController] when
/// they register themselves.
static set instance(CentralController instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
CentralState get state;
Stream<CentralStateChangedEventArgs> get stateChanged;
Stream<CentralDiscoveredEventArgs> get discovered;
Stream<PeripheralStateChangedEventArgs> get peripheralStateChanged;
Stream<GattCharacteristicValueChangedEventArgs>
get characteristicValueChanged;
Future<void> setUp();
Future<void> tearDown();
Future<void> startDiscovery();
Future<void> stopDiscovery();
Future<void> connect(Peripheral peripheral);
Future<void> disconnect(Peripheral peripheral);
Future<void> discoverGATT(Peripheral peripheral);
Future<List<GattService>> getServices(Peripheral peripheral);
Future<List<GattCharacteristic>> getCharacteristics(GattService service);
Future<List<GattDescriptor>> getDescriptors(
GattCharacteristic characteristic,
);
Future<Uint8List> readCharacteristic(GattCharacteristic characteristic);
Future<void> writeCharacteristic(
GattCharacteristic characteristic, {
required Uint8List value,
required GattCharacteristicWriteType type,
});
Future<void> notifyCharacteristic(
GattCharacteristic characteristic, {
required bool state,
});
Future<Uint8List> readDescriptor(GattDescriptor descriptor);
Future<void> writeDescriptor(
GattDescriptor descriptor, {
required Uint8List value,
});
}

View File

@ -0,0 +1,7 @@
enum CentralState {
unknown,
unsupported,
unauthorized,
poweredOff,
poweredOn,
}

View File

@ -0,0 +1,10 @@
class BluetoothLowEnergyError extends Error {
final String message;
BluetoothLowEnergyError(this.message);
@override
String toString() {
return 'BluetoothLowEnergyError: $message';
}
}

View File

@ -0,0 +1,36 @@
import 'dart:typed_data';
import 'advertisement.dart';
import 'central_state.dart';
import 'gatt_characteristic.dart';
import 'peripheral.dart';
abstract class EventArgs {}
class CentralStateChangedEventArgs extends EventArgs {
final CentralState state;
CentralStateChangedEventArgs(this.state);
}
class CentralDiscoveredEventArgs extends EventArgs {
final Peripheral peripheral;
final int rssi;
final Advertisement advertisement;
CentralDiscoveredEventArgs(this.peripheral, this.rssi, this.advertisement);
}
class PeripheralStateChangedEventArgs extends EventArgs {
final Peripheral peripheral;
final bool state;
PeripheralStateChangedEventArgs(this.peripheral, this.state);
}
class GattCharacteristicValueChangedEventArgs extends EventArgs {
final GattCharacteristic characteristic;
final Uint8List value;
GattCharacteristicValueChangedEventArgs(this.characteristic, this.value);
}

View File

@ -0,0 +1,12 @@
import 'gatt_characteristic_property.dart';
import 'uuid.dart';
class GattCharacteristic {
final UUID uuid;
final List<GattCharacteristicProperty> properties;
GattCharacteristic({
required this.uuid,
required this.properties,
});
}

View File

@ -0,0 +1,7 @@
enum GattCharacteristicProperty {
read,
write,
writeWithoutResponse,
notify,
indicate,
}

View File

@ -0,0 +1,8 @@
enum GattCharacteristicWriteType {
// Write with response
withResponse,
// Write without response
withoutResponse,
// Write with response and waiting for confirmation
// reliable,
}

View File

@ -0,0 +1,9 @@
import 'uuid.dart';
class GattDescriptor {
final UUID uuid;
GattDescriptor({
required this.uuid,
});
}

View File

@ -0,0 +1,9 @@
import 'uuid.dart';
class GattService {
final UUID uuid;
GattService({
required this.uuid,
});
}

View File

@ -0,0 +1,5 @@
import 'uuid.dart';
abstract class Peripheral {
UUID get uuid;
}

View File

@ -0,0 +1,141 @@
/// 128 bit universally unique identifier used in Bluetooth.
class UUID {
/// The value of the UUID in 16 bytes.
final List<int> value;
/// True if the UUID is a short (16 or 32 bit) encoded UUID.
bool get isShort =>
value[4] == 0x00 &&
value[5] == 0x00 &&
value[6] == 0x10 &&
value[7] == 0x00 &&
value[8] == 0x80 &&
value[9] == 0x00 &&
value[10] == 0x00 &&
value[11] == 0x80 &&
value[12] == 0x5f &&
value[13] == 0x9b &&
value[14] == 0x34 &&
value[15] == 0xfb;
/// Creates a new UUID from 16 bytes.
UUID(Iterable<int> value) : value = value.toList() {
if (value.length != 16) {
throw const FormatException('Invalid length UUID');
}
}
// Creates a new Bluetooth UUID from the short (16 or 32 bit) encoding.
UUID.short(int shortValue)
: value = [
(shortValue >> 24) & 0xff,
(shortValue >> 16) & 0xff,
(shortValue >> 8) & 0xff,
(shortValue >> 0) & 0xff,
0x00,
0x00,
0x10,
0x00,
0x80,
0x00,
0x00,
0x80,
0x5f,
0x9b,
0x34,
0xfb
];
/// Creates a new UUID from the string format encoding (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx where xx is a hexadecimal number).
factory UUID.fromString(String value) {
if (value.length == 4) {
try {
final shortValue = int.parse(value, radix: 16);
return UUID.short(shortValue);
} catch (e) {
throw const FormatException('Invalid UUID string');
}
}
var groups = value.split('-');
if (groups.length != 5 ||
groups[0].length != 8 ||
groups[1].length != 4 ||
groups[2].length != 4 ||
groups[3].length != 4 ||
groups[4].length != 12) {
throw const FormatException('Invalid UUID string');
}
int group0, group1, group2, group3, group4;
try {
group0 = int.parse(groups[0], radix: 16);
group1 = int.parse(groups[1], radix: 16);
group2 = int.parse(groups[2], radix: 16);
group3 = int.parse(groups[3], radix: 16);
group4 = int.parse(groups[4], radix: 16);
} catch (e) {
throw const FormatException('Invalid UUID string');
}
return UUID([
(group0 >> 24) & 0xff,
(group0 >> 16) & 0xff,
(group0 >> 8) & 0xff,
(group0 >> 0) & 0xff,
(group1 >> 8) & 0xff,
(group1 >> 0) & 0xff,
(group2 >> 8) & 0xff,
(group2 >> 0) & 0xff,
(group3 >> 8) & 0xff,
(group3 >> 0) & 0xff,
(group4 >> 40) & 0xff,
(group4 >> 32) & 0xff,
(group4 >> 24) & 0xff,
(group4 >> 16) & 0xff,
(group4 >> 8) & 0xff,
(group4 >> 0) & 0xff
]);
}
@override
String toString() {
var v0 = value[0].toRadixString(16).padLeft(2, '0');
var v1 = value[1].toRadixString(16).padLeft(2, '0');
var v2 = value[2].toRadixString(16).padLeft(2, '0');
var v3 = value[3].toRadixString(16).padLeft(2, '0');
var v4 = value[4].toRadixString(16).padLeft(2, '0');
var v5 = value[5].toRadixString(16).padLeft(2, '0');
var v6 = value[6].toRadixString(16).padLeft(2, '0');
var v7 = value[7].toRadixString(16).padLeft(2, '0');
var v8 = value[8].toRadixString(16).padLeft(2, '0');
var v9 = value[9].toRadixString(16).padLeft(2, '0');
var v10 = value[10].toRadixString(16).padLeft(2, '0');
var v11 = value[11].toRadixString(16).padLeft(2, '0');
var v12 = value[12].toRadixString(16).padLeft(2, '0');
var v13 = value[13].toRadixString(16).padLeft(2, '0');
var v14 = value[14].toRadixString(16).padLeft(2, '0');
var v15 = value[15].toRadixString(16).padLeft(2, '0');
return '$v0$v1$v2$v3-$v4$v5-$v6$v7-$v8$v9-$v10$v11$v12$v13$v14$v15';
}
@override
bool operator ==(other) =>
other is UUID &&
other.value[0] == value[0] &&
other.value[1] == value[1] &&
other.value[2] == value[2] &&
other.value[3] == value[3] &&
other.value[4] == value[4] &&
other.value[5] == value[5] &&
other.value[6] == value[6] &&
other.value[7] == value[7] &&
other.value[8] == value[8] &&
other.value[9] == value[9] &&
other.value[10] == value[10] &&
other.value[11] == value[11] &&
other.value[12] == value[12] &&
other.value[13] == value[13] &&
other.value[14] == value[14] &&
other.value[15] == value[15];
@override
int get hashCode => value.fold(17, (prev, value) => 37 * prev + value);
}