Record
public record HdlcControl : System.ValueType, System.IEquatable<SharpMeter.Dlms.Framing.HdlcControl>
Namespace: SharpMeter.Dlms.Framing
HDLC control field supporting I, S, and U frame types.
Inheritance
Inherits from: System.ValueType
Implements: System.IEquatable<SharpMeter.Dlms.Framing.HdlcControl>
Constructors
| Name | Description |
|---|---|
HdlcControl(…) |
HDLC control field supporting I, S, and U frame types. |
HdlcControl(HdlcFrameType FrameType, bool PollFinal, byte SendSequence, byte ReceiveSequence)
HdlcControl.HdlcControl(HdlcFrameType FrameType, bool PollFinal = false, byte SendSequence = 0, byte ReceiveSequence = 0)
HDLC control field supporting I, S, and U frame types.
Parameters
| Name | Type | Description |
|---|---|---|
FrameType | SharpMeter.Dlms.Framing.HdlcFrameType | The frame type. |
PollFinal | bool | The poll/final bit. |
SendSequence | byte | Send sequence number (N(S)) for I-frames. |
ReceiveSequence | byte | Receive sequence number (N(R)) for I/S-frames. |
Properties
| Name | Description |
|---|---|
FrameType |
The frame type. |
PollFinal |
The poll/final bit. |
ReceiveSequence |
Receive sequence number (N(R)) for I/S-frames. |
SendSequence |
Send sequence number (N(S)) for I-frames. |
FrameType
HdlcFrameType HdlcControl.FrameType { get; init; }
The frame type.
PollFinal
bool HdlcControl.PollFinal { get; init; }
The poll/final bit.
ReceiveSequence
byte HdlcControl.ReceiveSequence { get; init; }
Receive sequence number (N(R)) for I/S-frames.
SendSequence
byte HdlcControl.SendSequence { get; init; }
Send sequence number (N(S)) for I-frames.
Methods
| Name | Description |
|---|---|
Decode(byte value) static |
Decodes a control byte. |
Encode() |
Encodes this control field as a single byte. |
Decode(byte value)
HdlcControl HdlcControl.Decode(byte value)
Decodes a control byte.
Encode()
byte HdlcControl.Encode()
Encodes this control field as a single byte.
Fields
| Name | Description |
|---|---|
Disc static |
DISC (Disconnect). |
Dm static |
DM (Disconnected Mode). |
Snrm static |
SNRM (Set Normal Response Mode) — connection establishment. |
Ua static |
UA (Unnumbered Acknowledge). |
Disc
SharpMeter.Dlms.Framing.HdlcControl Disc
DISC (Disconnect).
Dm
SharpMeter.Dlms.Framing.HdlcControl Dm
DM (Disconnected Mode).
Snrm
SharpMeter.Dlms.Framing.HdlcControl Snrm
SNRM (Set Normal Response Mode) — connection establishment.
Ua
SharpMeter.Dlms.Framing.HdlcControl Ua
UA (Unnumbered Acknowledge).
Type Relationships
classDiagram
style HdlcControl fill:#f9f,stroke:#333,stroke-width:2px
HdlcControl --|> ValueType : inherits
HdlcControl ..|> HdlcControl~ : implements
View Source
/// <summary>
/// HDLC control field supporting I, S, and U frame types.
/// </summary>
/// <param name = "FrameType">The frame type.</param>
/// <param name = "PollFinal">The poll/final bit.</param>
/// <param name = "SendSequence">Send sequence number (N(S)) for I-frames.</param>
/// <param name = "ReceiveSequence">Receive sequence number (N(R)) for I/S-frames.</param>
public readonly record struct HdlcControl(HdlcFrameType FrameType, bool PollFinal = false, byte SendSequence = 0, byte ReceiveSequence = 0)
{
#region Well-Known Controls
/// <summary>SNRM (Set Normal Response Mode) — connection establishment.</summary>
public static readonly HdlcControl Snrm = new(HdlcFrameType.Snrm, true);
/// <summary>UA (Unnumbered Acknowledge).</summary>
public static readonly HdlcControl Ua = new(HdlcFrameType.Ua, true);
/// <summary>DISC (Disconnect).</summary>
public static readonly HdlcControl Disc = new(HdlcFrameType.Disc, true);
/// <summary>DM (Disconnected Mode).</summary>
public static readonly HdlcControl Dm = new(HdlcFrameType.Dm, true);
#endregion
#region Methods
/// <summary>Encodes this control field as a single byte.</summary>
public byte Encode()
{
var pf = PollFinal ? 0x10 : 0;
return FrameType switch
{
// I-frame: N(R) | P/F | N(S) | 0
HdlcFrameType.Information => (byte)((ReceiveSequence << 5) | pf | (SendSequence << 1)),
// RR: N(R) | P/F | 0001
HdlcFrameType.ReceiveReady => (byte)((ReceiveSequence << 5) | pf | 0x01),
// RNR: N(R) | P/F | 0101
HdlcFrameType.ReceiveNotReady => (byte)((ReceiveSequence << 5) | pf | 0x05),
// SNRM: 100 P/F 0011
HdlcFrameType.Snrm => (byte)(0x83 | pf),
// DISC: 010 P/F 0011
HdlcFrameType.Disc => (byte)(0x43 | pf),
// UA: 011 P/F 0011
HdlcFrameType.Ua => (byte)(0x63 | pf),
// DM: 000 P/F 1111
HdlcFrameType.Dm => (byte)(0x0F | pf),
// FRMR: 100 P/F 0111
HdlcFrameType.FrameReject => (byte)(0x87 | pf),
// UI: 000 P/F 0011
HdlcFrameType.UnnumberedInformation => (byte)(0x03 | pf),
_ => 0
};
}
/// <summary>Decodes a control byte.</summary>
public static HdlcControl Decode(byte value)
{
var pf = (value & 0x10) != 0;
// I-frame: bit 0 = 0
if ((value & 0x01) == 0)
{
var ns = (byte)((value >> 1) & 0x07);
var nr = (byte)((value >> 5) & 0x07);
return new HdlcControl(HdlcFrameType.Information, pf, ns, nr);
}
// S-frame: bits 1:0 = 01
if ((value & 0x02) == 0)
{
var nr = (byte)((value >> 5) & 0x07);
HdlcFrameType sType = (value & 0x0C) switch
{
0x00 => HdlcFrameType.ReceiveReady,
0x04 => HdlcFrameType.ReceiveNotReady,
_ => HdlcFrameType.ReceiveReady
};
return new HdlcControl(sType, pf, ReceiveSequence: nr);
}
// U-frame
var masked = value & 0xEF; // mask out P/F
HdlcFrameType frameType = masked switch
{
0x83 => HdlcFrameType.Snrm,
0x43 => HdlcFrameType.Disc,
0x63 => HdlcFrameType.Ua,
0x0F => HdlcFrameType.Dm,
0x87 => HdlcFrameType.FrameReject,
0x03 => HdlcFrameType.UnnumberedInformation,
_ => HdlcFrameType.UnnumberedInformation
};
return new HdlcControl(frameType, pf);
}
#endregion
}