aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-10-26 09:38:24 +0200
committerHarald Welte <laforge@gnumonks.org>2016-10-26 09:38:24 +0200
commitd83c51379b52d3bd94db57de046ba674377b4386 (patch)
tree2a494c8469fbfbeceb6f1479d92e5c9098c39439
parent59b94d061172bf683eb4edc4e67a64f9760e33ba (diff)
WIP: More work on SuperChannel decode, but it doesn't work yet...
-rw-r--r--src/flip_bits.c29
-rw-r--r--src/flip_bits.h4
-rw-r--r--src/hdlc.c111
-rw-r--r--src/hdlc.h18
4 files changed, 162 insertions, 0 deletions
diff --git a/src/flip_bits.c b/src/flip_bits.c
new file mode 100644
index 0000000..f33994e
--- /dev/null
+++ b/src/flip_bits.c
@@ -0,0 +1,29 @@
+#include <stdint.h>
+#include "flip_bits.h"
+
+static uint8_t flip_table[256];
+
+void init_flip_bits(void)
+{
+ int i,k;
+
+ for (i = 0 ; i < 256 ; i++) {
+ uint8_t sample = 0 ;
+ for (k = 0; k<8; k++) {
+ if ( i & 1 << k ) sample |= 0x80 >> k;
+ }
+ flip_table[i] = sample;
+ }
+}
+
+uint8_t *flip_buf_bits(uint8_t *buf, int len)
+{
+ int i;
+ uint8_t *start = buf;
+
+ for (i = 0 ; i < len; i++) {
+ buf[i] = flip_table[(uint8_t)buf[i]];
+ }
+
+ return start;
+}
diff --git a/src/flip_bits.h b/src/flip_bits.h
new file mode 100644
index 0000000..319a181
--- /dev/null
+++ b/src/flip_bits.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void init_flip_bits(void);
+uint8_t *flip_buf_bits(uint8_t * buf , int len);
diff --git a/src/hdlc.c b/src/hdlc.c
new file mode 100644
index 0000000..1768dfd
--- /dev/null
+++ b/src/hdlc.c
@@ -0,0 +1,111 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/bits.h>
+
+#include "hdlc.h"
+
+#if 0
+#define DEBUGP(x, args ...) fprintf(stderr, x, ## args)
+#else
+#define DEBUGP(x, args ...) do {} while (0)
+#endif
+
+static const ubit_t five_ones[] = { 1,1,1,1,1 };
+
+static int append_bit(struct hdlc_proc *hdlc, uint8_t bit, int ignore)
+{
+ memmove(hdlc->history+1, hdlc->history, sizeof(hdlc->history)-1);
+ hdlc->history[0] = bit;
+ if (ignore)
+ return -1;
+
+ 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) {
+ pbit_t out;
+ /* generate one output byte */
+ osmo_ubit2pbit_ext(&out, 0, hdlc->next_outbyte, 0, 8, 0);
+ hdlc->num_bits = 0;
+ return out;
+ }
+
+ return -1;
+}
+
+static int process_hdlc_bit(struct hdlc_proc *hdlc, uint8_t bit)
+{
+ int ignore = 0;
+ int out, 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:
+ if (bit == 0) {
+ DEBUGP("F ");
+ flag = 1;
+ hdlc->state = STATE_PAYLOAD;
+ } else {
+ hdlc->state = STATE_INIT;
+ }
+ ignore = 1;
+ hdlc->num_bits = 0;
+ break;
+ default:
+ if (!memcmp(five_ones, hdlc->history, sizeof(five_ones))) {
+ if (bit == 1) {
+ //DEBUGP("F ");
+ hdlc->state = STATE_FLAG_WAIT_ZERO;
+ 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)));
+ if (out > 0)
+ DEBUGP(", out 0x%02x\n", out);
+ else
+ DEBUGP("\n");
+
+ if (flag)
+ return -123;
+ else
+ return out;
+}
+
+int process_raw_hdlc(struct hdlc_proc *hdlc, uint8_t *data, unsigned int len)
+{
+ unsigned int i;
+ int out;
+ static int last_out;
+
+ for (i = 0; i < len; i ++) {
+ out = process_hdlc_bit(hdlc, data[i]);
+ if (out == -123) {
+ /* suppress repeating Flag characters */
+ if (last_out != out)
+ printf("\nF ");
+ last_out = out;
+ } else if (out >= 0) {
+ /* suppress 0xAA and 0x55 bit pattern */
+ if (out != 0xaa && out != 0x55)
+ printf("%02x ", out);
+ last_out = out;
+ }
+ }
+ return 0;
+}
diff --git a/src/hdlc.h b/src/hdlc.h
new file mode 100644
index 0000000..10ec8e2
--- /dev/null
+++ b/src/hdlc.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#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;
+};
+
+int process_raw_hdlc(struct hdlc_proc *hdlc, uint8_t *data, unsigned int len);