26#define HDLC_BITS_PER_BYTE 8U
27#define HDLC_SYNC_MIN_FRAME_SIZE_BYTES 4U
28#define HDLC_SYNC_MAX_REASONABLE_FRAME_SIZE_BYTES 2048U
29#define HDLC_SYNC_SHORT_BUFFER_SEARCH_LIMIT 64U
72 if (!accumulator || drop_count == 0)
77 if (drop_count >= accumulator->
position)
85 size_t remaining = accumulator->
position - drop_count;
86 memmove(accumulator->
buffer, accumulator->
buffer + drop_count, remaining);
111 if (!accumulator || !out_frame || !scan_index)
137 uint8_t bit_offset,
bool shift_right, uint8_t* out_byte)
139 if (!accumulator || !out_byte || raw_index >= accumulator->
position ||
147 *out_byte = accumulator->
buffer[raw_index];
151 if ((raw_index + 1) >= accumulator->
position)
158 *out_byte = (uint8_t)((uint8_t)(accumulator->
buffer[raw_index] >> bit_offset) |
159 (uint8_t)(accumulator->
buffer[raw_index + 1] <<
164 *out_byte = (uint8_t)((uint8_t)(accumulator->
buffer[raw_index] << bit_offset) |
165 (uint8_t)(accumulator->
buffer[raw_index + 1] >>
178 size_t scan_index,
bool allow_left_shift,
179 size_t* out_start_index, uint8_t* out_bit_pos,
180 bool* out_shift_right)
182 if (!accumulator || !out_start_index || !out_bit_pos || !out_shift_right ||
189 size_t start = (scan_index > 0) ? (scan_index - 1) : 0;
190 if (start >= (accumulator->
position - 1))
196 for (; start < (accumulator->
position - 1); ++start)
202 *out_start_index = start;
204 *out_shift_right =
false;
214 *out_start_index = start;
215 *out_bit_pos = bit_pos;
216 *out_shift_right =
true;
221 if (allow_left_shift)
228 *out_start_index = start;
229 *out_bit_pos = bit_pos;
230 *out_shift_right =
false;
249 size_t scan_index,
size_t* out_start_index,
250 uint8_t* out_bit_pos,
bool* out_shift_right)
252 if (!accumulator || !out_start_index || !out_bit_pos || !out_shift_right ||
261 size_t start = (scan_index > 0) ? (scan_index - 1) : 0;
262 if (start >= (accumulator->
position - 1))
267 bool found_best =
false;
268 size_t best_start = 0;
269 uint8_t best_bit_pos = 0;
270 bool best_shift =
false;
271 size_t best_frame_size = 0;
272 uint8_t start_byte = 0;
273 uint8_t probe_byte = 0;
275 for (; start < (accumulator->
position - 1); ++start)
281 for (uint8_t mode = 0; mode < 2; ++mode)
283 bool shift_right = (mode != 0);
284 if (bit_pos == 0 && shift_right)
299 size_t frame_size = 1;
300 for (
size_t probe = start + 1; probe < accumulator->
position; ++probe)
309 if (probe_byte == accumulator->
sync_byte &&
313 if (!found_best || frame_size > best_frame_size)
318 best_bit_pos = bit_pos;
319 best_shift = shift_right;
320 best_frame_size = frame_size;
335 *out_start_index = best_start;
336 *out_bit_pos = best_bit_pos;
337 *out_shift_right = best_shift;
347 size_t start_index = 0;
348 uint8_t found_bit_pos = 0;
349 bool found_shift_dir =
false;
352 accumulator, *scan_index, &start_index, &found_bit_pos, &found_shift_dir);
357 &found_bit_pos, &found_shift_dir);
363 *scan_index = accumulator->
position;
374 *scan_index = start_index + 1;
551 if (!accumulator || !out_frame || !out_frame->
payload || out_frame->
capacity == 0)
569 size_t scan_index = accumulator->
processed;
570 while (scan_index < accumulator->position)
575 switch (accumulator->
state)
656 drop = accumulator->
position - keep;
e2s_error_t
Common error codes returned by ether2ser modules.
@ E2S_ERR_HDLC_ACC_FRAME_READY
@ E2S_ERR_HDLC_DECODE_PAYLOAD_TOO_LONG
void hdlc_sync_acc_consume_candidate(HDLC_SYNC_ACCUMULATOR_T *accumulator, bool accept)
Consume current candidate and advance accumulator window.
static bool hdlc_sync_get_aligned_byte(const HDLC_SYNC_ACCUMULATOR_T *accumulator, size_t raw_index, uint8_t bit_offset, bool shift_right, uint8_t *out_byte)
static bool hdlc_sync_find_complete_candidate_short(const HDLC_SYNC_ACCUMULATOR_T *accumulator, size_t scan_index, size_t *out_start_index, uint8_t *out_bit_pos, bool *out_shift_right)
static HDLC_SYNC_POLL_STEP_RESULT_T hdlc_sync_step_syncing(HDLC_SYNC_ACCUMULATOR_T *accumulator, HDLC_FRAME_T *out_frame, size_t *scan_index, e2s_error_t *out_error)
static HDLC_SYNC_POLL_STEP_RESULT_T hdlc_sync_step_synced(HDLC_SYNC_ACCUMULATOR_T *accumulator, HDLC_FRAME_T *out_frame, size_t *scan_index, e2s_error_t *out_error)
static void hdlc_sync_reject_oversized_candidate(HDLC_SYNC_ACCUMULATOR_T *accumulator, HDLC_FRAME_T *out_frame, size_t *scan_index)
#define HDLC_SYNC_SHORT_BUFFER_SEARCH_LIMIT
static bool hdlc_sync_find_opening_candidate(const HDLC_SYNC_ACCUMULATOR_T *accumulator, size_t scan_index, bool allow_left_shift, size_t *out_start_index, uint8_t *out_bit_pos, bool *out_shift_right)
void hdlc_sync_acc_init(HDLC_SYNC_ACCUMULATOR_T *accumulator, uint8_t sync_byte)
Initialize HDLC sync accumulator state.
#define HDLC_BITS_PER_BYTE
#define HDLC_SYNC_MAX_REASONABLE_FRAME_SIZE_BYTES
HDLC_SYNC_POLL_STEP_RESULT_T
@ HDLC_SYNC_POLL_STEP_STOP
@ HDLC_SYNC_POLL_STEP_FRAME_READY
@ HDLC_SYNC_POLL_STEP_ERROR
@ HDLC_SYNC_POLL_STEP_PROGRESS
static void hdlc_sync_finalize_poll_no_frame(HDLC_SYNC_ACCUMULATOR_T *accumulator, size_t scan_index)
static void hdlc_sync_reset_hunting_state(HDLC_SYNC_ACCUMULATOR_T *accumulator)
static HDLC_SYNC_POLL_STEP_RESULT_T hdlc_sync_step_hunting(HDLC_SYNC_ACCUMULATOR_T *accumulator, HDLC_FRAME_T *out_frame, size_t *scan_index)
static void hdlc_sync_drop_prefix(HDLC_SYNC_ACCUMULATOR_T *accumulator, size_t drop_count)
e2s_error_t hdlc_sync_acc_poll(HDLC_SYNC_ACCUMULATOR_T *accumulator, HDLC_FRAME_T *out_frame)
Poll accumulator for an aligned HDLC frame candidate.
#define HDLC_SYNC_MIN_FRAME_SIZE_BYTES
bool hdlc_sync_acc_process_byte(HDLC_SYNC_ACCUMULATOR_T *accumulator, uint8_t byte)
Append one received raw byte to the accumulator.
#define RX_HDLC_SYNC_MAX_BUFFER_SIZE
Maximum raw RX bytes retained in the HDLC sync accumulator.
@ HDLC_SYNC_STATE_HUNTING
@ HDLC_SYNC_STATE_SYNCING
Generic HDLC frame buffer descriptor.
Accumulator and state for HDLC bit-offset synchronization.
uint32_t lookahead_wait_synced
uint32_t frame_ready_count
uint32_t hardcap_drop_bytes
uint8_t buffer[RX_HDLC_SYNC_MAX_BUFFER_SIZE]
uint32_t lookahead_wait_syncing
uint32_t hardcap_drop_events