bluetooth connectivity layer added

This commit is contained in:
Constantin Leue
2026-07-30 19:46:52 +02:00
parent 310d92f187
commit 5994aee7ad
19 changed files with 1665 additions and 15 deletions
@@ -0,0 +1,76 @@
import 'dart:async';
import 'dart:typed_data';
import '../link_transport.dart';
/// Transport ohne echte Gegenstelle (Doku Kommunikationsschicht Abschnitt 2/9):
/// erlaubt UI- und MSP-Entwicklung ohne Bluetooth-Hardware oder SITL. Bytes,
/// die die Gegenstelle "gesendet" haette, werden ueber [feed] eingespeist;
/// [sentData] sammelt, was die App darueber gesendet hat, damit Tests das
/// pruefen koennen.
class LoopbackTransport implements LinkTransport {
final _incomingController = StreamController<Uint8List>.broadcast();
final _stateController = StreamController<LinkState>.broadcast();
LinkState _state = LinkState.disconnected;
LinkErrorReason? _lastErrorReason;
String? _lastErrorMessage;
/// Alle bisher per [send] geschickten Bytes, in Reihenfolge.
final List<Uint8List> sentData = [];
@override
Stream<Uint8List> get incoming => _incomingController.stream;
@override
Stream<LinkState> get state => _stateController.stream;
@override
LinkErrorReason? get lastErrorReason => _lastErrorReason;
@override
String? get lastErrorMessage => _lastErrorMessage;
/// Simuliert eingehende Bytes von der Gegenstelle (z.B. aufgezeichnete
/// MSP-Antworten, Doku Abschnitt 9).
void feed(Uint8List data) => _incomingController.add(data);
/// Simuliert einen Verbindungsfehler, z.B. um Fehlerbehandlung in der
/// Oberflaeche ohne Hardware zu testen.
void simulateError(LinkErrorReason reason, [String? message]) {
_lastErrorReason = reason;
_lastErrorMessage = message;
_setState(LinkState.error);
}
@override
Future<void> connect() async {
_lastErrorReason = null;
_lastErrorMessage = null;
_setState(LinkState.connecting);
_setState(LinkState.connected);
}
@override
Future<void> disconnect() async {
_setState(LinkState.disconnected);
}
@override
Future<void> send(Uint8List data) async {
sentData.add(data);
}
@override
void dispose() {
_incomingController.close();
_stateController.close();
}
void _setState(LinkState next) {
_state = next;
if (!_stateController.isClosed) _stateController.add(next);
}
LinkState get currentState => _state;
}