FreeCalypso > hg > gsm-codec-lib
diff frtest/dlcap-sync.c @ 474:285381a001fc
new program gsmfr-dlcap-sync
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 15 May 2024 06:20:59 +0000 |
parents | efrtest/dlcap-sync.c@d80ccb3c3970 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frtest/dlcap-sync.c Wed May 15 06:20:59 2024 +0000 @@ -0,0 +1,106 @@ +/* + * This program reads a TCH/FS downlink capture file from a FreeCalypso GSM MS + * that was produced in a session in which seqsync PCMA or PCMU input + * (seqsyn_[au].inp) was fed into the test call from IP-PSTN side. It looks + * for FRv1 DHF followed by specific frame patterns given by ETSI in + * syn???_[au].cod files, and reports what it finds. Matches indicate + * a particular alignment between the input sequence and encoder frame + * boundaries, if the network speech transcoder implements the encoder + * homing feature which is optional for FRv1. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "../libgsmfr2/tw_gsmfr.h" + +extern const uint8_t sync_from_pcma[160*33]; +extern const uint8_t sync_from_pcmu[160*33]; + +static int +check_for_match(input, table) + const uint8_t *input, *table; +{ + unsigned n; + + for (n = 0; n < 160; n++) { + if (!bcmp(input, table + n * 33, 33)) + 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], libgsm_bytes[33]; + const uint8_t *match_table; + int dhf_state; + + 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, "FR ", 3)) { + rc = parse_dlcap_common(linebuf + 3, status_words, + tidsp_bytes); + if (rc < 0) + goto invalid; + if (linebuf[84] != ' ') + goto invalid; + if (!isdigit(linebuf[85])) + goto invalid; + } else + goto invalid; + if ((status_words[0] & 0xC004) != 0xC000) { + dhf_state = 0; + continue; + } + gsm0610_tidsp_to_libgsm(tidsp_bytes, libgsm_bytes); + if (!bcmp(libgsm_bytes, gsmfr_decoder_homing_frame, 33)) { + dhf_state = 1; + continue; + } + if (!dhf_state) + continue; + rc = check_for_match(libgsm_bytes, match_table); + if (rc >= 0 && rc <= 159) { + printf( + "line %d: match to expected sync frame for offset %d\n", + lineno, rc); + } + dhf_state = 0; + } + exit(0); +}