diff --git a/Lawo.EmberPlusSharpTest/S101/CommunicationTestBase.cs b/Lawo.EmberPlusSharpTest/S101/CommunicationTestBase.cs
index 5f5d99f9..81779471 100644
--- a/Lawo.EmberPlusSharpTest/S101/CommunicationTestBase.cs
+++ b/Lawo.EmberPlusSharpTest/S101/CommunicationTestBase.cs
@@ -9,6 +9,7 @@ namespace Lawo.EmberPlusSharp.S101
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
+ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
@@ -26,6 +27,8 @@ public abstract class CommunicationTestBase : TestBase
{
private static readonly EmberData EmberDataCommandField = new EmberData(0x01, 0x0A, 0x02);
private static readonly S101Message EmberDataMessageField = new S101Message(0x00, EmberDataCommandField);
+ private static readonly S101Message KeepAliveRequestMessageField = new S101Message(0x00, new KeepAliveRequest());
+ private static readonly S101Message KeepAliveResponseMessageField = new S101Message(0x00, new KeepAliveResponse());
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -47,6 +50,18 @@ protected static S101Message EmberDataMessage
get { return EmberDataMessageField; }
}
+ /// Gets a message with an command.
+ protected static S101Message KeepAliveRequestMessage
+ {
+ get { return KeepAliveRequestMessageField; }
+ }
+
+ /// Gets a message with an command.
+ protected static S101Message KeepAliveResponseMessage
+ {
+ get { return KeepAliveResponseMessageField; }
+ }
+
/// Uses to simulate a provider communicating with the
/// object passed to .
/// The type whose namespace is used to scope
@@ -232,6 +247,19 @@ protected static async Task MonitorConnection(
await waitForConnectionLost;
}
+ /// Gets a random byte that is guaranteed to not be equal to any of the elements in
+ /// .
+ protected byte GetRandomByteExcept(params byte[] exceptions)
+ {
+ byte result;
+
+ while (exceptions.Contains(result = (byte)this.Random.Next(byte.MinValue, byte.MaxValue + 1)))
+ {
+ }
+
+ return result;
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static Task Read(
diff --git a/Lawo.EmberPlusSharpTest/S101/S101ClientTest.cs b/Lawo.EmberPlusSharpTest/S101/S101ClientTest.cs
index 601a1200..b52c4ef4 100644
--- a/Lawo.EmberPlusSharpTest/S101/S101ClientTest.cs
+++ b/Lawo.EmberPlusSharpTest/S101/S101ClientTest.cs
@@ -238,18 +238,5 @@ public void VersionTest()
null,
null));
}
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- private byte GetRandomByteExcept(params byte[] exceptions)
- {
- byte result;
-
- while (exceptions.Contains(result = (byte)this.Random.Next(byte.MinValue, byte.MaxValue + 1)))
- {
- }
-
- return result;
- }
}
}
diff --git a/Lawo.EmberPlusSharpTest/S101/S101WriterTest.cs b/Lawo.EmberPlusSharpTest/S101/S101WriterTest.cs
index 0505e300..52232583 100644
--- a/Lawo.EmberPlusSharpTest/S101/S101WriterTest.cs
+++ b/Lawo.EmberPlusSharpTest/S101/S101WriterTest.cs
@@ -54,24 +54,27 @@ public void OutOfFrameByteTest()
AsyncPump.Run(
async () =>
{
+ var first = GetRandomByteExcept(0xFE);
+ var second = GetRandomByteExcept(0xFE);
+
+ var prefix = new[] { GetRandomByteExcept() };
+ var third = GetRandomByteExcept(0xFE);
+ var postfix = new[] { GetRandomByteExcept() };
+
using (var asyncStream = new MemoryStream())
{
var writer = new S101Writer(asyncStream.WriteAsync);
try
{
- await writer.WriteMessageAsync(
- new S101Message(0x00, new KeepAliveRequest()), CancellationToken.None);
- await writer.WriteOutOfFrameByte((byte)this.Random.Next(0xFE), CancellationToken.None);
- await writer.WriteMessageAsync(
- new S101Message(0x00, new KeepAliveResponse()), CancellationToken.None);
+ await writer.WriteOutOfFrameByte(first, CancellationToken.None);
+ await writer.WriteMessageAsync(KeepAliveRequestMessage, CancellationToken.None);
+ await writer.WriteOutOfFrameByte(second, CancellationToken.None);
using (var encodingStream = await writer.WriteMessageAsync(EmberDataMessage, CancellationToken.None))
{
- var prefix = new byte[] { 0x42 };
- var postfix = new byte[] { 0x43 };
await encodingStream.WriteAsync(prefix, 0, prefix.Length, CancellationToken.None);
- await writer.WriteOutOfFrameByte(0xEE, CancellationToken.None);
+ await writer.WriteOutOfFrameByte(third, CancellationToken.None);
await encodingStream.WriteAsync(postfix, 0, postfix.Length, CancellationToken.None);
await encodingStream.DisposeAsync(CancellationToken.None);
}
@@ -81,9 +84,30 @@ await writer.WriteMessageAsync(
await writer.DisposeAsync(CancellationToken.None);
}
- var stringBytes =
- asyncStream.ToArray().Select(b => b.ToString("X2", CultureInfo.InvariantCulture));
- var result = string.Join(", ", stringBytes).ToUpperInvariant();
+ asyncStream.Position = 0;
+ var reader = new S101Reader(asyncStream.ReadAsync);
+ var firstTask = WaitForOutOfFrameByte(reader);
+ Assert.IsTrue(await reader.ReadAsync(CancellationToken.None));
+ Assert.AreEqual(0x00, reader.Message.Slot);
+ Assert.IsInstanceOfType(reader.Message.Command, typeof(KeepAliveRequest));
+ Assert.AreEqual(first, await firstTask);
+ var secondTask = WaitForOutOfFrameByte(reader);
+ Assert.IsTrue(await reader.ReadAsync(CancellationToken.None));
+ Assert.AreEqual(0x00, reader.Message.Slot);
+ Assert.IsInstanceOfType(reader.Message.Command, typeof(EmberData));
+ Assert.AreEqual(second, await secondTask);
+ var thirdTask = WaitForOutOfFrameByte(reader);
+
+ using (var payloadStream = new MemoryStream())
+ {
+ await reader.Payload.CopyToAsync(payloadStream);
+ var payload = payloadStream.ToArray();
+ Assert.AreEqual(2, payload.Length);
+ Assert.AreEqual(prefix.Single(), payload[0]);
+ Assert.AreEqual(postfix.Single(), payload[1]);
+ }
+
+ Assert.AreEqual(third, await thirdTask);
}
});
}
@@ -190,21 +214,36 @@ await AssertThrowAsync(
() => stream.Position = 0,
() => stream.Seek(0, SeekOrigin.Begin));
- await AssertThrowAsync(
- () => writer.WriteMessageAsync(new S101Message(0x00, new KeepAliveRequest()), CancellationToken.None));
+ await AssertThrowAsync(() => writer.WriteMessageAsync(
+ new S101Message(0x00, new KeepAliveRequest()), CancellationToken.None));
await stream.DisposeAsync(CancellationToken.None);
await AssertThrowAsync(
() => stream.WriteAsync(new byte[] { 2 }, 0, 1, CancellationToken.None));
}
await writer.DisposeAsync(CancellationToken.None);
- await AssertThrowAsync(
- () => writer.WriteMessageAsync(new S101Message(0x00, new KeepAliveRequest()), CancellationToken.None));
+ await AssertThrowAsync(() => writer.WriteMessageAsync(
+ new S101Message(0x00, new KeepAliveRequest()), CancellationToken.None));
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ private Task WaitForOutOfFrameByte(S101Reader reader)
+ {
+ var resultSource = new TaskCompletionSource();
+ EventHandler handler = null;
+
+ handler = (s, e) =>
+ {
+ reader.OutOfFrameByteReceived -= handler;
+ resultSource.SetResult(e.Value);
+ };
+
+ reader.OutOfFrameByteReceived += handler;
+ return resultSource.Task;
+ }
+
private static async Task Encode(S101Message message, byte[] payload = null)
{
using (var asyncStream = new MemoryStream())