pamoja.mesh
Idiomatic mesh-framing facade.
When the fixed infrastructure is gone or was never there, devices carry each other's traffic: every node relays what it hears, so a message crosses an area no single node can reach. This is the packet half of that, addressing and integrity over radios that give you neither.
1"""Idiomatic mesh-framing facade. 2 3When the fixed infrastructure is gone or was never there, devices carry each 4other's traffic: every node relays what it hears, so a message crosses an area no 5single node can reach. This is the packet half of that, addressing and integrity 6over radios that give you neither. 7""" 8 9from __future__ import annotations 10 11from pamoja._native import MeshFrame, SeenPackets 12from pamoja._native import mesh_broadcast_frame as _broadcast_frame 13from pamoja._native import mesh_crc16 as _crc16 14from pamoja._native import mesh_frame as _frame 15from pamoja._native import mesh_limits as _limits 16from pamoja._native import mesh_parse_frame as _parse_frame 17from pamoja._native import mesh_relayed as _relayed 18 19__all__ = [ 20 "BROADCAST", 21 "DEFAULT_HOP_LIMIT", 22 "MAX_FRAME", 23 "MAX_PAYLOAD", 24 "HEADER_LEN", 25 "SEEN_DEFAULT_CAPACITY", 26 "MeshFrame", 27 "SeenPackets", 28 "broadcast", 29 "crc16", 30 "frame", 31 "parse", 32 "relayed", 33] 34 35_MAX_FRAME, _MAX_PAYLOAD, _BROADCAST, _HOP_LIMIT, _SEEN, _HEADER = _limits() 36 37#: How many bytes of a frame are header, so where its payload starts. 38HEADER_LEN = _HEADER 39#: The largest frame, in bytes, including its header and checksum. 40MAX_FRAME = _MAX_FRAME 41#: The largest payload a single frame can carry, in bytes. 42MAX_PAYLOAD = _MAX_PAYLOAD 43#: The destination address that means every node. 44BROADCAST = _BROADCAST 45#: The hop limit a frame starts with unless one is given. 46DEFAULT_HOP_LIMIT = _HOP_LIMIT 47#: A duplicate-cache size for a caller with no reason to choose one. 48SEEN_DEFAULT_CAPACITY = _SEEN 49 50 51def frame( 52 src: int, 53 dst: int, 54 id: int, 55 payload: bytes, 56 hop_limit: int | None = None, 57) -> MeshFrame: 58 """Build a frame addressed to one node. 59 60 :param src: The address of this node. 61 :param dst: The address the frame is for, or :data:`BROADCAST`. 62 :param id: The sequence number identifying this packet from this source. 63 :param payload: The bytes to carry. 64 :param hop_limit: How many relays the frame may take, defaulting to 65 :data:`DEFAULT_HOP_LIMIT`. 66 :returns: The frame, with the bytes to transmit on its ``bytes`` attribute. 67 :raises PamojaError: If the payload is larger than :data:`MAX_PAYLOAD`. 68 """ 69 return _frame(src, dst, id, bytes(payload), hop_limit) 70 71 72def broadcast( 73 src: int, id: int, payload: bytes, hop_limit: int | None = None 74) -> MeshFrame: 75 """Build a frame addressed to every node. 76 77 :param src: The address of this node. 78 :param id: The sequence number identifying this packet from this source. 79 :param payload: The bytes to carry. 80 :param hop_limit: How many relays the frame may take, defaulting to 81 :data:`DEFAULT_HOP_LIMIT`. 82 :returns: The frame, with the bytes to transmit on its ``bytes`` attribute. 83 :raises PamojaError: If the payload is larger than :data:`MAX_PAYLOAD`. 84 """ 85 return _broadcast_frame(src, id, bytes(payload), hop_limit) 86 87 88def parse(data: bytes) -> MeshFrame: 89 """Parse a frame received off a radio. 90 91 :param data: The frame exactly as it arrived. 92 :returns: The parsed frame. 93 :raises PamojaError: If the frame is truncated, of an unknown version, or 94 fails its checksum, which is what a noisy radio produces. 95 """ 96 return _parse_frame(bytes(data)) 97 98 99def relayed(data: bytes) -> MeshFrame | None: 100 """Return the same frame with one hop spent, ready to forward. 101 102 :param data: The frame exactly as it arrived. 103 :returns: The frame to forward, or ``None`` once its hops have run out, 104 which is what stops a flood from circulating forever. 105 :raises PamojaError: If the frame cannot be parsed. 106 """ 107 return _relayed(bytes(data)) 108 109 110def crc16(data: bytes) -> int: 111 """Compute the CRC-16 a frame carries. 112 113 :param data: The bytes the checksum covers. 114 :returns: The checksum. 115 """ 116 return _crc16(bytes(data))
BROADCAST =
4294967295
DEFAULT_HOP_LIMIT =
3
MAX_FRAME =
250
MAX_PAYLOAD =
236
HEADER_LEN =
12
SEEN_DEFAULT_CAPACITY =
64
class
MeshFrame:
A mesh packet: its addressing, its payload, and the bytes to transmit.
class
SeenPackets:
A memory of recently seen packets, so a node relays each one only once.
def
contains(self, /, src, id):
Reports whether a packet is currently remembered, without recording it.
def
broadcast( src: int, id: int, payload: bytes, hop_limit: int | None = None) -> MeshFrame:
73def broadcast( 74 src: int, id: int, payload: bytes, hop_limit: int | None = None 75) -> MeshFrame: 76 """Build a frame addressed to every node. 77 78 :param src: The address of this node. 79 :param id: The sequence number identifying this packet from this source. 80 :param payload: The bytes to carry. 81 :param hop_limit: How many relays the frame may take, defaulting to 82 :data:`DEFAULT_HOP_LIMIT`. 83 :returns: The frame, with the bytes to transmit on its ``bytes`` attribute. 84 :raises PamojaError: If the payload is larger than :data:`MAX_PAYLOAD`. 85 """ 86 return _broadcast_frame(src, id, bytes(payload), hop_limit)
Build a frame addressed to every node.
Parameters
- src: The address of this node.
- id: The sequence number identifying this packet from this source.
- payload: The bytes to carry.
- hop_limit: How many relays the frame may take, defaulting to
DEFAULT_HOP_LIMIT. :returns: The frame, with the bytes to transmit on itsbytesattribute.
Raises
- PamojaError: If the payload is larger than
MAX_PAYLOAD.
def
crc16(data: bytes) -> int:
111def crc16(data: bytes) -> int: 112 """Compute the CRC-16 a frame carries. 113 114 :param data: The bytes the checksum covers. 115 :returns: The checksum. 116 """ 117 return _crc16(bytes(data))
Compute the CRC-16 a frame carries.
Parameters
- data: The bytes the checksum covers. :returns: The checksum.
def
frame( src: int, dst: int, id: int, payload: bytes, hop_limit: int | None = None) -> MeshFrame:
52def frame( 53 src: int, 54 dst: int, 55 id: int, 56 payload: bytes, 57 hop_limit: int | None = None, 58) -> MeshFrame: 59 """Build a frame addressed to one node. 60 61 :param src: The address of this node. 62 :param dst: The address the frame is for, or :data:`BROADCAST`. 63 :param id: The sequence number identifying this packet from this source. 64 :param payload: The bytes to carry. 65 :param hop_limit: How many relays the frame may take, defaulting to 66 :data:`DEFAULT_HOP_LIMIT`. 67 :returns: The frame, with the bytes to transmit on its ``bytes`` attribute. 68 :raises PamojaError: If the payload is larger than :data:`MAX_PAYLOAD`. 69 """ 70 return _frame(src, dst, id, bytes(payload), hop_limit)
Build a frame addressed to one node.
Parameters
- src: The address of this node.
- dst: The address the frame is for, or
BROADCAST. - id: The sequence number identifying this packet from this source.
- payload: The bytes to carry.
- hop_limit: How many relays the frame may take, defaulting to
DEFAULT_HOP_LIMIT. :returns: The frame, with the bytes to transmit on itsbytesattribute.
Raises
- PamojaError: If the payload is larger than
MAX_PAYLOAD.
def
parse(data: bytes) -> MeshFrame:
89def parse(data: bytes) -> MeshFrame: 90 """Parse a frame received off a radio. 91 92 :param data: The frame exactly as it arrived. 93 :returns: The parsed frame. 94 :raises PamojaError: If the frame is truncated, of an unknown version, or 95 fails its checksum, which is what a noisy radio produces. 96 """ 97 return _parse_frame(bytes(data))
Parse a frame received off a radio.
Parameters
- data: The frame exactly as it arrived. :returns: The parsed frame.
Raises
- PamojaError: If the frame is truncated, of an unknown version, or fails its checksum, which is what a noisy radio produces.
def
relayed(data: bytes) -> MeshFrame | None:
100def relayed(data: bytes) -> MeshFrame | None: 101 """Return the same frame with one hop spent, ready to forward. 102 103 :param data: The frame exactly as it arrived. 104 :returns: The frame to forward, or ``None`` once its hops have run out, 105 which is what stops a flood from circulating forever. 106 :raises PamojaError: If the frame cannot be parsed. 107 """ 108 return _relayed(bytes(data))
Return the same frame with one hop spent, ready to forward.
Parameters
- data: The frame exactly as it arrived.
:returns: The frame to forward, or
Noneonce its hops have run out, which is what stops a flood from circulating forever.
Raises
- PamojaError: If the frame cannot be parsed.