From b6f34096af829f0e44d06d6767535b47b5c75dce Mon Sep 17 00:00:00 2001 From: Richard Fuchs <rfuchs@sipwise.com> Date: Fri, 14 Mar 2025 11:56:36 -0400 Subject: [PATCH] MT#55283 allow overriding T.38 version Change-Id: I2e8040774ceb7faaa65a2ec6e69bc67be0260caa --- daemon/call_interfaces.c | 12 ++++ daemon/codec.c | 5 ++ docs/ng_control_protocol.md | 8 +++ include/call_interfaces.h | 1 + t/auto-daemon-tests-t38.pl | 108 ++++++++++++++++++++++++++++++++++++ 5 files changed, 134 insertions(+) diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 8e8522922..90a5b398f 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1449,6 +1449,7 @@ void call_ng_flags_init(sdp_ng_flags *out, enum ng_opmode opmode) { out->frequencies = g_array_new(false, false, sizeof(int)); for (int i = 0; i < __MT_MAX; ++i) out->sdp_media_remove[i] = false; + out->t38_version = -1; } static void call_ng_direction_flag_iter(str *s, unsigned int i, helper_arg arg) { @@ -2115,6 +2116,17 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h case CSH_LOOKUP("t.38"): call_ng_flags_str_list(parser, value, ng_t38_option, out); break; + + case CSH_LOOKUP("T38-version"): + case CSH_LOOKUP("T.38-version"): + case CSH_LOOKUP("t38-version"): + case CSH_LOOKUP("t.38-version"): + case CSH_LOOKUP("T38 version"): + case CSH_LOOKUP("T.38 version"): + case CSH_LOOKUP("t38 version"): + case CSH_LOOKUP("t.38 version"): + out->t38_version = parser->get_int_str(value, out->t38_version); + break; #endif case CSH_LOOKUP("template"):; str *tplate = t_hash_table_lookup(rtpe_signalling_templates, &s); diff --git a/daemon/codec.c b/daemon/codec.c index 629235dfc..6c7b82efa 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -899,6 +899,10 @@ static void __t38_options_from_flags(struct t38_options *t_opts, const sdp_ng_fl t38_opt(no_v29); t38_opt(no_v34); t38_opt(no_iaf); +#undef t38_opt + + if (flags && flags->t38_version >= 0) + t_opts->version = flags->t38_version; } static void __check_t38_gateway(struct call_media *pcm_media, struct call_media *t38_media, @@ -914,6 +918,7 @@ static void __check_t38_gateway(struct call_media *pcm_media, struct call_media t_opts.fec_span = 3; t_opts.max_ec_entries = 3; } + __t38_options_from_flags(&t_opts, flags); MEDIA_SET(pcm_media, GENERATOR); diff --git a/docs/ng_control_protocol.md b/docs/ng_control_protocol.md index 5a466ad5d..d2d2769c8 100644 --- a/docs/ng_control_protocol.md +++ b/docs/ng_control_protocol.md @@ -860,6 +860,14 @@ Optionally included keys are: Use UDPTL FEC instead of redundancy. Only useful with `T.38=force` as it's a negotiated parameter. +* `T.38 version` + + Sets the T.38 version number to use for the T.38 gateway. The default is + version zero, or to go along with what has been advertised in the SDP if + responding to a received T.38 offer. Overriding the version to zero + regardless of what has been advertised in the SDP can solve T.38 gateway + problems against certain endpoints. + * `volume` Sets the tone volume for `DTMF-security` modes `tone`, `zero, `DTMF`, diff --git a/include/call_interfaces.h b/include/call_interfaces.h index e462ba1a7..4860ed648 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -155,6 +155,7 @@ struct sdp_ng_flags { str vsc_pause_rec; str vsc_pause_resume_rec; str vsc_start_pause_resume_rec; + int t38_version; #define X(x) str_q x; RTPE_NG_FLAGS_STR_Q_PARAMS diff --git a/t/auto-daemon-tests-t38.pl b/t/auto-daemon-tests-t38.pl index b2e0ca16f..01c66e7d6 100755 --- a/t/auto-daemon-tests-t38.pl +++ b/t/auto-daemon-tests-t38.pl @@ -681,6 +681,114 @@ t38_gw_test('FEC span 5', +new_call; + +offer('override T.38 version control', { 'T.38' => [ 'decode' ] }, <<SDP); +v=0 +o=- 1545997027 1 IN IP4 198.51.100.1 +s=tester +t=0 0 +m=image 4000 udptl t38 +c=IN IP4 198.51.100.1 +a=sendrecv +a=T38FaxVersion:1 +a=T38MaxBitRate:14400 +a=T38FaxRateManagement:transferredTCF +a=T38FaxMaxBuffer:262 +a=T38FaxMaxDatagram:300 +a=T38FaxUdpEC:t38UDPRedundancy +---------------------------------- +v=0 +o=- 1545997027 1 IN IP4 198.51.100.1 +s=tester +t=0 0 +m=audio PORT RTP/AVP 0 8 +c=IN IP4 203.0.113.1 +a=rtpmap:0 PCMU/8000 +a=rtpmap:8 PCMA/8000 +a=sendrecv +a=rtcp:PORT +SDP + +answer('override T.38 version control', { }, <<SDP); +v=0 +o=- 1545997027 1 IN IP4 198.51.100.3 +s=tester +t=0 0 +m=audio 4002 RTP/AVP 8 +c=IN IP4 198.51.100.3 +a=sendrecv +-------------------------------------- +v=0 +o=- 1545997027 1 IN IP4 198.51.100.3 +s=tester +t=0 0 +m=image PORT udptl t38 +c=IN IP4 203.0.113.1 +a=T38FaxVersion:1 +a=T38MaxBitRate:14400 +a=T38FaxRateManagement:transferredTCF +a=T38FaxMaxBuffer:1800 +a=T38FaxMaxDatagram:512 +a=T38FaxUdpEC:t38UDPRedundancy +a=sendrecv +SDP + + +new_call; + +offer('override T.38 version', { 'T.38' => [ 'decode' ], 'T.38 version' => 0 }, <<SDP); +v=0 +o=- 1545997027 1 IN IP4 198.51.100.1 +s=tester +t=0 0 +m=image 4000 udptl t38 +c=IN IP4 198.51.100.1 +a=sendrecv +a=T38FaxVersion:1 +a=T38MaxBitRate:14400 +a=T38FaxRateManagement:transferredTCF +a=T38FaxMaxBuffer:262 +a=T38FaxMaxDatagram:300 +a=T38FaxUdpEC:t38UDPRedundancy +---------------------------------- +v=0 +o=- 1545997027 1 IN IP4 198.51.100.1 +s=tester +t=0 0 +m=audio PORT RTP/AVP 0 8 +c=IN IP4 203.0.113.1 +a=rtpmap:0 PCMU/8000 +a=rtpmap:8 PCMA/8000 +a=sendrecv +a=rtcp:PORT +SDP + +answer('override T.38 version', { }, <<SDP); +v=0 +o=- 1545997027 1 IN IP4 198.51.100.3 +s=tester +t=0 0 +m=audio 4002 RTP/AVP 8 +c=IN IP4 198.51.100.3 +a=sendrecv +-------------------------------------- +v=0 +o=- 1545997027 1 IN IP4 198.51.100.3 +s=tester +t=0 0 +m=image PORT udptl t38 +c=IN IP4 203.0.113.1 +a=T38FaxVersion:0 +a=T38MaxBitRate:14400 +a=T38FaxRateManagement:transferredTCF +a=T38FaxMaxBuffer:1800 +a=T38FaxMaxDatagram:512 +a=T38FaxUdpEC:t38UDPRedundancy +a=sendrecv +SDP + + # XXX packet loss tests # XXX tests of different SDP options