diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 3ccdc4e40..5a64a74e8 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1315,6 +1315,7 @@ void call_ng_flags_init(sdp_ng_flags *out, enum call_opmode opmode) { out->volume = 9999; out->digit = -1; out->frequencies = g_array_new(false, false, sizeof(int)); + out->t38_version = -1; } static void call_ng_dict_iter(sdp_ng_flags *out, bencode_item_t *input, @@ -1949,6 +1950,17 @@ void call_ng_main_flags(sdp_ng_flags *out, str *key, bencode_item_t *value, case CSH_LOOKUP("t.38"): call_ng_flags_str_list(out, value, ng_t38_option, NULL); 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 = bencode_get_integer_str(value, out->t38_version); + break; #endif case CSH_LOOKUP("to-interface"): out->direction[1] = s; diff --git a/daemon/codec.c b/daemon/codec.c index 00a8148f3..7c267acad 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -872,6 +872,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, @@ -887,6 +891,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 0cb05ee97..c7910e01f 100644 --- a/docs/ng_control_protocol.md +++ b/docs/ng_control_protocol.md @@ -844,6 +844,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 e456c4698..22ff824cf 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -141,6 +141,7 @@ struct sdp_ng_flags { str vsc_pause_rec; str vsc_pause_resume_rec; str vsc_start_pause_resume_rec; + int t38_version; unsigned int asymmetric:1, protocol_accept:1, diff --git a/t/auto-daemon-tests-t38.pl b/t/auto-daemon-tests-t38.pl index a740d6f4b..cd3bdf784 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' ] }, < [ 'decode' ], 'T.38 version' => 0 }, <