xref: /aosp_15_r20/external/pigweed/pw_hdlc/design.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_hdlc-design:
2
3================
4Design & roadmap
5================
6.. pigweed-module-subpage::
7   :name: pw_hdlc
8
9.. pw_hdlc-overview-start
10
11``pw_hdlc`` implements a subset of the `High-Level Data Link Control
12<https://en.wikipedia.org/wiki/High-Level_Data_Link_Control>`_ (HDLC) protocol.
13HDLC is a data link layer protocol intended for serial communication between
14devices and is standardized as `ISO/IEC 13239:2002
15<https://www.iso.org/standard/37010.html>`_.
16
17.. pw_hdlc-overview-end
18
19--------
20Overview
21--------
22The ``pw_hdlc`` module provides a simple, robust frame-oriented transport that
23uses a subset of the HDLC protocol. ``pw_hdlc`` supports sending between
24embedded devices or the host. It can be used with :ref:`module-pw_rpc` to enable
25remote procedure calls (RPCs) on embedded devices.
26
27``pw_hdlc`` has two primary functions:
28
29* **Encoding** data by constructing a frame with the escaped payload bytes and
30  frame check sequence.
31* **Decoding** data by unescaping the received bytes, verifying the frame
32  check sequence, and returning successfully decoded frames.
33
34Design considerations
35=====================
36* ``pw_hdlc`` only supports unnumbered information frames.
37* It uses special escaped bytes to mark the beginning and end of a frame.
38* Frame data is stored in a buffer until the end-of-frame delimiter byte is read.
39
40--------------------
41Protocol Description
42--------------------
43
44Frames
45======
46The HDLC implementation in ``pw_hdlc`` supports only HDLC unnumbered
47information frames. These frames are encoded as follows:
48
49.. code-block:: text
50
51   _________________________________________
52   | | | |                          |    | |...
53   | | | |                          |    | |... [More frames]
54   |_|_|_|__________________________|____|_|...
55    F A C       Payload              FCS  F
56
57    F = flag byte (0x7e, the ~ character)
58    A = address field
59    C = control field
60    FCS = frame check sequence (CRC-32)
61
62
63Encoding and sending data
64=========================
65This module first writes an initial frame delimiter byte (``0x7E``) to indicate
66the beginning of the frame. Before sending any of the payload data through
67serial, the special bytes are escaped:
68
69+-------------------------+-----------------------+
70| Unescaped Special Bytes | Escaped Special Bytes |
71+=========================+=======================+
72|         ``7E``          |      ``7D 5E``        |
73+-------------------------+-----------------------+
74|         ``7D``          |      ``7D 5D``        |
75+-------------------------+-----------------------+
76
77The bytes of the payload are escaped and written in a single pass. The
78frame check sequence is calculated, escaped, and written after. After this, a
79final frame delimiter byte (``0x7E``) is written to mark the end of the frame.
80
81Decoding received bytes
82=======================
83Frames may be received in multiple parts, so ``pw_hdlc`` needs to store the
84received data in a buffer until the ending frame delimiter (``0x7E``) is read.
85When the ``pw_hdlc`` decoder receives data, it unescapes it and adds it to a
86buffer. When the frame is complete, it calculates and verifies the frame check
87sequence and does the following:
88
89* If correctly verified, the decoder returns the decoded frame.
90* If the checksum verification fails, the frame is discarded and an error is
91  reported.
92
93-------
94Roadmap
95-------
96- **Expanded protocol support** - ``pw_hdlc`` currently only supports
97  unnumbered information frames. Support for different frame types and
98  extended control fields may be added in the future.
99
100-----------------
101More pw_hdlc docs
102-----------------
103.. include:: docs.rst
104   :start-after: .. pw_hdlc-nav-start
105   :end-before: .. pw_hdlc-nav-end
106