XMODEM protocol implementation

0.5.0 · active · verified Wed Apr 15

The `xmodem` library provides an implementation of the XMODEM, YMODEM, and ZMODEM protocols for Python. It focuses on a minimalistic implementation while adhering to protocol specifications. All modem classes require `getc` and `putc` callback functions to handle character data for communication. The current version is 0.5.0, with releases occurring periodically to address bugs and introduce enhancements.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to initialize the `XMODEM` class by providing `getc` and `putc` callback functions, which handle reading from and writing to a communication channel (e.g., a serial port). It shows the basic structure for sending and receiving data streams using the `send()` and `recv()` methods. Note that a full XMODEM transfer requires a cooperating sender and receiver, and a dummy serial port is used here for illustrative purposes.

import serial
from xmodem import XMODEM

# Configure your serial port here
# For example, using a dummy serial port for demonstration
# In a real application, replace with an actual serial port like '/dev/ttyUSB0'
class DummySerial:
    def __init__(self, timeout=0):
        self.buffer = b''

    def read(self, size):
        if not self.buffer:
            return b''
        data = self.buffer[:size]
        self.buffer = self.buffer[size:]
        return data

    def write(self, data):
        # In a real scenario, this would send data over serial
        # For this dummy example, we just 'receive' it instantly
        # Or, you could print it to simulate output.
        # print(f"DummySerial sent: {data!r}")
        self.buffer += data # Simulate loopback or immediate reception
        return len(data)

# Replace DummySerial() with serial.Serial('/dev/ttyUSB0', timeout=0) for actual use
ser = DummySerial(timeout=0)

def getc(size, timeout=1):
    return ser.read(size) or None

def putc(data, timeout=1):
    return ser.write(data)

modem = XMODEM(getc, putc)

# --- Example: Sending a file ---
print("Attempting to send data...")
# Create a dummy stream for demonstration
import io
stream_to_send = io.BytesIO(b"Hello, XMODEM world! This is a test file.\n")

# In a real scenario, this would be `open('/path/to/file', 'rb')`
# status = modem.send(stream_to_send)
# print(f"Send status: {status}")

# Due to the complexity of XMODEM handshakes in a simple script 
# without a cooperating receiver, the send/recv calls are commented out.
# A successful transfer requires a matching XMODEM receiver on the other end.
print("To send a file: modem.send(file_stream_object)")
print("To receive a file: modem.recv(file_stream_object)")
print("Note: A full XMODEM transfer requires a corresponding receiver/sender.")

# --- Example: Receiving a file ---
# stream_to_receive = io.BytesIO()
# received_bytes = modem.recv(stream_to_receive)
# if received_bytes is not None:
#     print(f"Received {received_bytes} bytes: {stream_to_receive.getvalue()!r}")
# else:
#     print("Failed to receive data.")

view raw JSON →