Skip to content

Commit 95d5aa0

Browse files
committed
HDLCStream: add framing logic
1 parent afd3311 commit 95d5aa0

File tree

1 file changed

+48
-20
lines changed

1 file changed

+48
-20
lines changed

src/AudioTools/Sandbox/HDLCStream.h

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
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
@@ -20,21 +21,27 @@
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

2829
namespace 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

3643
class 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

Comments
 (0)