FreeCalypso > hg > gsm-codec-lib
comparison frtest/cvt-dlcap.c @ 137:b7ea278390eb
gsmfr-cvt-dlcap: support new FC TCH DL recording format
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 13 Dec 2022 04:37:45 +0000 |
parents | 7960744ba19c |
children | be57e06bed84 |
comparison
equal
deleted
inserted
replaced
136:8eb0e7a39409 | 137:b7ea278390eb |
---|---|
7 | 7 |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <ctype.h> | 9 #include <ctype.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 #include <stdlib.h> | 11 #include <stdlib.h> |
12 | 12 #include <string.h> |
13 static const char bfi_marker[2] = {0xBF, 0x00}; | 13 #include <strings.h> |
14 | 14 |
15 static | 15 static |
16 decode_hex_digit(ch) | 16 decode_hex_digit(ch) |
17 { | 17 { |
18 if (isdigit(ch)) | 18 if (isdigit(ch)) |
21 return(ch - 'A' + 10); | 21 return(ch - 'A' + 10); |
22 else | 22 else |
23 return(ch - 'a' + 10); | 23 return(ch - 'a' + 10); |
24 } | 24 } |
25 | 25 |
26 static | |
27 parse_classic_part(line, status_words, tidsp_bytes) | |
28 char *line; | |
29 u_short *status_words; | |
30 u_char *tidsp_bytes; | |
31 { | |
32 char *cp; | |
33 int i; | |
34 | |
35 /* grok DSP status words */ | |
36 cp = line; | |
37 for (i = 0; i < 3; i++) { | |
38 if (!isxdigit(cp[0]) || !isxdigit(cp[1]) || | |
39 !isxdigit(cp[2]) || !isxdigit(cp[3])) | |
40 return -1; | |
41 status_words[i] = (decode_hex_digit(cp[0]) << 12) | | |
42 (decode_hex_digit(cp[1]) << 8) | | |
43 (decode_hex_digit(cp[2]) << 4) | | |
44 decode_hex_digit(cp[3]); | |
45 cp += 4; | |
46 if (*cp++ != ' ') | |
47 return -1; | |
48 } | |
49 /* read the frame bits */ | |
50 for (i = 0; i < 33; i++) { | |
51 if (!isxdigit(cp[0]) || !isxdigit(cp[1])) | |
52 return -1; | |
53 tidsp_bytes[i] = (decode_hex_digit(cp[0]) << 4) | | |
54 decode_hex_digit(cp[1]); | |
55 cp += 2; | |
56 } | |
57 return 0; | |
58 } | |
59 | |
26 main(argc, argv) | 60 main(argc, argv) |
27 char **argv; | 61 char **argv; |
28 { | 62 { |
29 FILE *inf, *outf; | 63 FILE *inf, *outf; |
30 char linebuf[128]; | 64 char linebuf[128]; |
31 int lineno; | 65 int lineno, rc; |
32 char *cp; | |
33 int i; | |
34 u_short status_words[3]; | 66 u_short status_words[3]; |
35 u_char tidsp_bytes[33], libgsm_bytes[33]; | 67 u_char tidsp_bytes[33], libgsm_bytes[33], bfi[2]; |
68 unsigned fn_mod_104; | |
36 | 69 |
37 if (argc != 3) { | 70 if (argc != 3) { |
38 fprintf(stderr, "usage: %s infile outfile\n", argv[0]); | 71 fprintf(stderr, "usage: %s infile outfile\n", argv[0]); |
39 exit(1); | 72 exit(1); |
40 } | 73 } |
47 if (!outf) { | 80 if (!outf) { |
48 perror(argv[2]); | 81 perror(argv[2]); |
49 exit(1); | 82 exit(1); |
50 } | 83 } |
51 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { | 84 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { |
52 /* grok DSP status words */ | 85 /* support both old and new formats */ |
53 cp = linebuf; | 86 if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) && |
54 for (i = 0; i < 3; i++) { | 87 isxdigit(linebuf[2]) && isxdigit(linebuf[3])) { |
55 if (!isxdigit(cp[0]) || !isxdigit(cp[1]) || | 88 rc = parse_classic_part(linebuf, status_words, |
56 !isxdigit(cp[2]) || !isxdigit(cp[3])) { | 89 tidsp_bytes); |
90 if (rc < 0) { | |
57 invalid: fprintf(stderr, | 91 invalid: fprintf(stderr, |
58 "error: %s is not in the expected format\n", | 92 "error: %s is not in the expected format\n", |
59 argv[1]); | 93 argv[1]); |
60 exit(1); | 94 exit(1); |
61 } | 95 } |
62 status_words[i] = (decode_hex_digit(cp[0]) << 12) | | 96 fn_mod_104 = 0; /* won't have TAF */ |
63 (decode_hex_digit(cp[1]) << 8) | | 97 } else if (!strncmp(linebuf, "FR ", 3)) { |
64 (decode_hex_digit(cp[2]) << 4) | | 98 rc = parse_classic_part(linebuf + 3, status_words, |
65 decode_hex_digit(cp[3]); | 99 tidsp_bytes); |
66 cp += 4; | 100 if (rc < 0) |
67 if (*cp++ != ' ') | |
68 goto invalid; | 101 goto invalid; |
69 } | 102 if (linebuf[84] != ' ') |
70 /* read the frame bits */ | |
71 for (i = 0; i < 33; i++) { | |
72 if (!isxdigit(cp[0]) || !isxdigit(cp[1])) | |
73 goto invalid; | 103 goto invalid; |
74 tidsp_bytes[i] = (decode_hex_digit(cp[0]) << 4) | | 104 if (!isdigit(linebuf[85])) |
75 decode_hex_digit(cp[1]); | 105 goto invalid; |
76 cp += 2; | 106 fn_mod_104 = strtoul(linebuf + 85, 0, 10); |
77 } | 107 } else |
78 /* bit 2 of status word 0 is BFI */ | 108 goto invalid; |
79 if (status_words[0] & 0x0004) | 109 /* |
80 fwrite(bfi_marker, 1, 2, outf); | 110 * Bit 15 of status word 0 is buffer validity flag, |
81 else { | 111 * bit 2 is BFI. |
112 */ | |
113 if (!(status_words[0] & 0x8000) || (status_words[0] & 0x0004)) { | |
114 bfi[0] = 0xBF; | |
115 bfi[1] = fn_mod_104 == 60; | |
116 fwrite(bfi, 1, 2, outf); | |
117 } else { | |
82 gsm0610_tidsp_to_libgsm(tidsp_bytes, libgsm_bytes); | 118 gsm0610_tidsp_to_libgsm(tidsp_bytes, libgsm_bytes); |
83 fwrite(libgsm_bytes, 1, 33, outf); | 119 fwrite(libgsm_bytes, 1, 33, outf); |
84 } | 120 } |
85 } | 121 } |
86 exit(0); | 122 exit(0); |