FreeCalypso > hg > gsm-codec-lib
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/efrtest/dlcap-sync.c Mon May 13 07:21:09 2024 +0000 @@ -0,0 +1,138 @@ +/* + * This program reads a TCH/EFS downlink capture file from a FreeCalypso GSM MS + * that was produced in a session in which seqsync PCMA or PCMU input was fed + * into the test call from IP-PSTN side. It looks for EFR DHF followed by + * specific frame patterns indicating how the seqsync input was transcoded + * by the alien GSM network, and reports its findings. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +static const uint8_t efr_dhf[31] = { +0xC0,0x85,0xEB,0x49,0x0F,0xAA,0xD6,0x03,0xE3,0xA1,0x86,0x07,0xB0,0xC4,0x2C,0x08, +0x04,0x80,0x55,0x80,0x00,0x00,0x00,0x00,0x03,0x6B,0x00,0x00,0x00,0x00,0x00, +}; + +static const uint8_t mr122_dhf[31] = { +0xC0,0x85,0x4D,0xB9,0x6A,0xAA,0xD6,0x00,0x00,0x00,0x00,0x01,0xB5,0x87,0xF6,0x68, +0x37,0x94,0x09,0x00,0x41,0x58,0x54,0xF1,0x0F,0x6B,0x02,0x40,0x3C,0x7E,0xA0, +}; + +extern const uint8_t sync_from_pcma[320*31]; +extern const uint8_t sync_from_pcmu[320*31]; + +static int +check_for_match(input, table) + const uint8_t *input, *table; +{ + unsigned n; + + for (n = 0; n < 320; n++) { + if (!bcmp(input, table + n * 31, 31)) + return n; + } + return -1; +} + +main(argc, argv) + char **argv; +{ + FILE *inf; + char linebuf[128]; + int lineno, rc; + uint16_t status_words[3]; + uint8_t tidsp_bytes[33], efr_bytes[31]; + const uint8_t *match_table; + int dhf_state; + char *dhf_name; + + if (argc != 3) { +usage: fprintf(stderr, "usage: %s dlcap-file alaw|ulaw\n", argv[0]); + exit(1); + } + inf = fopen(argv[1], "r"); + if (!inf) { + perror(argv[1]); + exit(1); + } + if (!strcmp(argv[2], "alaw")) + match_table = sync_from_pcma; + else if (!strcmp(argv[2], "ulaw")) + match_table = sync_from_pcmu; + else + goto usage; + dhf_state = 0; + for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { + /* support both old and new formats */ + if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) && + isxdigit(linebuf[2]) && isxdigit(linebuf[3])) { + rc = parse_dlcap_common(linebuf, status_words, + tidsp_bytes); + if (rc < 0) { +invalid: fprintf(stderr, + "error: %s is not in the expected format\n", + argv[1]); + exit(1); + } + } else if (!strncmp(linebuf, "EFR ", 4)) { + rc = parse_dlcap_common(linebuf + 4, status_words, + tidsp_bytes); + if (rc < 0) + goto invalid; + if (linebuf[85] != ' ') + goto invalid; + if (!isdigit(linebuf[86])) + goto invalid; + } else + goto invalid; + if ((status_words[0] & 0xC204) != 0xC000) { + dhf_state = 0; + continue; + } + efr_tidsp_to_std(tidsp_bytes, efr_bytes); + if (!bcmp(efr_bytes, efr_dhf, 31)) { + dhf_state = 1; + continue; + } + if (!bcmp(efr_bytes, mr122_dhf, 31)) { + dhf_state = 2; + continue; + } + if (!dhf_state) + continue; + rc = check_for_match(efr_bytes, match_table); + if (rc >= 0 && rc <= 159) { + printf( + "line %d: match to standard EFR with offset %d\n", + lineno, rc); + if (dhf_state == 2) + printf("... but preceded by MR122 DHF!\n"); + } else if (rc >= 160 && rc <= 279) { + printf("line %d: match to AMR-EFR with offset %d\n", + lineno, rc - 160); + if (dhf_state == 2) + printf("... but preceded by MR122 DHF!\n"); + } else if (rc >= 280 && rc <= 319) { + printf("line %d: match to AMR-EFR with offset %d\n", + lineno, rc - 160); + switch (dhf_state) { + case 1: + dhf_name = "EFR"; + break; + case 2: + dhf_name = "MR122"; + break; + default: + dhf_name = "???"; + } + printf("previous frame was %s DHF\n", dhf_name); + } + dhf_state = 0; + } + exit(0); +}