aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-11-14 21:26:11 +0100
committerHarald Welte <laforge@gnumonks.org>2016-11-14 21:26:11 +0100
commit6daa71dbd2898ee4afad984eff79c30ce171d0d6 (patch)
tree0dc664728bdfec64b546530dedfbade125143fb0 /src
parent90fb78580423c18dc03ef5cad9c2ce607ad90760 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/hdlc.c71
-rw-r--r--src/hdlc.h7
2 files changed, 25 insertions, 53 deletions
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 <osmocom/core/bits.h>
-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;
};