157 lines
3.0 KiB
C
157 lines
3.0 KiB
C
#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>
|
|
|
|
#if 0
|
|
#define DEBUGP(x, args ...) fprintf(stderr, x, ## args)
|
|
#else
|
|
#define DEBUGP(x, args ...) do {} while (0)
|
|
#endif
|
|
|
|
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;
|
|
};
|
|
|
|
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, 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", 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int fd, rc, bitlen;
|
|
uint8_t buf[512];
|
|
ubit_t bitbuf[512*8];
|
|
struct hdlc_proc hdlc;
|
|
|
|
memset(&hdlc, 0, sizeof(hdlc));
|
|
|
|
if (argc < 2) {
|
|
fprintf(stderr, "You have to specify the input file\n");
|
|
exit(2);
|
|
}
|
|
|
|
printf("opening '%s'\n", argv[1]);
|
|
|
|
fd = open(argv[1], O_RDONLY);
|
|
if (fd < 0) {
|
|
perror("opening infile");
|
|
exit(2);
|
|
}
|
|
|
|
while (1) {
|
|
rc = read(fd, buf, sizeof(buf));
|
|
if (rc <= 0)
|
|
exit(1);
|
|
|
|
bitlen = osmo_pbit2ubit_ext(bitbuf, 0, buf, 0, rc*8, 0);
|
|
DEBUGP("%s\n", ubit_dump(bitbuf, bitlen));
|
|
process_raw_hdlc(&hdlc, bitbuf, bitlen);
|
|
}
|
|
|
|
exit(0);
|
|
}
|