Livt packages
Livt.Net
Version 1.4.1
Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.
Published files (163)
src/link/TestFrameReceiver.lvt
namespace Livt.Net
enum TestReceiveState
{
Empty
Available
Acquired
Resetting
}
/**
* Deterministic buffered receiver for Livt tests. Inject/Publish/Fail/Reset
* controls belong to the test harness, not IFrameReceiver or a device driver.
*/
component TestFrameReceiver<CAPACITY: int = 128> : IFrameReceiver
{
// Owned capture storage; acquisition freezes its publication lifetime.
storage: ArrayPacketData<CAPACITY>
// Receive ownership, optional wire length and independently latched error.
phase: TestReceiveState
wireKnown: bool
wireLength: int
failed: bool
/**
* Creates owned packet storage and starts empty, with no wire-length knowledge or error.
*/
new()
{
storage = new ArrayPacketData<CAPACITY>()
phase = TestReceiveState.Empty
wireKnown = false
wireLength = 0
failed = false
}
/**
* Returns the maximum captured prefix length in bytes, not the wire length.
*/
override fn GetReceiveCapacity() int
{
return CAPACITY
}
/**
* Reports an available or already acquired frame; this snapshot does not acquire it.
*/
override fn HasReceiveFrame() bool
{
return phase == TestReceiveState.Available || phase == TestReceiveState.Acquired
}
/**
* Reports whether a frame is acquired and readable by its owner.
*/
override fn IsReady() bool
{
return phase == TestReceiveState.Acquired
}
/**
* Returns the acquired captured prefix length, or zero without acquisition.
*/
override fn GetAvailableLength() int
{
if (phase != TestReceiveState.Acquired) {
return 0
}
return storage.GetAvailableLength()
}
/**
* Reads a captured byte only while acquired. Returns NotReady without ownership
* and Invalid outside the captured prefix; output is data only on Success.
*/
override fn TryRead(index: int, value: out byte) PacketDataResult
{
value = 0x00
if (phase != TestReceiveState.Acquired) {
return PacketDataResult.NotReady
}
return storage.TryRead(index, value)
}
/**
* Acquires the available frame on Success; packet reads then become valid.
* Busy means already acquired, NotReady means unavailable/resetting, and
* DeviceFailure reports a receive error. Failed acquisition grants no ownership.
*/
override fn TryAcquire() FrameLinkResult
{
if (phase == TestReceiveState.Acquired) {
return FrameLinkResult.Busy
}
if (phase == TestReceiveState.Resetting) {
return FrameLinkResult.NotReady
}
if (failed) {
return FrameLinkResult.DeviceFailure
}
if (phase != TestReceiveState.Available) {
return FrameLinkResult.NotReady
}
phase = TestReceiveState.Acquired
return FrameLinkResult.Success
}
/**
* Releases an acquired frame and clears prefix/wire metadata without erasing RAM.
* Close all dependent views first. Returns Invalid without acquisition or
* NotReady while resetting.
*/
override fn TryRelease() FrameLinkResult
{
if (phase == TestReceiveState.Resetting) {
return FrameLinkResult.NotReady
}
if (phase != TestReceiveState.Acquired) {
return FrameLinkResult.Invalid
}
storage.TryRelease()
wireKnown = false
wireLength = 0
phase = TestReceiveState.Empty
return FrameLinkResult.Success
}
/**
* Reports whether the acquired frame has an exact wire length.
*/
override fn HasKnownWireLength() bool
{
return phase == TestReceiveState.Acquired && wireKnown
}
/**
* Zero is not an unknown-length sentinel; first check HasKnownWireLength.
*/
override fn GetWireLength() int
{
if (phase != TestReceiveState.Acquired || !wireKnown) {
return 0
}
return wireLength
}
/**
* Reports a latched receive failure independently of frame ownership.
*/
override fn HasReceiveError() bool
{
return failed
}
/**
* Clears a pending receive error. Returns NotReady if no error can be acknowledged.
*/
override fn TryAcknowledgeReceiveError() FrameLinkResult
{
if (phase == TestReceiveState.Resetting || !failed) {
return FrameLinkResult.NotReady
}
failed = false
return FrameLinkResult.Success
}
/**
* Appends or overwrites an initialized byte while empty. Holes/out-of-range
* indices are Invalid; owned frames are Busy and a latched error is DeviceFailure.
*/
public fn InjectByte(index: int, value: byte) FrameLinkResult
{
if (phase == TestReceiveState.Resetting) {
return FrameLinkResult.NotReady
}
if (phase != TestReceiveState.Empty) {
return FrameLinkResult.Busy
}
if (failed) {
return FrameLinkResult.DeviceFailure
}
if (storage.TryWrite(index, value) != PacketDataResult.Success) {
return FrameLinkResult.Invalid
}
return FrameLinkResult.Success
}
/**
* Publish the initialized prefix; unknown wire length must be supplied as zero.
*/
public fn Publish(known: bool, length: int) FrameLinkResult
{
if (phase == TestReceiveState.Resetting) {
return FrameLinkResult.NotReady
}
if (phase != TestReceiveState.Empty) {
return FrameLinkResult.Busy
}
if (failed) {
return FrameLinkResult.DeviceFailure
}
if (length < 0 || (!known && length != 0)) {
return FrameLinkResult.Invalid
}
if (known && length < storage.GetWrittenLength()) {
return FrameLinkResult.Invalid
}
storage.TryPublish()
wireKnown = known
wireLength = length
phase = TestReceiveState.Available
return FrameLinkResult.Success
}
/**
* Discard an incomplete capture and latch an error; never revoke an owned frame.
*/
public fn FailReceive() FrameLinkResult
{
if (phase == TestReceiveState.Resetting) {
return FrameLinkResult.NotReady
}
if (phase != TestReceiveState.Empty) {
return FrameLinkResult.Busy
}
storage.TryClear()
failed = true
return FrameLinkResult.Success
}
/**
* Enters the reset barrier and disables access. Stop dependent readers before CompleteReset.
*/
public fn BeginReset()
{
phase = TestReceiveState.Resetting
}
/**
* Harness barrier: all dependent readers must already be stopped/reset.
*/
public fn CompleteReset()
{
if (phase != TestReceiveState.Resetting) {
return
}
if (storage.IsReady()) {
storage.TryRelease()
}
else {
storage.TryClear()
}
wireKnown = false
wireLength = 0
failed = false
phase = TestReceiveState.Empty
}
}