97b5d8a84f
Signed-off-by: Tony <tonylu@tony-cloud.com>
167 lines
4.1 KiB
Dart
167 lines
4.1 KiB
Dart
import 'dart:async';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:knx_stack/knx_stack.dart';
|
|
import 'package:knx_stack_tpuart/knx_stack_tpuart.dart';
|
|
|
|
void main() {
|
|
group('KnxTpUartClient', () {
|
|
test('completes the reset and state handshake', () async {
|
|
final transport = _FakeKnxTransport();
|
|
final client = KnxTpUartClient(transport: transport);
|
|
|
|
final connectFuture = client.connect();
|
|
await _flushMicrotasks();
|
|
|
|
expect(transport.sentFrames, hasLength(1));
|
|
expect(transport.sentFrames.single, [0x01]);
|
|
|
|
transport.emit(const [0x03]);
|
|
await _flushMicrotasks();
|
|
|
|
expect(transport.sentFrames, hasLength(2));
|
|
expect(transport.sentFrames.last, [0x02]);
|
|
|
|
transport.emit(const [0x07]);
|
|
await connectFuture;
|
|
|
|
expect(client.isConnected, isTrue);
|
|
});
|
|
|
|
test('encodes cEMI writes into TP-UART service bytes', () async {
|
|
final transport = _FakeKnxTransport();
|
|
final client = KnxTpUartClient(transport: transport);
|
|
await _connectClient(client, transport);
|
|
|
|
final sendFuture = client.send(_sampleCemiWrite().toBytes());
|
|
await _flushMicrotasks();
|
|
|
|
expect(transport.sentFrames.last, [
|
|
0x80,
|
|
0xbc,
|
|
0x81,
|
|
0x11,
|
|
0x82,
|
|
0x01,
|
|
0x83,
|
|
0x00,
|
|
0x84,
|
|
0x01,
|
|
0x85,
|
|
0xe2,
|
|
0x86,
|
|
0x00,
|
|
0x87,
|
|
0x80,
|
|
0x88,
|
|
0x64,
|
|
0x49,
|
|
0x54,
|
|
]);
|
|
|
|
transport.emit(const [0x8b]);
|
|
await sendFuture;
|
|
});
|
|
|
|
test('decodes inbound TP telegrams into cEMI indications', () async {
|
|
final transport = _FakeKnxTransport();
|
|
final client = KnxTpUartClient(transport: transport);
|
|
await _connectClient(client, transport);
|
|
|
|
final frameFuture = client.inboundFrames.first;
|
|
final messageFuture = client.inboundMessages.first;
|
|
|
|
transport.emit(const [0xbc, 0x11, 0x01, 0x00, 0x01, 0xe2, 0x00, 0x80, 0x64, 0x54]);
|
|
|
|
expect(await frameFuture, [
|
|
0x29,
|
|
0x00,
|
|
0xbc,
|
|
0xe0,
|
|
0x11,
|
|
0x01,
|
|
0x00,
|
|
0x01,
|
|
0x02,
|
|
0x00,
|
|
0x80,
|
|
0x64,
|
|
]);
|
|
expect((await messageFuture).destinationAddress.canonical, '0/0/1');
|
|
});
|
|
});
|
|
}
|
|
|
|
Future<void> _connectClient(KnxTpUartClient client, _FakeKnxTransport transport) async {
|
|
final connectFuture = client.connect();
|
|
await _flushMicrotasks();
|
|
transport.emit(const [0x03]);
|
|
await _flushMicrotasks();
|
|
transport.emit(const [0x07]);
|
|
await connectFuture;
|
|
}
|
|
|
|
Future<void> _flushMicrotasks() async {
|
|
await Future<void>.delayed(Duration.zero);
|
|
}
|
|
|
|
CemiLDataReq _sampleCemiWrite() {
|
|
final controlField2 = ExtendedControlField()
|
|
..addressType = AddressType.group
|
|
..hopCount = 6
|
|
..eff = ExtendedFrameFormat.pointToPointOrStandardGroupAddressedLDataExtendedFrame;
|
|
|
|
return CemiLDataReq(
|
|
controlField1: ControlField(0xbc),
|
|
controlField2: controlField2,
|
|
sourceAddress: KnxIndividualAddress.parse('1.1.1'),
|
|
destinationAddress: KnxGroupAddress.parse('0/0/1'),
|
|
tpdu: TPDU(data: Uint8List.fromList([0x64])),
|
|
);
|
|
}
|
|
|
|
final class _FakeKnxTransport implements KnxTransport {
|
|
final StreamController<Uint8List> _frames = StreamController<Uint8List>.broadcast();
|
|
final List<Uint8List> sentFrames = <Uint8List>[];
|
|
|
|
bool _isConnected = false;
|
|
|
|
@override
|
|
String get transportId => 'fake_tpuart';
|
|
|
|
@override
|
|
KnxFeature get feature => KnxFeature.tpuartTransport;
|
|
|
|
@override
|
|
KnxFeatureSupport get support => const KnxFeatureSupport.supported(
|
|
feature: KnxFeature.tpuartTransport,
|
|
platform: KnxPlatform.macos,
|
|
);
|
|
|
|
@override
|
|
bool get isConnected => _isConnected;
|
|
|
|
@override
|
|
Stream<Uint8List> get inboundFrames => _frames.stream;
|
|
|
|
@override
|
|
Future<void> connect() async {
|
|
_isConnected = true;
|
|
}
|
|
|
|
@override
|
|
Future<void> disconnect() async {
|
|
_isConnected = false;
|
|
}
|
|
|
|
@override
|
|
Future<void> send(Uint8List frame) async {
|
|
sentFrames.add(Uint8List.fromList(frame));
|
|
}
|
|
|
|
void emit(List<int> frame) {
|
|
_frames.add(Uint8List.fromList(frame));
|
|
}
|
|
}
|