Open embedded specification
Portable Frame Protocol
Carry complete messages across constrained links and routed device networks with one small, predictable frame format.
- Status
- Stable
- Wire version
- 1
- Specification
- 1.0.0
- Licence
- MIT
64 bytes
A fixed frame size for constrained links and implementations with known resource limits.
Any payload
Application messages remain opaque, so PFP does not dictate a serialisation format.
Any link
Link profiles can carry complete frames over USB, CAN, Bluetooth, IP, or another transport.
Routed
Session addressing, gateways, discovery, and hop limits support bounded device topologies.
PFP moves complete messages across small links and through gateways while keeping resource use bounded. It defines how data is framed and routed. It does not define what the application puts inside each message.
This separation lets a product keep its existing application protocol, choose links that suit the hardware, and implement PFP in its existing language and architecture.
A small, predictable frame
Every PFP wire-version 1 frame is exactly 64 bytes. Twenty bytes describe the session, route, message, fragment, and priority. Forty bytes carry payload. The final four bytes contain a CRC-32/ISO-HDLC integrity check over everything that precedes them.
A fixed frame makes capacity and buffering easier to plan. Receivers can validate a complete frame before allocating reassembly state. Gateways can forward valid frames without decoding the application payload.
Complete messages over constrained links
One upper-layer message may contain from 1 to 10,200 bytes. PFP splits it into as many as 255 frames, numbers every fragment, and carries the exact original message length. A receiver can accept fragments out of order, ignore identical duplicates, reject conflicting data, and publish only a completely reassembled message.
The following is illustrative pseudocode, not a PFP or Corelib API:
message = application.encode(value)
frames = pfp.fragment(message, destination)
for frame in frames:
link.send(frame)
frame = link.receive()
if pfp.validate(frame):
complete_message = pfp.accept(frame)
if complete_message is ready:
application.handle(complete_message)
PFP does not acknowledge or retransmit missing frames. A link profile, an upper-layer protocol, or the surrounding system supplies reliability when it is required.
One session, from a direct device to a routed topology
A PFP session has one root. The root creates the session and assigns temporary addresses. A directly attached node can also act as a gateway. It discovers downstream links and forwards frames to them within defined limits. Persistent UUIDs identify devices independently of their session address.
Hop limits keep forwarding bounded. Session identifiers isolate stale traffic, while discovery and control messages allow the root to maintain the authoritative topology. A simple two-node connection uses the same framing and session rules without needing a larger routed network.
A focused contract
| PFP defines | Another layer defines |
|---|---|
| Fixed 64-byte frame encoding | Application request and response semantics |
| Fragmentation and exact reassembly | Payload serialisation |
| Session-scoped node addresses | Persistent product identity beyond UUIDs |
| Gateway discovery and bounded routing | Link-specific bootstrap and transport details |
| Per-frame CRC integrity checking | Delivery acknowledgements and retransmission |
| Validation and resource-bounded behaviour | Authentication, confidentiality, and hostile-link protection |
This boundary keeps PFP small enough for constrained devices. Other layers can then handle the concerns that sit outside framing and routing.
Corelib is one implementation
Corelib implements PFP wire version 1 for portable C11 projects and includes an optional fixed-storage C++14 facade. It provides a practical way to build a PFP-compatible device for Programmor. Corelib’s APIs, storage model, and upper-layer transaction protocol are not part of PFP.
Other implementations can conform to the same specification without using Corelib.
The repository is the specification
This page introduces PFP but does not replace the normative protocol text. PFP releases use semantic versioning, and tagged specification releases are frozen. Read the PFP v1.0.0 specification for complete requirements, field definitions, validation rules, and topology behaviour. Proposed changes and later releases are managed in the PFP repository.