1 #include "AudioConfig.h"
2 #include "AudioTools/CoreAudio/Buffers.h"
8 #define FRAME_BOUNDARY_OCTET 0x7E
11 #define CONTROL_ESCAPE_OCTET 0x7D
15 #define INVERT_OCTET 0x20
20 #define CRC16_CCITT_INIT_VAL 0xFFFF
23 #define low(x) ((x)&0xFF)
24 #define high(x) (((x) >> 8) & 0xFF)
25 #define lo8(x) ((x)&0xff)
26 #define hi8(x) ((x) >> 8)
41 this->max_frame_length = max_frame_length;
48 this->max_frame_length = max_frame_length;
53 this->frame_position = 0;
54 this->frame_checksum = CRC16_CCITT_INIT_VAL;
55 this->escape_character =
false;
56 if (frame_buffer.size() == 0) {
57 frame_buffer.resize(max_frame_length + 1);
59 return p_out !=
nullptr || p_in !=
nullptr;
62 void end() { this->frame_buffer.resize(0); }
64 int availableForWrite()
override {
65 return p_out ==
nullptr ? 0 : DEFAULT_BUFFER_SIZE;
69 size_t write(
const uint8_t *data,
size_t len)
override {
70 LOGD(
"HDLCStream::write: %zu", len);
72 for (
int j = 0; j < len; j++) {
73 bool ok = frame_buffer.
write(data[j]);
75 if (frame_buffer.
available() == max_frame_length) {
76 sendFrame(frame_buffer.
data(), max_frame_length);
83 int available()
override {
84 return p_in ==
nullptr ? 0 : max_frame_length;
88 size_t readBytes(uint8_t *data,
size_t len)
override {
89 if (p_in ==
nullptr) {
90 LOGI(
"No data source");
97 int ch = p_in->read();
100 result = charReceiver(ch);
102 result = frame_buffer.
readArray(data, result);
109 LOGD(
"HDLCStream::readBytes: %zu -> %d", len, result);
114 void setStream(
Stream &io) {
119 void setStream(Print &out) { p_out = &out; }
121 void setOutput(Print &out) { p_out = &out; }
123 size_t write(uint8_t ch)
override {
return write(&ch, 1); };
125 int read()
override {
134 int peek()
override {
return -1; }
137 Print *p_out =
nullptr;
139 bool escape_character =
false;
141 uint8_t frame_position = 0;
143 uint16_t frame_checksum;
144 uint16_t max_frame_length;
147 int charReceiver(uint8_t data) {
149 uint8_t *frame_buffer_data = frame_buffer.
address();
150 LOGD(
"charReceiver: %c", data);
152 if (data == FRAME_BOUNDARY_OCTET) {
153 if (escape_character ==
true) {
154 escape_character =
false;
155 }
else if ((frame_position >= 2) &&
157 ((frame_buffer_data[frame_position - 1] << 8) |
158 (frame_buffer_data[frame_position - 2] & 0xff)))) {
162 LOGD(
"==> Result: %d", result);
165 frame_checksum = CRC16_CCITT_INIT_VAL;
169 if (escape_character) {
170 escape_character =
false;
171 data ^= INVERT_OCTET;
172 }
else if (data == CONTROL_ESCAPE_OCTET) {
173 escape_character =
true;
177 frame_buffer_data[frame_position] = data;
179 if (frame_position - 2 >= 0) {
180 frame_checksum = _crc_ccitt_update(frame_checksum,
181 frame_buffer_data[frame_position - 2]);
186 if (frame_position == max_frame_length) {
188 frame_checksum = CRC16_CCITT_INIT_VAL;
194 void sendFrame(
const uint8_t *framebuffer,
size_t frame_length) {
195 LOGD(
"HDLCStream::sendFrame: %zu", frame_length);
197 uint16_t fcs = CRC16_CCITT_INIT_VAL;
199 p_out->write((uint8_t)FRAME_BOUNDARY_OCTET);
201 while (frame_length) {
202 data = *framebuffer++;
203 fcs = HDLCStream::_crc_ccitt_update(fcs, data);
204 if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) {
205 p_out->write((uint8_t)CONTROL_ESCAPE_OCTET);
206 data ^= INVERT_OCTET;
208 p_out->write((uint8_t)data);
212 if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) {
213 p_out->write((uint8_t)CONTROL_ESCAPE_OCTET);
214 data ^= (uint8_t)INVERT_OCTET;
216 p_out->write((uint8_t)data);
218 if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) {
219 p_out->write(CONTROL_ESCAPE_OCTET);
220 data ^= INVERT_OCTET;
223 p_out->write(FRAME_BOUNDARY_OCTET);
227 static uint16_t crc16_update(uint16_t crc, uint8_t a) {
230 for (i = 0; i < 8; ++i) {
232 crc = (crc >> 1) ^ 0xA001;
239 static uint16_t crc_xmodem_update(uint16_t crc, uint8_t data) {
242 crc = crc ^ ((uint16_t)data << 8);
243 for (i = 0; i < 8; i++) {
245 crc = (crc << 1) ^ 0x1021;
253 static uint16_t _crc_ccitt_update(uint16_t crc, uint8_t data) {
256 return ((((uint16_t)data << 8) | hi8(crc)) ^ (uint8_t)(data >> 4) ^
257 ((uint16_t)data << 3));
260 static uint8_t _crc_ibutton_update(uint8_t crc, uint8_t data) {
263 for (i = 0; i < 8; i++) {
265 crc = (crc >> 1) ^ 0x8C;