blob: d97e6b4a0c2f4cd60d94879e7fcfdc3a7712aa8a [file] [log] [blame]
Harald Welted83c5132016-10-26 09:38:24 +02001#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9
10#include <osmocom/core/utils.h>
11#include <osmocom/core/bits.h>
12
13#include "hdlc.h"
14
15#if 0
16#define DEBUGP(x, args ...) fprintf(stderr, x, ## args)
17#else
18#define DEBUGP(x, args ...) do {} while (0)
19#endif
20
Harald Welte6daa71d2016-11-14 21:26:11 +010021static const ubit_t flag_octet[] = { 0,1,1,1,1,1,1,0 };
22static const ubit_t five_ones_zero[] = { 0,1,1,1,1,1 };
Harald Welted83c5132016-10-26 09:38:24 +020023
Harald Welte6daa71d2016-11-14 21:26:11 +010024static void append_bit_history(struct hdlc_proc *hdlc, uint8_t bit)
Harald Welted83c5132016-10-26 09:38:24 +020025{
Harald Welte90fb7852016-11-14 19:34:30 +010026 /* we always add the bit to the history */
Harald Welted83c5132016-10-26 09:38:24 +020027 memmove(hdlc->history+1, hdlc->history, sizeof(hdlc->history)-1);
28 hdlc->history[0] = bit;
Harald Welte6daa71d2016-11-14 21:26:11 +010029}
Harald Welte90fb7852016-11-14 19:34:30 +010030
Harald Welte6daa71d2016-11-14 21:26:11 +010031static int append_bit_out(struct hdlc_proc *hdlc, uint8_t bit)
32{
Harald Welted83c5132016-10-26 09:38:24 +020033 memmove(hdlc->next_outbyte+1, hdlc->next_outbyte, sizeof(hdlc->next_outbyte)-1);
34 hdlc->next_outbyte[0] = bit;
35 hdlc->num_bits++;
36
37 if (hdlc->num_bits == 8) {
38 pbit_t out;
Harald Welte90bd7b62016-11-14 22:06:46 +010039 hdlc->num_bits = 0;
Harald Welted83c5132016-10-26 09:38:24 +020040 /* generate one output byte */
41 osmo_ubit2pbit_ext(&out, 0, hdlc->next_outbyte, 0, 8, 0);
Harald Welte90bd7b62016-11-14 22:06:46 +010042 /* append to output buffer */
43 OSMO_ASSERT(hdlc->out.len < sizeof(hdlc->out.buf));
44 hdlc->out.buf[hdlc->out.len++] = out;
Harald Welted83c5132016-10-26 09:38:24 +020045 return out;
46 }
47
48 return -1;
49}
50
51static int process_hdlc_bit(struct hdlc_proc *hdlc, uint8_t bit)
52{
Harald Welte6daa71d2016-11-14 21:26:11 +010053 int out = -1, flag = 0;
Harald Welted83c5132016-10-26 09:38:24 +020054
55 DEBUGP("bit=%u, history_in = %s, ", bit, osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
56
Harald Welte6daa71d2016-11-14 21:26:11 +010057 /* always append bit to history */
58 append_bit_history(hdlc, bit);
59
60 if (!memcmp(flag_octet, hdlc->history, sizeof(flag_octet))) {
Harald Welted83c5132016-10-26 09:38:24 +020061 hdlc->num_bits = 0;
Harald Welte6daa71d2016-11-14 21:26:11 +010062 DEBUGP("S ");
63 flag = 1;
Harald Welte90bd7b62016-11-14 22:06:46 +010064 if (hdlc->out.len) {
65 /* call output function if any frame was
66 * received before the flag octet */
67 if (hdlc->out_cb)
68 hdlc->out_cb(hdlc->out.buf, hdlc->out.len,
69 hdlc->priv);
70 hdlc->out.len = 0;
71 }
Harald Welte6daa71d2016-11-14 21:26:11 +010072 } else if (!memcmp(five_ones_zero, hdlc->history, sizeof(five_ones_zero))) {
73 /* 4.3.1 Synchronous transmission: receiver shall
74 * discard any "0" bit after five contiguous ones */
75 DEBUGP("I ");
76 } else {
77 out = append_bit_out(hdlc, bit);
Harald Welted83c5132016-10-26 09:38:24 +020078 }
Harald Welte6daa71d2016-11-14 21:26:11 +010079
Harald Welted83c5132016-10-26 09:38:24 +020080 DEBUGP("history_out = %s", osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
Harald Welte6daa71d2016-11-14 21:26:11 +010081 if (out >= 0)
Harald Welted83c5132016-10-26 09:38:24 +020082 DEBUGP(", out 0x%02x\n", out);
83 else
84 DEBUGP("\n");
85
86 if (flag)
87 return -123;
88 else
89 return out;
90}
91
Harald Welte90bd7b62016-11-14 22:06:46 +010092int process_raw_hdlc(struct hdlc_proc *hdlc, ubit_t *bits, unsigned int len)
Harald Welted83c5132016-10-26 09:38:24 +020093{
94 unsigned int i;
95 int out;
96 static int last_out;
97
Harald Welte90bd7b62016-11-14 22:06:46 +010098 DEBUGP("process_raw_hdlc(%s)\n", osmo_hexdump(bits, len));
Harald Welte6daa71d2016-11-14 21:26:11 +010099
Harald Welted83c5132016-10-26 09:38:24 +0200100 for (i = 0; i < len; i ++) {
Harald Welte90bd7b62016-11-14 22:06:46 +0100101 out = process_hdlc_bit(hdlc, bits[i]);
Harald Welted83c5132016-10-26 09:38:24 +0200102 if (out == -123) {
103 /* suppress repeating Flag characters */
104 if (last_out != out)
105 printf("\nF ");
106 last_out = out;
107 } else if (out >= 0) {
108 /* suppress 0xAA and 0x55 bit pattern */
Harald Welte6daa71d2016-11-14 21:26:11 +0100109 //if (out != 0xaa && out != 0x55)
Harald Welted83c5132016-10-26 09:38:24 +0200110 printf("%02x ", out);
111 last_out = out;
112 }
113 }
114 return 0;
115}