#include #include #include #include #include #include #include #include #include #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); }