blob: 19ba90015b1504b27a76d1a95ba2f3fb7bee0cd4 [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) {
Harald Welte6daa71d2016-11-14 21:26:11 +010038 hdlc->num_bits = 0;
Harald Welted83c5132016-10-26 09:38:24 +020039 pbit_t out;
40 /* generate one output byte */
41 osmo_ubit2pbit_ext(&out, 0, hdlc->next_outbyte, 0, 8, 0);
Harald Welted83c5132016-10-26 09:38:24 +020042 return out;
43 }
44
45 return -1;
46}
47
48static int process_hdlc_bit(struct hdlc_proc *hdlc, uint8_t bit)
49{
Harald Welte6daa71d2016-11-14 21:26:11 +010050 int out = -1, flag = 0;
Harald Welted83c5132016-10-26 09:38:24 +020051
52 DEBUGP("bit=%u, history_in = %s, ", bit, osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
53
Harald Welte6daa71d2016-11-14 21:26:11 +010054 /* always append bit to history */
55 append_bit_history(hdlc, bit);
56
57 if (!memcmp(flag_octet, hdlc->history, sizeof(flag_octet))) {
Harald Welted83c5132016-10-26 09:38:24 +020058 hdlc->num_bits = 0;
Harald Welte6daa71d2016-11-14 21:26:11 +010059 DEBUGP("S ");
60 flag = 1;
61 } else if (!memcmp(five_ones_zero, hdlc->history, sizeof(five_ones_zero))) {
62 /* 4.3.1 Synchronous transmission: receiver shall
63 * discard any "0" bit after five contiguous ones */
64 DEBUGP("I ");
65 } else {
66 out = append_bit_out(hdlc, bit);
Harald Welted83c5132016-10-26 09:38:24 +020067 }
Harald Welte6daa71d2016-11-14 21:26:11 +010068
Harald Welted83c5132016-10-26 09:38:24 +020069 DEBUGP("history_out = %s", osmo_ubit_dump(hdlc->history, sizeof(hdlc->history)));
Harald Welte6daa71d2016-11-14 21:26:11 +010070 if (out >= 0)
Harald Welted83c5132016-10-26 09:38:24 +020071 DEBUGP(", out 0x%02x\n", out);
72 else
73 DEBUGP("\n");
74
75 if (flag)
76 return -123;
77 else
78 return out;
79}
80
81int process_raw_hdlc(struct hdlc_proc *hdlc, uint8_t *data, unsigned int len)
82{
83 unsigned int i;
84 int out;
85 static int last_out;
86
Harald Welte6daa71d2016-11-14 21:26:11 +010087 DEBUGP("process_raw_hdlc(%s)\n", osmo_hexdump(data,len));
88
Harald Welted83c5132016-10-26 09:38:24 +020089 for (i = 0; i < len; i ++) {
90 out = process_hdlc_bit(hdlc, data[i]);
91 if (out == -123) {
92 /* suppress repeating Flag characters */
93 if (last_out != out)
94 printf("\nF ");
95 last_out = out;
96 } else if (out >= 0) {
97 /* suppress 0xAA and 0x55 bit pattern */
Harald Welte6daa71d2016-11-14 21:26:11 +010098 //if (out != 0xaa && out != 0x55)
Harald Welted83c5132016-10-26 09:38:24 +020099 printf("%02x ", out);
100 last_out = out;
101 }
102 }
103 return 0;
104}