1- #include " AudioToolsConfig.h"
2- #include " AudioTools/CoreAudio/Buffers.h"
31#include < stdbool.h>
42#include < stdint.h>
53
4+ #include " AudioTools/CoreAudio/Buffers.h"
5+ #include " AudioToolsConfig.h"
6+
67// / HDLC Asynchronous framing: The frame boundary octet is 01111110, (7E in
78// / hexadecimal notation)
89#define FRAME_BOUNDARY_OCTET 0x7E
2021#define CRC16_CCITT_INIT_VAL 0xFFFF
2122
2223// / 16bit low and high bytes copier
23- #define low (x ) ((x)& 0xFF )
24+ #define low (x ) ((x) & 0xFF )
2425#define high (x ) (((x) >> 8 ) & 0xFF )
25- #define lo8 (x ) ((x)& 0xff )
26+ #define lo8 (x ) ((x) & 0xff )
2627#define hi8 (x ) ((x) >> 8 )
2728
2829namespace audio_tools {
2930
31+ enum class HDLCWriteLogic { OnBufferFull, OnFlush, onWrite };
32+
3033/* *
3134 * @brief High-Level Data Link Control (HDLC) is a bit-oriented code-transparent
32- * synchronous data link layer protocol
35+ * synchronous data link layer protocol in scenarios where you need reliable,
36+ * framed, and error-checked communication between devices at the data link
37+ * layer.
38+ *
3339 * @ingroup communications
40+ * @author Phil Schatzmann
3441 */
3542
3643class HDLCStream : public Stream {
37- public:
44+ public:
3845 // / Defines the output for the hdlc encoding
3946 HDLCStream (Print &out, uint16_t max_frame_length) {
4047 setOutput (out);
@@ -69,21 +76,38 @@ class HDLCStream : public Stream {
6976 size_t write (const uint8_t *data, size_t len) override {
7077 LOGD (" HDLCStream::write: %zu" , len);
7178
72- for (int j = 0 ; j < len; j++) {
73- bool ok = frame_buffer.write (data[j]);
74- assert (ok);
75- if (frame_buffer.available () == max_frame_length) {
76- sendFrame (frame_buffer.data (), max_frame_length);
77- frame_buffer.reset ();
78- }
79+ switch (write_logic) {
80+ case HDLCWriteLogic::OnBufferFull:
81+ for (int j = 0 ; j < len; j++) {
82+ bool ok = frame_buffer.write (data[j]);
83+ assert (ok);
84+ if (frame_buffer.available () == max_frame_length) {
85+ sendFrame (frame_buffer.data (), max_frame_length);
86+ frame_buffer.reset ();
87+ }
88+ }
89+ break ;
90+ case HDLCWriteLogic::onWrite:
91+ sendFrame (data, len);
92+ break ;
7993 }
94+
8095 return len;
8196 }
8297
83- int available () override {
84- return p_in == nullptr ? 0 : max_frame_length;
98+ void flush () override {
99+ LOGD (" HDLCStream::flush" );
100+ if (frame_buffer.available () > 0 ) {
101+ sendFrame (frame_buffer.data (), frame_buffer.available ());
102+ frame_buffer.reset ();
103+ }
104+ if (p_out != nullptr ) {
105+ p_out->flush ();
106+ }
85107 }
86108
109+ int available () override { return p_in == nullptr ? 0 : max_frame_length; }
110+
87111 // / Provides the decoded data
88112 size_t readBytes (uint8_t *data, size_t len) override {
89113 if (p_in == nullptr ) {
@@ -96,7 +120,7 @@ class HDLCStream : public Stream {
96120 while (result == 0 ) {
97121 int ch = p_in->read ();
98122 // ch is -1 when no data
99- if (ch >= 0 ){
123+ if (ch >= 0 ) {
100124 result = charReceiver (ch);
101125 if (result > 0 ) {
102126 result = frame_buffer.readArray (data, result);
@@ -108,7 +132,6 @@ class HDLCStream : public Stream {
108132 }
109133 LOGD (" HDLCStream::readBytes: %zu -> %d" , len, result);
110134 return result;
111- ;
112135 }
113136
114137 void setStream (Stream &io) {
@@ -133,7 +156,10 @@ class HDLCStream : public Stream {
133156 // / not supported
134157 int peek () override { return -1 ; }
135158
136- private:
159+ // / Defines the framing logic for writing data
160+ void setWriteLogic (HDLCWriteLogic logic) { write_logic = logic; }
161+
162+ private:
137163 Print *p_out = nullptr ;
138164 Stream *p_in = nullptr ;
139165 bool escape_character = false ;
@@ -142,8 +168,10 @@ class HDLCStream : public Stream {
142168 // 16bit CRC sum for _crc_ccitt_update
143169 uint16_t frame_checksum;
144170 uint16_t max_frame_length;
171+ HDLCWriteLogic write_logic = HDLCWriteLogic::OnBufferFull;
145172
146- // / Function to find valid HDLC frame from incoming data: returns the available result bytes in the buffer
173+ // / Function to find valid HDLC frame from incoming data: returns the
174+ // / available result bytes in the buffer
147175 int charReceiver (uint8_t data) {
148176 int result = 0 ;
149177 uint8_t *frame_buffer_data = frame_buffer.address ();
@@ -270,4 +298,4 @@ class HDLCStream : public Stream {
270298 }
271299};
272300
273- } // namespace audio_tools
301+ } // namespace audio_tools
0 commit comments