diff --git a/src/hdlc.c b/src/hdlc.c index 0a53a27..19ba900 100644 --- a/src/hdlc.c +++ b/src/hdlc.c @@ -18,27 +18,27 @@ #define DEBUGP(x, args ...) do {} while (0) #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 */ memmove(hdlc->history+1, hdlc->history, sizeof(hdlc->history)-1); hdlc->history[0] = bit; +} - /* if it is a to-be-discarded bit, we bail out */ - if (ignore) - return -1; - +static int append_bit_out(struct hdlc_proc *hdlc, uint8_t bit) +{ memmove(hdlc->next_outbyte+1, hdlc->next_outbyte, sizeof(hdlc->next_outbyte)-1); hdlc->next_outbyte[0] = bit; hdlc->num_bits++; if (hdlc->num_bits == 8) { + hdlc->num_bits = 0; pbit_t out; /* generate one output byte */ osmo_ubit2pbit_ext(&out, 0, hdlc->next_outbyte, 0, 8, 0); - hdlc->num_bits = 0; 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) { - int ignore = 0; - int out, flag = 0; + int out = -1, flag = 0; DEBUGP("bit=%u, history_in = %s, ", bit, osmo_ubit_dump(hdlc->history, sizeof(hdlc->history))); - switch (hdlc->state) { - case STATE_FLAG_WAIT_ZERO: - /* we've received 6 consecutive '1' just before and are - * waiting for the final '0' to end the flag character */ - 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; + /* always append bit to history */ + append_bit_history(hdlc, bit); + + if (!memcmp(flag_octet, hdlc->history, sizeof(flag_octet))) { hdlc->num_bits = 0; - break; - case STATE_PAYLOAD: - case STATE_INIT: - if (!memcmp(five_ones, hdlc->history, sizeof(five_ones))) { - /* five consecutive ones in the history */ - if (bit == 1) { - /* one more '1' was received -> we wait - * for a zero at the end of the flag - * character 0x7E */ - hdlc->state = STATE_FLAG_WAIT_ZERO; - /* discard bit */ - ignore = 1; - } else { - /* discard bit */ - ignore = 1; - } - } - break; + DEBUGP("S "); + flag = 1; + } else if (!memcmp(five_ones_zero, hdlc->history, sizeof(five_ones_zero))) { + /* 4.3.1 Synchronous transmission: receiver shall + * discard any "0" bit after five contiguous ones */ + DEBUGP("I "); + } else { + out = append_bit_out(hdlc, bit); } - out = append_bit(hdlc, bit, ignore); + DEBUGP("history_out = %s", osmo_ubit_dump(hdlc->history, sizeof(hdlc->history))); - if (out > 0) + if (out >= 0) DEBUGP(", out 0x%02x\n", out); else DEBUGP("\n"); @@ -107,6 +84,8 @@ int process_raw_hdlc(struct hdlc_proc *hdlc, uint8_t *data, unsigned int len) int out; static int last_out; + DEBUGP("process_raw_hdlc(%s)\n", osmo_hexdump(data,len)); + for (i = 0; i < len; i ++) { out = process_hdlc_bit(hdlc, data[i]); if (out == -123) { @@ -116,7 +95,7 @@ int process_raw_hdlc(struct hdlc_proc *hdlc, uint8_t *data, unsigned int len) last_out = out; } else if (out >= 0) { /* suppress 0xAA and 0x55 bit pattern */ - if (out != 0xaa && out != 0x55) + //if (out != 0xaa && out != 0x55) printf("%02x ", out); last_out = out; } diff --git a/src/hdlc.h b/src/hdlc.h index 10ec8e2..2d44e75 100644 --- a/src/hdlc.h +++ b/src/hdlc.h @@ -2,16 +2,9 @@ #include -enum hdlc_proc_state { - STATE_INIT, - STATE_FLAG_WAIT_ZERO, - STATE_PAYLOAD, -}; - struct hdlc_proc { ubit_t history[8]; ubit_t next_outbyte[8]; - enum hdlc_proc_state state; uint8_t num_bits; };