FreeCalypso > hg > gsm-codec-lib
comparison efrtest/dlcap-sync.c @ 468:4104b0390fab
efrtest: new program gsmefr-dlcap-sync
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 13 May 2024 07:21:09 +0000 |
parents | |
children | d80ccb3c3970 |
comparison
equal
deleted
inserted
replaced
467:ad032051166a | 468:4104b0390fab |
---|---|
1 /* | |
2 * This program reads a TCH/EFS downlink capture file from a FreeCalypso GSM MS | |
3 * that was produced in a session in which seqsync PCMA or PCMU input was fed | |
4 * into the test call from IP-PSTN side. It looks for EFR DHF followed by | |
5 * specific frame patterns indicating how the seqsync input was transcoded | |
6 * by the alien GSM network, and reports its findings. | |
7 */ | |
8 | |
9 #include <ctype.h> | |
10 #include <stdio.h> | |
11 #include <stdint.h> | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 #include <strings.h> | |
15 | |
16 static const uint8_t efr_dhf[31] = { | |
17 0xC0,0x85,0xEB,0x49,0x0F,0xAA,0xD6,0x03,0xE3,0xA1,0x86,0x07,0xB0,0xC4,0x2C,0x08, | |
18 0x04,0x80,0x55,0x80,0x00,0x00,0x00,0x00,0x03,0x6B,0x00,0x00,0x00,0x00,0x00, | |
19 }; | |
20 | |
21 static const uint8_t mr122_dhf[31] = { | |
22 0xC0,0x85,0x4D,0xB9,0x6A,0xAA,0xD6,0x00,0x00,0x00,0x00,0x01,0xB5,0x87,0xF6,0x68, | |
23 0x37,0x94,0x09,0x00,0x41,0x58,0x54,0xF1,0x0F,0x6B,0x02,0x40,0x3C,0x7E,0xA0, | |
24 }; | |
25 | |
26 extern const uint8_t sync_from_pcma[320*31]; | |
27 extern const uint8_t sync_from_pcmu[320*31]; | |
28 | |
29 static int | |
30 check_for_match(input, table) | |
31 const uint8_t *input, *table; | |
32 { | |
33 unsigned n; | |
34 | |
35 for (n = 0; n < 320; n++) { | |
36 if (!bcmp(input, table + n * 31, 31)) | |
37 return n; | |
38 } | |
39 return -1; | |
40 } | |
41 | |
42 main(argc, argv) | |
43 char **argv; | |
44 { | |
45 FILE *inf; | |
46 char linebuf[128]; | |
47 int lineno, rc; | |
48 uint16_t status_words[3]; | |
49 uint8_t tidsp_bytes[33], efr_bytes[31]; | |
50 const uint8_t *match_table; | |
51 int dhf_state; | |
52 char *dhf_name; | |
53 | |
54 if (argc != 3) { | |
55 usage: fprintf(stderr, "usage: %s dlcap-file alaw|ulaw\n", argv[0]); | |
56 exit(1); | |
57 } | |
58 inf = fopen(argv[1], "r"); | |
59 if (!inf) { | |
60 perror(argv[1]); | |
61 exit(1); | |
62 } | |
63 if (!strcmp(argv[2], "alaw")) | |
64 match_table = sync_from_pcma; | |
65 else if (!strcmp(argv[2], "ulaw")) | |
66 match_table = sync_from_pcmu; | |
67 else | |
68 goto usage; | |
69 dhf_state = 0; | |
70 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { | |
71 /* support both old and new formats */ | |
72 if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) && | |
73 isxdigit(linebuf[2]) && isxdigit(linebuf[3])) { | |
74 rc = parse_dlcap_common(linebuf, status_words, | |
75 tidsp_bytes); | |
76 if (rc < 0) { | |
77 invalid: fprintf(stderr, | |
78 "error: %s is not in the expected format\n", | |
79 argv[1]); | |
80 exit(1); | |
81 } | |
82 } else if (!strncmp(linebuf, "EFR ", 4)) { | |
83 rc = parse_dlcap_common(linebuf + 4, status_words, | |
84 tidsp_bytes); | |
85 if (rc < 0) | |
86 goto invalid; | |
87 if (linebuf[85] != ' ') | |
88 goto invalid; | |
89 if (!isdigit(linebuf[86])) | |
90 goto invalid; | |
91 } else | |
92 goto invalid; | |
93 if ((status_words[0] & 0xC204) != 0xC000) { | |
94 dhf_state = 0; | |
95 continue; | |
96 } | |
97 efr_tidsp_to_std(tidsp_bytes, efr_bytes); | |
98 if (!bcmp(efr_bytes, efr_dhf, 31)) { | |
99 dhf_state = 1; | |
100 continue; | |
101 } | |
102 if (!bcmp(efr_bytes, mr122_dhf, 31)) { | |
103 dhf_state = 2; | |
104 continue; | |
105 } | |
106 if (!dhf_state) | |
107 continue; | |
108 rc = check_for_match(efr_bytes, match_table); | |
109 if (rc >= 0 && rc <= 159) { | |
110 printf( | |
111 "line %d: match to standard EFR with offset %d\n", | |
112 lineno, rc); | |
113 if (dhf_state == 2) | |
114 printf("... but preceded by MR122 DHF!\n"); | |
115 } else if (rc >= 160 && rc <= 279) { | |
116 printf("line %d: match to AMR-EFR with offset %d\n", | |
117 lineno, rc - 160); | |
118 if (dhf_state == 2) | |
119 printf("... but preceded by MR122 DHF!\n"); | |
120 } else if (rc >= 280 && rc <= 319) { | |
121 printf("line %d: match to AMR-EFR with offset %d\n", | |
122 lineno, rc - 160); | |
123 switch (dhf_state) { | |
124 case 1: | |
125 dhf_name = "EFR"; | |
126 break; | |
127 case 2: | |
128 dhf_name = "MR122"; | |
129 break; | |
130 default: | |
131 dhf_name = "???"; | |
132 } | |
133 printf("previous frame was %s DHF\n", dhf_name); | |
134 } | |
135 dhf_state = 0; | |
136 } | |
137 exit(0); | |
138 } |