OSDP.Net 5.2.1
A .NET library for implementing the Open Supervised Device Protocol (OSDP)
Loading...
Searching...
No Matches
LineQualityProtocol.cs
1using System;
2using System.Collections.Generic;
3
5{
21 public static class LineQualityProtocol
22 {
30 internal static readonly byte[] VendorCodeBytes = { 0x02, 0x00, 0x0A };
31
37 public const byte TestAddress = 0x7D;
38
40 public const byte EchoCommandId = 0x01;
41
43 public const byte BaudRateChangeCommandId = 0x02;
44
49 public const int EchoHeaderLength = 7;
50
60 public const int MaxPayloadLength = 113;
61
65 public static IReadOnlyList<int> TestPayloadLengths { get; } = new[] { 0, 48, MaxPayloadLength };
66
67 private static readonly int[] BaudRateValues =
68 { 9600, 19200, 38400, 57600, 115200, 230400, 460800 };
69
74 public static IReadOnlyList<int> DefaultBaudRates { get; } =
75 new[] { 9600, 19200, 38400, 57600, 115200, 230400 };
76
80 public static ReadOnlySpan<byte> VendorCode => VendorCodeBytes;
81
87 public static bool IsLineQualityVendorCode(ReadOnlySpan<byte> candidate)
88 {
89 if (candidate.Length < VendorCodeBytes.Length) return false;
90
91 for (int index = 0; index < VendorCodeBytes.Length; index++)
92 {
93 if (candidate[index] != VendorCodeBytes[index]) return false;
94 }
95
96 return true;
97 }
98
107 public static byte[] GeneratePattern(TestPattern pattern, int length)
108 {
109 if (length < 0 || length > MaxPayloadLength)
110 {
111 throw new ArgumentOutOfRangeException(nameof(length),
112 $"Payload length must be between 0 and {MaxPayloadLength}.");
113 }
114
115 if (!IsSupportedPattern(pattern))
116 {
117 throw new ArgumentOutOfRangeException(nameof(pattern), $"Unknown test pattern {pattern}.");
118 }
119
120 var data = new byte[length];
121 for (int index = 0; index < length; index++)
122 {
123 data[index] = ExpectedByte(pattern, index);
124 }
125
126 return data;
127 }
128
135 public static bool ValidatePattern(TestPattern pattern, ReadOnlySpan<byte> data)
136 {
137 if (!IsSupportedPattern(pattern)) return false;
138
139 for (int index = 0; index < data.Length; index++)
140 {
141 if (data[index] != ExpectedByte(pattern, index)) return false;
142 }
143
144 return true;
145 }
146
156 public static bool IsSupportedPattern(TestPattern pattern) => pattern <= TestPattern.WalkingOne;
157
164 public static int ToBaudRate(LineQualityBaudRate baudRateId)
165 {
166 // The enum is byte-backed, so the index cannot be negative.
167 int index = (int)baudRateId;
168 if (index >= BaudRateValues.Length)
169 {
170 throw new ArgumentOutOfRangeException(nameof(baudRateId), $"Unknown baud rate ID {baudRateId}.");
171 }
172
173 return BaudRateValues[index];
174 }
175
182 public static bool TryGetBaudRateId(int baudRate, out LineQualityBaudRate baudRateId)
183 {
184 for (int index = 0; index < BaudRateValues.Length; index++)
185 {
186 if (BaudRateValues[index] != baudRate) continue;
187
188 baudRateId = (LineQualityBaudRate)index;
189 return true;
190 }
191
192 baudRateId = default;
193 return false;
194 }
195
202 public static int IterationsPerCombination(TestProfile profile)
203 {
204 switch (profile)
205 {
206 case TestProfile.Screening: return 10;
207 case TestProfile.Qualification: return 60;
208 case TestProfile.Extended: return 200;
209 default:
210 throw new ArgumentOutOfRangeException(nameof(profile), $"Unknown test profile {profile}.");
211 }
212 }
213
226 public static double DetectionLimitPercent(int packetsSent) =>
227 packetsSent <= 0 ? 100.0 : 300.0 / packetsSent;
228
236 public static TimeSpan TransmissionTime(int byteCount, int baudRate) =>
237 baudRate <= 0
238 ? TimeSpan.Zero
239 : TimeSpan.FromSeconds(byteCount * 10.0 / baudRate);
240
241 internal static byte ExpectedByte(TestPattern pattern, int index)
242 {
243 switch (pattern)
244 {
245 case TestPattern.AllZeros: return 0x00;
246 case TestPattern.AllOnes: return 0xFF;
247 case TestPattern.AlternatingA: return 0xAA;
248 case TestPattern.Alternating5: return 0x55;
249 case TestPattern.Sequential: return (byte)(index & 0xFF);
250 case TestPattern.WalkingOne: return (byte)(1 << (index % 8));
251 default: return 0x00;
252 }
253 }
254 }
255}
Constants and helpers for the OSDP Line Quality Test Procedure.
static IReadOnlyList< int > TestPayloadLengths
The payload lengths exercised by the test matrix in section 3.10.
static byte[] GeneratePattern(TestPattern pattern, int length)
Generates the test data for a pattern.
static int ToBaudRate(LineQualityBaudRate baudRateId)
Converts a Baud Rate ID into the baud rate it represents.
const byte BaudRateChangeCommandId
Command and reply identifier for the baud rate change exchange.
const int MaxPayloadLength
The largest test payload every conforming responder must accept, 113 bytes.
static IReadOnlyList< int > DefaultBaudRates
The six baud rates named by OSDP section 5.2, in ascending order.
static bool ValidatePattern(TestPattern pattern, ReadOnlySpan< byte > data)
Determines whether data matches what the pattern should have produced.
static double DetectionLimitPercent(int packetsSent)
Calculates the smallest packet loss rate a run of the given size can rule out, as a percentage,...
static int IterationsPerCombination(TestProfile profile)
Returns the number of iterations a profile runs for each pattern and size combination.
static bool IsSupportedPattern(TestPattern pattern)
Determines whether a pattern identifier is one this implementation can generate.
static ReadOnlySpan< byte > VendorCode
The reserved line quality vendor code, 02-00-0A.
static bool IsLineQualityVendorCode(ReadOnlySpan< byte > candidate)
Determines whether the supplied bytes are the reserved line quality vendor code.
static TimeSpan TransmissionTime(int byteCount, int baudRate)
Calculates how long a frame occupies the line, used to let a transmission drain before changing the b...
const int EchoHeaderLength
Number of bytes preceding the test data in an echo request or response: three vendor code bytes,...
static bool TryGetBaudRateId(int baudRate, out LineQualityBaudRate baudRateId)
Converts a baud rate into the Baud Rate ID that represents it.
const byte TestAddress
The dedicated line quality test address, 125 (0x7D).
const byte EchoCommandId
Command and reply identifier for the echo exchange.
TestPattern
Test pattern identifiers defined by the OSDP Line Quality Test Procedure, section 3....
LineQualityBaudRate
Baud Rate identifiers defined by the OSDP Line Quality Test Procedure, section 3.4.
TestProfile
Test profiles from section 3.10 of the Line Quality Test Procedure.