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