hdlc: Simplify + Fix HDLC implementation
* remove the notion of states, as there is really only one state * implement zero removal / bit stuffing for synchronous links
This commit is contained in:
parent
90fb785804
commit
6daa71dbd2
71
src/hdlc.c
71
src/hdlc.c
|
@ -18,27 +18,27 @@
|
||||||
#define DEBUGP(x, args ...) do {} while (0)
|
#define DEBUGP(x, args ...) do {} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const ubit_t five_ones[] = { 1,1,1,1,1 };
|
static const ubit_t flag_octet[] = { 0,1,1,1,1,1,1,0 };
|
||||||
|
static const ubit_t five_ones_zero[] = { 0,1,1,1,1,1 };
|
||||||
|
|
||||||
static int append_bit(struct hdlc_proc *hdlc, uint8_t bit, int ignore)
|
static void append_bit_history(struct hdlc_proc *hdlc, uint8_t bit)
|
||||||
{
|
{
|
||||||
/* we always add the bit to the history */
|
/* we always add the bit to the history */
|
||||||
memmove(hdlc->history+1, hdlc->history, sizeof(hdlc->history)-1);
|
memmove(hdlc->history+1, hdlc->history, sizeof(hdlc->history)-1);
|
||||||
hdlc->history[0] = bit;
|
hdlc->history[0] = bit;
|
||||||
|
}
|
||||||
|
|
||||||
/* if it is a to-be-discarded bit, we bail out */
|
static int append_bit_out(struct hdlc_proc *hdlc, uint8_t bit)
|
||||||
if (ignore)
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
memmove(hdlc->next_outbyte+1, hdlc->next_outbyte, sizeof(hdlc->next_outbyte)-1);
|
memmove(hdlc->next_outbyte+1, hdlc->next_outbyte, sizeof(hdlc->next_outbyte)-1);
|
||||||
hdlc->next_outbyte[0] = bit;
|
hdlc->next_outbyte[0] = bit;
|
||||||
hdlc->num_bits++;
|
hdlc->num_bits++;
|
||||||
|
|
||||||
if (hdlc->num_bits == 8) {
|
if (hdlc->num_bits == 8) {
|
||||||
|
hdlc->num_bits = 0;
|
||||||
pbit_t out;
|
pbit_t out;
|
||||||
/* generate one output byte */
|
/* generate one output byte */
|
||||||
osmo_ubit2pbit_ext(&out, 0, hdlc->next_outbyte, 0, 8, 0);
|
osmo_ubit2pbit_ext(&out, 0, hdlc->next_outbyte, 0, 8, 0);
|
||||||
hdlc->num_bits = 0;
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,50 +47,27 @@ static int append_bit(struct hdlc_proc *hdlc, uint8_t bit, int ignore)
|
||||||
|
|
||||||
static int process_hdlc_bit(struct hdlc_proc *hdlc, uint8_t bit)
|
static int process_hdlc_bit(struct hdlc_proc *hdlc, uint8_t bit)
|
||||||
{
|
{
|
||||||
int ignore = 0;
|
int out = -1, flag = 0;
|
||||||
int out, flag = 0;
|
|
||||||
|
|
||||||
DEBUGP("bit=%u, history_in = %s, ", bit, osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
|
DEBUGP("bit=%u, history_in = %s, ", bit, osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
|
||||||
|
|
||||||
switch (hdlc->state) {
|
/* always append bit to history */
|
||||||
case STATE_FLAG_WAIT_ZERO:
|
append_bit_history(hdlc, bit);
|
||||||
/* we've received 6 consecutive '1' just before and are
|
|
||||||
* waiting for the final '0' to end the flag character */
|
if (!memcmp(flag_octet, hdlc->history, sizeof(flag_octet))) {
|
||||||
if (bit == 0) {
|
|
||||||
/* it was a zero, flag character detected */
|
|
||||||
DEBUGP("F ");
|
|
||||||
flag = 1;
|
|
||||||
/* we're now inside the payload state */
|
|
||||||
hdlc->state = STATE_PAYLOAD;
|
|
||||||
} else {
|
|
||||||
/* if we received yet another '1', we re-start
|
|
||||||
* from the beginning */
|
|
||||||
hdlc->state = STATE_INIT;
|
|
||||||
}
|
|
||||||
ignore = 1;
|
|
||||||
hdlc->num_bits = 0;
|
hdlc->num_bits = 0;
|
||||||
break;
|
DEBUGP("S ");
|
||||||
case STATE_PAYLOAD:
|
flag = 1;
|
||||||
case STATE_INIT:
|
} else if (!memcmp(five_ones_zero, hdlc->history, sizeof(five_ones_zero))) {
|
||||||
if (!memcmp(five_ones, hdlc->history, sizeof(five_ones))) {
|
/* 4.3.1 Synchronous transmission: receiver shall
|
||||||
/* five consecutive ones in the history */
|
* discard any "0" bit after five contiguous ones */
|
||||||
if (bit == 1) {
|
DEBUGP("I ");
|
||||||
/* one more '1' was received -> we wait
|
} else {
|
||||||
* for a zero at the end of the flag
|
out = append_bit_out(hdlc, bit);
|
||||||
* character 0x7E */
|
|
||||||
hdlc->state = STATE_FLAG_WAIT_ZERO;
|
|
||||||
/* discard bit */
|
|
||||||
ignore = 1;
|
|
||||||
} else {
|
|
||||||
/* discard bit */
|
|
||||||
ignore = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
out = append_bit(hdlc, bit, ignore);
|
|
||||||
DEBUGP("history_out = %s", osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
|
DEBUGP("history_out = %s", osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
|
||||||
if (out > 0)
|
if (out >= 0)
|
||||||
DEBUGP(", out 0x%02x\n", out);
|
DEBUGP(", out 0x%02x\n", out);
|
||||||
else
|
else
|
||||||
DEBUGP("\n");
|
DEBUGP("\n");
|
||||||
|
@ -107,6 +84,8 @@ int process_raw_hdlc(struct hdlc_proc *hdlc, uint8_t *data, unsigned int len)
|
||||||
int out;
|
int out;
|
||||||
static int last_out;
|
static int last_out;
|
||||||
|
|
||||||
|
DEBUGP("process_raw_hdlc(%s)\n", osmo_hexdump(data,len));
|
||||||
|
|
||||||
for (i = 0; i < len; i ++) {
|
for (i = 0; i < len; i ++) {
|
||||||
out = process_hdlc_bit(hdlc, data[i]);
|
out = process_hdlc_bit(hdlc, data[i]);
|
||||||
if (out == -123) {
|
if (out == -123) {
|
||||||
|
@ -116,7 +95,7 @@ int process_raw_hdlc(struct hdlc_proc *hdlc, uint8_t *data, unsigned int len)
|
||||||
last_out = out;
|
last_out = out;
|
||||||
} else if (out >= 0) {
|
} else if (out >= 0) {
|
||||||
/* suppress 0xAA and 0x55 bit pattern */
|
/* suppress 0xAA and 0x55 bit pattern */
|
||||||
if (out != 0xaa && out != 0x55)
|
//if (out != 0xaa && out != 0x55)
|
||||||
printf("%02x ", out);
|
printf("%02x ", out);
|
||||||
last_out = out;
|
last_out = out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,9 @@
|
||||||
|
|
||||||
#include <osmocom/core/bits.h>
|
#include <osmocom/core/bits.h>
|
||||||
|
|
||||||
enum hdlc_proc_state {
|
|
||||||
STATE_INIT,
|
|
||||||
STATE_FLAG_WAIT_ZERO,
|
|
||||||
STATE_PAYLOAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hdlc_proc {
|
struct hdlc_proc {
|
||||||
ubit_t history[8];
|
ubit_t history[8];
|
||||||
ubit_t next_outbyte[8];
|
ubit_t next_outbyte[8];
|
||||||
enum hdlc_proc_state state;
|
|
||||||
uint8_t num_bits;
|
uint8_t num_bits;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue