FreeCalypso > hg > gsm-codec-lib
view amrconv/tw5c-dump.c @ 608:d4e42ec4a688 default tip
hrutil: new program gsmhr-decode-r
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 05 Dec 2025 09:01:14 +0000 |
| parents | fd6a394ab4cd |
| children |
line wrap: on
line source
/* * This program reads a TW-TS-005 Annex C hexadecimal file * and dumps all frames in human-readable form. */ #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <unistd.h> #include "../libtest/tw5reader.h" #include "amr_defs.h" extern char *amr_mode_names[16]; extern const uint8_t pl_total_bytes_oa[9], pl_total_bytes_bwe[9]; static char *infname; static int is_bwe; static void process_cmdline(argc, argv) char **argv; { int opt; extern int optind; while ((opt = getopt(argc, argv, "b")) != EOF) { switch (opt) { case 'b': is_bwe = 1; continue; default: usage: fprintf(stderr, "usage: %s [-b] hex-file\n", argv[0]); exit(1); } } if (argc != optind + 1) goto usage; infname = argv[optind]; } static void if1_bwe_to_oa(in, out, mode) uint8_t *in, *out; unsigned mode; { unsigned out_len, n; out_len = pl_total_bytes_oa[mode] - 2; for (n = 0; n < out_len; n++) out[n] = (in[n+1] << 2) | (in[n+2] >> 6); } static void process_file() { FILE *hexf; unsigned lineno; uint8_t frame[TWTS005_MAX_FRAME]; unsigned frame_len, base_len, cmr, ft, q, sid_byte, sti, sid_mode; const uint8_t *pl_len_table; uint8_t frm_to_oa[MAX_IF1_BYTES]; uint8_t ser_bits[MAX_SERIAL_SIZE]; uint16_t params[MAX_PRM_SIZE]; unsigned ptr; int rc; hexf = fopen(infname, "r"); if (!hexf) { perror(infname); exit(1); } lineno = 0; for (;;) { rc = twts005_read_frame(hexf, &lineno, frame, &frame_len); if (rc < 0) { fprintf(stderr, "%s line %u: not valid TW-TS-005\n", infname, lineno); exit(1); } if (!rc) break; if (frame_len == 0) { printf("line %u: NULL frame\n", lineno); continue; } if (frame_len < 2) { inv_payload: fprintf(stderr, "%s line %u: payload is not valid AMR %s\n", infname, lineno, is_bwe ? "BWE" : "OA"); exit(1); } cmr = frame[0] >> 4; if (cmr > MR122 && cmr != MODE_NO_DATA) goto inv_payload; if (is_bwe) { if (frame[0] & 0x08) goto inv_payload; ft = ((frame[0] & 0x07) << 1) | ((frame[1] & 0x80) >> 7); q = (frame[1] & 0x40) >> 6; pl_len_table = pl_total_bytes_bwe; } else { if (frame[1] & 0x80) goto inv_payload; ft = (frame[1] & 0x78) >> 3; q = (frame[1] & 0x04) >> 2; pl_len_table = pl_total_bytes_oa; } if (ft <= MRDTX) base_len = pl_len_table[ft]; else if (ft == MODE_NO_DATA) base_len = 2; else goto inv_payload; if (frame_len < base_len) goto inv_payload; printf("line %u: CMR=%u (%s) FT=%u (%s) Q=%u\n", lineno, cmr, amr_mode_names[cmr], ft, amr_mode_names[ft], q); if (ft != MODE_NO_DATA) { if (is_bwe) { if1_bwe_to_oa(frame, frm_to_oa, ft); amr_if1_unpack(frm_to_oa, ser_bits, ft); } else { amr_if1_unpack(frame + 2, ser_bits, ft); } reassemble_amr_params(ser_bits, params, ft); dump_amr_params(params, ft); } if (ft == MRDTX) { sid_byte = is_bwe ? frm_to_oa[4] : frame[6]; sti = (sid_byte & 0x10) >> 4; sid_mode = 0; if (sid_byte & 0x08) sid_mode |= 1; if (sid_byte & 0x04) sid_mode |= 2; if (sid_byte & 0x02) sid_mode |= 4; printf(" SID_%s Mode=%u (%s)\n", sti ? "UPDATE" : "FIRST", sid_mode, amr_mode_names[sid_mode]); } if (is_bwe) continue; /* TW-TS-006 extensions */ if (frame[0] & 0x08) printf(" RIF=%u\n", (frame[0] & 0x04) >> 2); ptr = base_len; if ((ft == MODE_NO_DATA) && (frame[1] & 0x02)) { fputs(" FT15 ext octet: ", stdout); if (ptr >= frame_len) { puts("indicated, but not present"); continue; } /* repurpose sti and sid_mode vars */ sti = (frame[ptr] & 0x80) >> 7; sid_mode = frame[ptr] & 7; printf("%s, Mode=%u (%s)\n", sti ? "Onset" : "No_Data", sid_mode, amr_mode_names[sid_mode]); ptr++; } if (frame[0] & 0x02) { if (ptr >= frame_len) { puts(" TA+DTXd+TFOE octet missing!"); continue; } printf(" TA=%u DTXd=%u TFOE=%u\n", frame[ptr] >> 2, (frame[ptr] & 0x02) >> 1, frame[ptr] & 0x01); ptr++; } if (frame[0] & 0x01) puts(" Rel4 Config_Prot present, not decoded"); if ((ft == MODE_NO_DATA) && (frame[1] & 0x01)) puts(" Rel5 GCF, not decoded"); } } main(argc, argv) char **argv; { process_cmdline(argc, argv); process_file(); exit(0); }
