# HG changeset patch # User Mychaela Falconia # Date 1670906265 0 # Node ID b7ea278390ebc6d3c2abb9653cfba1181320ee13 # Parent 8eb0e7a394096b3c4848007ef99732bb2d9cdbdb gsmfr-cvt-dlcap: support new FC TCH DL recording format diff -r 8eb0e7a39409 -r b7ea278390eb frtest/cvt-dlcap.c --- a/frtest/cvt-dlcap.c Sun Dec 11 22:20:36 2022 +0000 +++ b/frtest/cvt-dlcap.c Tue Dec 13 04:37:45 2022 +0000 @@ -9,8 +9,8 @@ #include #include #include - -static const char bfi_marker[2] = {0xBF, 0x00}; +#include +#include static decode_hex_digit(ch) @@ -23,16 +23,49 @@ return(ch - 'a' + 10); } +static +parse_classic_part(line, status_words, tidsp_bytes) + char *line; + u_short *status_words; + u_char *tidsp_bytes; +{ + char *cp; + int i; + + /* grok DSP status words */ + cp = line; + for (i = 0; i < 3; i++) { + if (!isxdigit(cp[0]) || !isxdigit(cp[1]) || + !isxdigit(cp[2]) || !isxdigit(cp[3])) + return -1; + status_words[i] = (decode_hex_digit(cp[0]) << 12) | + (decode_hex_digit(cp[1]) << 8) | + (decode_hex_digit(cp[2]) << 4) | + decode_hex_digit(cp[3]); + cp += 4; + if (*cp++ != ' ') + return -1; + } + /* read the frame bits */ + for (i = 0; i < 33; i++) { + if (!isxdigit(cp[0]) || !isxdigit(cp[1])) + return -1; + tidsp_bytes[i] = (decode_hex_digit(cp[0]) << 4) | + decode_hex_digit(cp[1]); + cp += 2; + } + return 0; +} + main(argc, argv) char **argv; { FILE *inf, *outf; char linebuf[128]; - int lineno; - char *cp; - int i; + int lineno, rc; u_short status_words[3]; - u_char tidsp_bytes[33], libgsm_bytes[33]; + u_char tidsp_bytes[33], libgsm_bytes[33], bfi[2]; + unsigned fn_mod_104; if (argc != 3) { fprintf(stderr, "usage: %s infile outfile\n", argv[0]); @@ -49,36 +82,39 @@ exit(1); } for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { - /* grok DSP status words */ - cp = linebuf; - for (i = 0; i < 3; i++) { - if (!isxdigit(cp[0]) || !isxdigit(cp[1]) || - !isxdigit(cp[2]) || !isxdigit(cp[3])) { + /* support both old and new formats */ + if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) && + isxdigit(linebuf[2]) && isxdigit(linebuf[3])) { + rc = parse_classic_part(linebuf, status_words, + tidsp_bytes); + if (rc < 0) { invalid: fprintf(stderr, - "error: %s is not in the expected format\n", - argv[1]); + "error: %s is not in the expected format\n", + argv[1]); exit(1); } - status_words[i] = (decode_hex_digit(cp[0]) << 12) | - (decode_hex_digit(cp[1]) << 8) | - (decode_hex_digit(cp[2]) << 4) | - decode_hex_digit(cp[3]); - cp += 4; - if (*cp++ != ' ') + fn_mod_104 = 0; /* won't have TAF */ + } else if (!strncmp(linebuf, "FR ", 3)) { + rc = parse_classic_part(linebuf + 3, status_words, + tidsp_bytes); + if (rc < 0) + goto invalid; + if (linebuf[84] != ' ') + goto invalid; + if (!isdigit(linebuf[85])) goto invalid; - } - /* read the frame bits */ - for (i = 0; i < 33; i++) { - if (!isxdigit(cp[0]) || !isxdigit(cp[1])) - goto invalid; - tidsp_bytes[i] = (decode_hex_digit(cp[0]) << 4) | - decode_hex_digit(cp[1]); - cp += 2; - } - /* bit 2 of status word 0 is BFI */ - if (status_words[0] & 0x0004) - fwrite(bfi_marker, 1, 2, outf); - else { + fn_mod_104 = strtoul(linebuf + 85, 0, 10); + } else + goto invalid; + /* + * Bit 15 of status word 0 is buffer validity flag, + * bit 2 is BFI. + */ + if (!(status_words[0] & 0x8000) || (status_words[0] & 0x0004)) { + bfi[0] = 0xBF; + bfi[1] = fn_mod_104 == 60; + fwrite(bfi, 1, 2, outf); + } else { gsm0610_tidsp_to_libgsm(tidsp_bytes, libgsm_bytes); fwrite(libgsm_bytes, 1, 33, outf); }