# HG changeset patch # User Mychaela Falconia # Date 1715667025 28800 # Node ID 4f81b959a5f5ad86cbde9e6fea525eda13f1fb61 # Parent 71f01a834820ef5c10009d8d0f77c3891473a2e4 sipout-test-voice: implement PCMU GSM uplink catcher diff -r 71f01a834820 -r 4f81b959a5f5 test-voice/Makefile --- a/test-voice/Makefile Sat May 11 22:27:07 2024 -0800 +++ b/test-voice/Makefile Mon May 13 22:10:25 2024 -0800 @@ -1,8 +1,8 @@ CC= gcc CFLAGS= -O2 PROG= sipout-test-voice -OBJS= bye_in.o disc_cmd.o main.o readconf.o reinvite.o rtp_rx.o rtp_tx.o \ - sdp_in.o sip_log.o sip_udp.o uac.o uas.o user_cmd.o +OBJS= bye_in.o disc_cmd.o main.o pcmu_catcher.o readconf.o reinvite.o \ + rtp_rx.o rtp_tx.o sdp_in.o sip_log.o sip_udp.o uac.o uas.o user_cmd.o LIBS= ../libsip/libsip.a ../librtpalloc/librtpalloc.a ../libutil/libutil.a INSTBIN=/opt/themwi/bin diff -r 71f01a834820 -r 4f81b959a5f5 test-voice/pcmu_catcher.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-voice/pcmu_catcher.c Mon May 13 22:10:25 2024 -0800 @@ -0,0 +1,174 @@ +/* + * This module implements the logic that scans received PCMU sample streams + * for patterns that result from a GSM-FR or GSM-EFR decoder processing + * uplink test frames constructed in vband-misc repository, ul-test + * subdirectory. + */ + +#include +#include + +static const uint8_t match_frame_fr[160] = { +0xFF,0x0F,0x0E,0x1B,0x8D,0x8A,0x9C,0x23,0x1D,0x38,0x1C,0x1B,0x26,0x8A,0x80,0x92, +0x11,0x06,0x1E,0xA3,0x9B,0xBF,0x9B,0x91,0x9C,0x11,0x06,0x1C,0x98,0x87,0x8D,0xAF, +0x1D,0x16,0x13,0x1F,0xBE,0x8D,0x88,0x99,0x1D,0x07,0x05,0x12,0xAC,0x8B,0x87,0x95, +0x25,0x09,0x06,0x14,0xAA,0x8B,0x88,0x97,0x25,0x0A,0x09,0x1A,0xA4,0x8C,0x8A,0x99, +0x28,0x0C,0x09,0x1B,0xA5,0x8C,0x8B,0x9D,0x23,0x0C,0x0A,0x19,0xA4,0x8C,0x8A,0x9D, +0x1E,0x0A,0x0A,0x1C,0xA2,0x8C,0x8B,0x9B,0x25,0x0C,0x0A,0x19,0xA7,0x8C,0x8B,0x9B, +0x26,0x0D,0x0B,0x1A,0xAA,0x8D,0x8A,0x99,0x2A,0x0D,0x0B,0x1A,0xAB,0x8E,0x8C,0x99, +0x2F,0x0F,0x0B,0x19,0xAE,0x8E,0x8C,0x99,0x34,0x0F,0x0D,0x1A,0xB2,0x91,0x8D,0x99, +0x3B,0x12,0x0D,0x19,0xBA,0x92,0x8E,0x9B,0x38,0x14,0x0F,0x1B,0xBB,0x94,0x8E,0x9A, +0x3B,0x13,0x0E,0x1B,0xBA,0x95,0x90,0x9B,0x3F,0x16,0x0F,0x1B,0xBB,0x94,0x8F,0x9C, +}; + +static const uint8_t match_frame_efr_classic[160] = { +0x6F,0x64,0x63,0x6B,0xE8,0xDA,0xDC,0xEF,0x60,0x5A,0x5D,0x6F,0xE2,0xD8,0xD9,0xEC, +0x5F,0x58,0x5E,0x7E,0xE2,0xDF,0xE2,0xF0,0x63,0x58,0x59,0x67,0xE0,0xD4,0xD7,0xEC, +0x5E,0x56,0x5A,0x6D,0xE1,0xD6,0xD7,0xEA,0x4D,0x37,0x2F,0x3A,0xC2,0xA7,0xA3,0xB5, +0x2F,0x1C,0x1A,0x2D,0xA9,0x96,0x96,0xAE,0x22,0x12,0x14,0x31,0x9E,0x8F,0x94,0xB6, +0x1B,0x0D,0x0F,0x2C,0x9B,0x8C,0x8E,0xAB,0x17,0x09,0x0C,0x28,0x97,0x88,0x8A,0xA7, +0x15,0x07,0x0A,0x29,0x95,0x88,0x8B,0xAA,0x15,0x08,0x0B,0x2A,0x96,0x88,0x8B,0xAA, +0x15,0x09,0x0C,0x2A,0x97,0x89,0x8C,0xAA,0x17,0x0A,0x0D,0x2B,0x98,0x8A,0x8D,0xAB, +0x18,0x0A,0x0D,0x2A,0x99,0x8A,0x8D,0xAA,0x18,0x0A,0x0D,0x29,0x99,0x8A,0x8D,0xA9, +0x19,0x0A,0x0D,0x29,0x99,0x8A,0x8D,0xA9,0x19,0x0A,0x0D,0x29,0x99,0x8A,0x8D,0xA9, +0x19,0x0A,0x0D,0x28,0x99,0x8A,0x8C,0xA8,0x19,0x0A,0x0D,0x27,0x9A,0x8B,0x8D,0xA7, +}; + +static const uint8_t match_frame_amrefr_dec[160] = { +0x6F,0x66,0x66,0x6E,0xE5,0xDA,0xDD,0xF2,0x5F,0x5A,0x5E,0x76,0xE0,0xD8,0xDA,0xEF, +0x5E,0x59,0x5F,0xFC,0xE1,0xDF,0xE5,0xF5,0x61,0x59,0x5B,0x6B,0xDE,0xD4,0xD9,0xEF, +0x5D,0x56,0x5B,0x71,0xDF,0xD6,0xD8,0xEE,0x4D,0x38,0x31,0x3E,0xBD,0xA7,0xA5,0xB9, +0x2D,0x1C,0x1C,0x35,0xA5,0x96,0x98,0xB4,0x1F,0x12,0x17,0x3D,0x9C,0x90,0x96,0xC1, +0x1A,0x0E,0x12,0x38,0x98,0x8C,0x8F,0xB4,0x16,0x0A,0x0D,0x32,0x94,0x88,0x8C,0xAE, +0x13,0x08,0x0C,0x35,0x92,0x88,0x8C,0xB3,0x13,0x08,0x0D,0x35,0x93,0x88,0x8D,0xB3, +0x13,0x09,0x0D,0x34,0x94,0x89,0x8D,0xB3,0x15,0x0A,0x0E,0x35,0x96,0x8B,0x8E,0xB5, +0x16,0x0B,0x0E,0x32,0x97,0x8B,0x8E,0xB3,0x16,0x0A,0x0E,0x32,0x96,0x8A,0x8E,0xB1, +0x16,0x0B,0x0E,0x31,0x96,0x8B,0x8E,0xB1,0x16,0x0B,0x0E,0x31,0x97,0x8B,0x8E,0xB1, +0x16,0x0A,0x0E,0x30,0x97,0x8A,0x8E,0xAF,0x17,0x0B,0x0E,0x2F,0x97,0x8B,0x8E,0xAE, +}; + +enum state { + STATE_GROUND, + STATE_FE, + STATE_EFR_PRELIM, + STATE_EFR_CLASSIC, + STATE_EFR_AMR, + STATE_FR, +}; + +static enum state state; +static unsigned fe_byte_count, match_pos; + +void +pcmu_catcher_reset() +{ + state = STATE_GROUND; +} + +static void +report_match(name, offset) + char *name; + unsigned offset; +{ + offset++; + if (offset == 160) + offset = 0; + printf("Caught output of %s decoder at offset %u\n", name, offset); +} + +static void +process_sample(samp, offset) + unsigned samp, offset; +{ + if (samp == 0xFE) { + if (state != STATE_FE) { + state = STATE_FE; + fe_byte_count = 1; + } else if (fe_byte_count < 160) + fe_byte_count++; + return; + } + switch (state) { + case STATE_GROUND: + return; + case STATE_FE: + if (fe_byte_count < 160) { + state = STATE_GROUND; + return; + } + switch (samp) { + case 0x6F: + state = STATE_EFR_PRELIM; + return; + case 0xFF: + state = STATE_FR; + match_pos = 1; + return; + default: + state = STATE_GROUND; + } + return; + case STATE_EFR_PRELIM: + switch (samp) { + case 0x64: + state = STATE_EFR_CLASSIC; + match_pos = 2; + return; + case 0x66: + state = STATE_EFR_AMR; + match_pos = 2; + return; + default: + state = STATE_GROUND; + } + return; + case STATE_EFR_CLASSIC: + if (samp == match_frame_efr_classic[match_pos]) + match_pos++; + else { + state = STATE_GROUND; + return; + } + if (match_pos < 160) + return; + report_match("classic EFR", offset); + state = STATE_GROUND; + return; + case STATE_EFR_AMR: + if (samp == match_frame_amrefr_dec[match_pos]) + match_pos++; + else { + state = STATE_GROUND; + return; + } + if (match_pos < 160) + return; + report_match("AMR-EFR", offset); + state = STATE_GROUND; + return; + case STATE_FR: + if (samp == match_frame_fr[match_pos]) + match_pos++; + else { + state = STATE_GROUND; + return; + } + if (match_pos < 160) + return; + report_match("GSM-FR", offset); + state = STATE_GROUND; + return; + default: + state = STATE_GROUND; + } +} + +void +pcmu_catcher_process(inbuf) + uint8_t *inbuf; +{ + unsigned n; + + for (n = 0; n < 160; n++) + process_sample(inbuf[n], n); +} diff -r 71f01a834820 -r 4f81b959a5f5 test-voice/rtp_rx.c --- a/test-voice/rtp_rx.c Sat May 11 22:27:07 2024 -0800 +++ b/test-voice/rtp_rx.c Mon May 13 22:10:25 2024 -0800 @@ -40,6 +40,7 @@ { is_state = 0; is_hunt_fill = 0; + pcmu_catcher_reset(); } static void @@ -255,6 +256,11 @@ } for (is_chunk = 0; is_chunk < 10; is_chunk++) is_rx_process(pkt.payload + is_chunk * 16, is_chunk); + switch (pkt.m_pt & 0x7F) { + case PSTN_CODEC_PCMU: + pcmu_catcher_process(pkt.payload); + break; + } } void