FreeCalypso > hg > freecalypso-reveng
view hr-bits/sid-count.c @ 408:14302e075f37 default tip
hr-bits: further conditionalize SID-1-diff
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 22 Jul 2024 10:06:38 +0000 |
parents | 183e81c8f6c0 |
children |
line wrap: on
line source
/* * This program reads a TCH/HS DL capture file made with FC tools * and analyzes the hex string of payload bits in every frame. * For each frame, this program counts how many bits in the SID field * are set (both class 1 and class 2. All input lines are passed * through to the output, but at the end of each line this program * appends bit counts that match the conventions used in GSM 06.06 * swSidDetection() function. */ #include <ctype.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> static const uint8_t class1_mask[12] = {0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x3F, 0xC0, 0x0F, 0x78, 0x0E, 0x06}; static const uint8_t class2_mask[3] = {0x1F, 0xFF, 0xF0}; static char *infname, *outfname; static FILE *inf, *outf; static int lineno; static char linebuf[80]; static uint8_t frame[15]; static int is_hex_string_spc(str, expect_len) char *str; unsigned expect_len; { char *cp, *endp; endp = str + expect_len; for (cp = str; cp < endp; cp++) { if (!isxdigit(*cp)) return 0; } if (*cp == ' ') return 1; else return 0; } static int decode_hex_digit(c) { int d; if (isdigit(c)) d = c - '0'; else if (isupper(c)) d = c - 'A' + 10; else d = c - 'a' + 10; return d; } static void frame_from_hex() { char *cp; uint8_t *dp; unsigned n, u, l; cp = linebuf + 18; dp = frame; for (n = 0; n < 15; n++) { u = decode_hex_digit(*cp++); l = decode_hex_digit(*cp++); *dp++ = (u << 4) | l; } } static unsigned ones_in_byte(byte) unsigned byte; { unsigned count; count = 0; for (; byte; byte >>= 1) { if (byte & 1) count++; } return count; } static unsigned count_1_bits(data, mask, nbytes) uint8_t *data, *mask; unsigned nbytes; { unsigned n, and, accum; accum = 0; for (n = 0; n < nbytes; n++) { and = *data++ & *mask++; accum += ones_in_byte(and); } return accum; } static void process_line() { char *cp; unsigned class1_ones, class1_zeros; unsigned class2_ones, class2_zeros; unsigned n1n2; cp = index(linebuf, '\n'); if (!cp) { fprintf(stderr, "%s line %d: too long or missing newline\n", infname, lineno); exit(1); } *cp = '\0'; if (strncmp(linebuf, "HR ", 3)) { inv: fprintf(stderr, "%s line %d: format does not match HR DL capture\n", infname, lineno); exit(1); } if (!is_hex_string_spc(linebuf + 3, 4)) goto inv; if (!is_hex_string_spc(linebuf + 8, 4)) goto inv; if (!is_hex_string_spc(linebuf + 13, 4)) goto inv; if (!is_hex_string_spc(linebuf + 18, 30)) goto inv; frame_from_hex(); class1_ones = count_1_bits(frame, class1_mask, 12); class1_zeros = 62 - class1_ones; class2_ones = count_1_bits(frame + 12, class2_mask, 3); class2_zeros = 17 - class2_ones; n1n2 = class1_zeros + class2_zeros; fprintf(outf, "%s %u %u", linebuf, class1_zeros, n1n2); if (n1n2 >= 11 && n1n2 < 16 && class1_zeros >= 3) fputs(" SID-1-diff", outf); if (n1n2 >= 16 && n1n2 <= 25) fputs(" BCI-to-BFI", outf); putc('\n', outf); } main(argc, argv) char **argv; { if (argc >= 2) { infname = argv[1]; inf = fopen(infname, "r"); if (!inf) { perror(infname); exit(1); } } else { inf = stdin; infname = "stdin"; } if (argc >= 3) { outfname = argv[2]; outf = fopen(outfname, "w"); if (!outf) { perror(outfname); exit(1); } } else { outf = stdout; outfname = "stdout"; } for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) process_line(); exit(0); }