protocol.ymodem

XMODEM/YMODEM protocol implementation.

The XMODEM and YMODEM families of protocols are closely related. This module implements both; the exact protocol used is determined by entry point and capability negotiation.

exception glasgow.protocol.ymodem.YModemError

XMODEM/YMODEM communication error.

class glasgow.protocol.ymodem.YModemTransport

Abstract XMODEM/YMODEM transport.

abstractmethod async recv(length: int) → bytes

Receive length bytes.

Can be safely cancelled.

abstractmethod async send(data: bytes)

Send data and flush.

abstractmethod async purge()

Clear any data in the receive buffer.

enum glasgow.protocol.ymodem.YModemHeader(value)

XMODEM/YMODEM packet header.

Member Type:

bytes

Valid values are as follows:

SOH = <YModemHeader.SOH: 0x01>

128 bytes of data.

STX = <YModemHeader.STX: 0x02>

1024 bytes of data.

EOT = <YModemHeader.EOT: 0x04>

End of transfer.

ACK = <YModemHeader.ACK: 0x06>

Acknowledgement.

NAK = <YModemHeader.NAK: 0x15>

Non-acknowledgement.

CAN = <YModemHeader.CAN: 0x18>

Cancel.

C = <YModemHeader.C: 0x43>

Use XMODEM-CRC.

K = <YModemHeader.K: 0x4b>

Use XMODEM-1K (implies XMODEM-CRC).

The Enum and its members also have the following methods:

packet() → YModemPacket

Create an XMODEM/YMODEM control packet.

enum glasgow.protocol.ymodem.YModemVariant(value)

XMODEM/YMODEM protocol variant.

Valid values are as follows:

XMODEM = YModemVariant.XMODEM
XMODEM_CRC = YModemVariant.XMODEM_CRC
XMODEM_1K = YModemVariant.XMODEM_1K

The Enum and its members also have the following methods:

property has_crc16

Whether to use CRC-16 for data packets.

True for XMODEM_CRC and XMODEM_1K.

property has_1k

Whether to use 1024-byte data packets.

True for XMODEM_1K.

class glasgow.protocol.ymodem.YModemPacket(control: YModemHeader, number: int | None = None, data: bytes | None = None)

Abstract XMODEM/YMODEM packet.

Represents the contents of a control or data packet.

control: YModemHeader

Header byte.

number: int | None = None

Packet number, for data packets.

data: bytes | None = None

Packet payload, for data packets.

classmethod for_data(*, number: int, data: bytes) → YModemPacket

Create an XMODEM/YMODEM data packet.

抛出:

ValueError -- If len(data) is neither 128 nor 1024.

async classmethod recv(transport: YModemTransport, *, variant: YModemVariant) → Self | None

Receive a packet from transport.

Reads and returns a single XMODEM/YMODEM packet from transport. If the first byte read from transport is not a valid YModemControl header, returns None.

抛出:
  • YModemError -- If a checksum or CRC-16 was incorrect.

  • Exception -- Any error raised by transport.recv().

async send(transport: YModemTransport, *, variant: YModemVariant)

Send a packet to transport.

Formats and writes a single XMODEM/YMODEM packet to transport.

抛出:

Exception -- Any error raised by transport.send().

class glasgow.protocol.ymodem.YModemFileInfo(*, pathname: bytes, length: int | None = None, modified: int | None = None, mode: int | None = None)

YMODEM file metadata, transmitted in block zero.

pathname: bytes

File pathname.

The exact format of the pathname is not specified, but it "must be acceptable to both the sender and receiving operating systems". Drive letters and backslashes may not appear in the pathname in any case. It is recommended but not required to translate the pathname to lower case.

length: int | None = None

File length.

If present, this field should be used to discard any padding in the final block of the transfer.

modified: int | None = None

Modification date.

If present, this field indicates modification date as number of seconds from 1970-01-01 GMT.

mode: int | None = None

File mode.

If present, this field indicates that the file has been sent from a Unix system and has the specified mode.

classmethod parse(data: bytes)

Parse YMODEM metadata.

The metadata parser tolerates significant deviations from the specified format in order to try and maximize compatibility.

抛出:

YModemError -- If the metadata has invalid format.

emit() → bytes

Serialize YMODEM metadata.

备注

For each of self.modified and self.mode, the preceding field must be defined as well for this field to be serialized.

class glasgow.protocol.ymodem.YModemFile(*, info: YModemFileInfo, data: bytes)

YMODEM file representation.

info: YModemFileInfo

YMODEM file metadata.

data: bytes

File data.

classmethod from_path(path: str | PurePath) → Self

Read file from filesystem path.

备注

The meta.pathname field receives the file name only (without a path and without case conversion). Callers should update this field if different behavior is desired.

class glasgow.protocol.ymodem.YModemProtocol(transport: YModemTransport, *, logger: Logger = logger, progress: Progress | None = None)

XMODEM/YMODEM protocol handler.

Handles packet sequencing, retransmission, and data storage.

async recv_single(*, variant=YModemVariant.XMODEM_1K) → bytearray

Receive a single file using the XMODEM protocol.

Returns the concatenation of every data block; this will include padding at the end.

抛出:
  • YModemError -- If retransmit count is exceeded.

  • YModemError -- If another protocol violation occurs.

  • Exception -- Any error raised by transport.send() or transport.recv().

async recv_batch() → list[YModemFile]

Receive a batch of files using the YMODEM protocol.

Returns a list of files received in the batch, with the file data trimmed to remove any padding.

抛出:
  • YModemError -- If YMODEM metadata is malformed.

  • YModemError -- If retransmit count is exceeded.

  • YModemError -- If another protocol violation occurs.

  • Exception -- Any error raised by transport.send() or transport.recv().

async send_single(file_data: bytearray)

Send a single file using the XMODEM protocol.

Last block will be padded with ASCII 0x1A (SUB) characters up to a 128-byte block boundary.

抛出:
  • YModemError -- If a protocol violation occurs.

  • Exception -- Any error raised by transport.send() or transport.recv().

async send_batch(files: list[YModemFile])

Send a batch of files using the YMODEM protocol.

See remark in send_single().

抛出:
  • YModemError -- If a protocol violation occurs.

  • Exception -- Any error raised by transport.send() or transport.recv().