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/drivers/ethernetlite/EthernetLiteReceiveWindow.lvt

namespace Livt.Net.Drivers.EthernetLite

using Livt.IO

/**
 * Finds a conservative prefix in CRC-accepted EthernetLite RX storage.
 * Scan at most capacity + four FCS octets. The first valid residue at or after
 * 64 octets bounds payload before FCS; an earlier accidental residue only
 * shortens the prefix. It does not establish exact wire length.
 */
component EthernetLiteReceiveWindow<CAPACITY: int = 128>
{
	static assert CAPACITY >= 60 && CAPACITY <= 1514, "Capture capacity must be 60..1514"

	// Ethernet CRC residue before final complement; byte updates come from Livt.IO.
	const RESIDUE: uint = 0xDEBB20E3

	// Current scan state; no packet storage is owned here.
	crc: uint
	const COUNT_BITS: int = Bits.RequiredFor(CAPACITY + 4)
	const LENGTH_BITS: int = Bits.RequiredFor(CAPACITY)
	count: logic[COUNT_BITS]
	finished: bool
	length: logic[LENGTH_BITS]

	/**
	 * Starts an empty scan. Capacity must fit the device's data window.
	 */
	new()
	{
		this.crc = 0xFFFFFFFF
	}

	/**
	 * Discards the previous scan before reading a new CRC-accepted device buffer.
	 */
	public fn Reset()
	{
		this.crc = 0xFFFFFFFF
		this.count = 0
		this.finished = false
		this.length = 0
	}

	/**
	 * Consumes the next memory octet in wire order, including retained FCS.
	 */
	public fn AddByte(value: byte)
	{
		if (this.finished) {
			return
		}

		var next = EthernetCrc.Update(this.crc as logic[32], value) as uint

		this.crc = next
		this.count++

		if (this.count >= 64 && next == RESIDUE) {
			this.length = (((this.count as uint) as int) - 4) as logic[LENGTH_BITS]
			this.finished = true
		} elif (((this.count as uint) as int) == CAPACITY + 4) {
			this.length = CAPACITY as logic[LENGTH_BITS]
			this.finished = true
		}
	}

	/**
	 * Reports whether the scan has certified a prefix.
	 */
	public fn IsFinished() bool
	{
		return this.finished
	}

	/**
	 * Returns the certified prefix length, or zero before scan completion.
	 */
	public fn GetLength() int
	{
		return (this.length as uint) as int
	}
}