TT#78501 add T.38 options

Change-Id: I4f173f384db18e832c1d24a7015a836ec4215a96
changes/99/38999/4
Richard Fuchs 5 years ago
parent 213b6074f4
commit d611bbbb74

@ -1122,6 +1122,35 @@ Optionally included keys are:
or `force` flags. This is useful to handle a rejected T.38 offer and revert the
session back to media passthrough.
- `no-ECM`
Disable support for ECM. Support is enabled by default.
- `no-V.17`
Disable support for V.17. Support is enabled by default.
- `no-V.27ter`
Disable support for V.27ter. Support is enabled by default.
- `no-V.29`
Disable support for V.29. Support is enabled by default.
- `no-V.34`
Disable support for V.34. Support is enabled by default.
- `no-IAF`
Disable support for IAF. Support is enabled by default.
- `FEC`
Use UDPTL FEC instead of redundancy. Only useful with `T.38=force` as
it's a negotiated parameter.
* `supports`
Contains a list of strings. Each string indicates support for an additional feature

@ -550,6 +550,7 @@ INLINE void ng_sdes_option(struct sdp_ng_flags *out, str *s, void *dummy) {
#ifdef WITH_TRANSCODING
INLINE void ng_t38_option(struct sdp_ng_flags *out, str *s, void *dummy) {
str_hyphenate(s);
switch (__csh_lookup(s)) {
case CSH_LOOKUP("decode"):
out->t38_decode = 1;
@ -560,6 +561,72 @@ INLINE void ng_t38_option(struct sdp_ng_flags *out, str *s, void *dummy) {
case CSH_LOOKUP("stop"):
out->t38_stop = 1;
break;
case CSH_LOOKUP("no-ECM"):
out->t38_no_ecm = 1;
break;
case CSH_LOOKUP("no-V17"):
out->t38_no_v17 = 1;
break;
case CSH_LOOKUP("no-V.17"):
out->t38_no_v17 = 1;
break;
case CSH_LOOKUP("no-V.27ter"):
out->t38_no_v27ter = 1;
break;
case CSH_LOOKUP("no-V27ter"):
out->t38_no_v27ter = 1;
break;
case CSH_LOOKUP("no-V29"):
out->t38_no_v29 = 1;
break;
case CSH_LOOKUP("no-V.29"):
out->t38_no_v29 = 1;
break;
case CSH_LOOKUP("no-V34"):
out->t38_no_v34 = 1;
break;
case CSH_LOOKUP("no-V.34"):
out->t38_no_v34 = 1;
break;
case CSH_LOOKUP("no-IAF"):
out->t38_no_iaf = 1;
break;
case CSH_LOOKUP("no-ecm"):
out->t38_no_ecm = 1;
break;
case CSH_LOOKUP("no-v17"):
out->t38_no_v17 = 1;
break;
case CSH_LOOKUP("no-v.17"):
out->t38_no_v17 = 1;
break;
case CSH_LOOKUP("no-v.27ter"):
out->t38_no_v27ter = 1;
break;
case CSH_LOOKUP("no-v27ter"):
out->t38_no_v27ter = 1;
break;
case CSH_LOOKUP("no-v29"):
out->t38_no_v29 = 1;
break;
case CSH_LOOKUP("no-v.29"):
out->t38_no_v29 = 1;
break;
case CSH_LOOKUP("no-v34"):
out->t38_no_v34 = 1;
break;
case CSH_LOOKUP("no-v.34"):
out->t38_no_v34 = 1;
break;
case CSH_LOOKUP("no-iaf"):
out->t38_no_iaf = 1;
break;
case CSH_LOOKUP("FEC"):
out->t38_fec = 1;
break;
case CSH_LOOKUP("fec"):
out->t38_fec = 1;
break;
default:
ilog(LOG_WARN, "Unknown 'T.38' flag encountered: '" STR_FORMAT "'",
STR_FMT(s));

@ -697,26 +697,37 @@ static void __generator_stop(struct call_media *media) {
}
}
static void __t38_options_from_flags(struct t38_options *t_opts, const struct sdp_ng_flags *flags) {
#define t38_opt(name) t_opts->name = flags->t38_ ## name
t38_opt(no_ecm);
t38_opt(no_v17);
t38_opt(no_v27ter);
t38_opt(no_v29);
t38_opt(no_v34);
t38_opt(no_iaf);
}
static void __check_t38_gateway(struct call_media *pcm_media, struct call_media *t38_media,
const struct stream_params *sp)
const struct stream_params *sp, const struct sdp_ng_flags *flags)
{
const struct t38_options *t_opts;
struct t38_options t_opts_stor = {0,};
struct t38_options t_opts = {0,};
if (sp)
t_opts = &sp->t38_options;
t_opts = sp->t38_options;
else {
// create our own options
t_opts_stor.max_ec_entries = 3;
t_opts = &t_opts_stor;
if (flags->t38_fec)
t_opts.fec_span = 3;
t_opts.max_ec_entries = 3;
}
__t38_options_from_flags(&t_opts, flags);
MEDIA_SET(pcm_media, TRANSCODE);
MEDIA_SET(pcm_media, GENERATOR);
MEDIA_SET(t38_media, TRANSCODE);
MEDIA_SET(t38_media, GENERATOR);
if (t38_gateway_pair(t38_media, pcm_media, t_opts))
if (t38_gateway_pair(t38_media, pcm_media, &t_opts))
return;
// need a packet handler on the T.38 side
@ -745,14 +756,16 @@ static void __check_t38_gateway(struct call_media *pcm_media, struct call_media
}
// call must be locked in W
static int codec_handler_udptl_update(struct call_media *receiver, struct call_media *sink) {
static int codec_handler_udptl_update(struct call_media *receiver, struct call_media *sink,
const struct sdp_ng_flags *flags)
{
// anything to do?
if (proto_is(sink->protocol, PROTO_UDPTL))
return 0;
if (sink->type_id == MT_AUDIO && proto_is_rtp(sink->protocol) && receiver->type_id == MT_IMAGE) {
if (!str_cmp(&receiver->format_str, "t38")) {
__check_t38_gateway(sink, receiver, NULL);
__check_t38_gateway(sink, receiver, NULL, flags);
return 1;
}
}
@ -769,7 +782,7 @@ static int codec_handler_non_rtp_update(struct call_media *receiver, struct call
const struct sdp_ng_flags *flags, const struct stream_params *sp)
{
if (proto_is(sink->protocol, PROTO_UDPTL) && !str_cmp(&sink->format_str, "t38")) {
__check_t38_gateway(receiver, sink, sp);
__check_t38_gateway(receiver, sink, sp, flags);
return 1;
}
ilog(LOG_WARN, "Unsupported non-RTP protocol: " STR_FORMAT "/" STR_FORMAT
@ -790,7 +803,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
// non-RTP protocol?
if (proto_is(receiver->protocol, PROTO_UDPTL)) {
if (codec_handler_udptl_update(receiver, sink))
if (codec_handler_udptl_update(receiver, sink, flags))
return;
}
// everything else is unsupported: pass through

@ -390,10 +390,14 @@ int t38_gateway_pair(struct call_media *t38_media, struct call_media *pcm_media,
// set options
t38_core_state_t *t38 = t38_gateway_get_t38_core_state(tg->gw);
t38_gateway_set_ecm_capability(tg->gw, TRUE);
t38_gateway_set_ecm_capability(tg->gw, opts.no_ecm ? FALSE : TRUE);
t38_gateway_set_transmit_on_idle(tg->gw, TRUE);
t38_gateway_set_supported_modems(tg->gw, T30_SUPPORT_V17 | T30_SUPPORT_V27TER | T30_SUPPORT_V29
| T30_SUPPORT_V34HDX | T30_SUPPORT_IAF);
t38_gateway_set_supported_modems(tg->gw,
(opts.no_v17 ? 0 : T30_SUPPORT_V17)
| (opts.no_v27ter ? 0 : T30_SUPPORT_V27TER)
| (opts.no_v29 ? 0 : T30_SUPPORT_V29)
| (opts.no_v34 ? 0 : T30_SUPPORT_V34HDX)
| (opts.no_iaf ? 0 : T30_SUPPORT_IAF));
t38_set_t38_version(t38, opts.version);
t38_set_data_rate_management_method(t38,
opts.local_tcf ? 1 : 2);

@ -80,6 +80,13 @@ struct sdp_ng_flags {
t38_decode:1,
t38_force:1,
t38_stop:1,
t38_no_ecm:1,
t38_no_v17:1,
t38_no_v27ter:1,
t38_no_v29:1,
t38_no_v34:1,
t38_no_iaf:1,
t38_fec:1,
supports_load_limit:1,
dtls_off:1,
sdes_off:1,

@ -16,6 +16,13 @@ struct t38_options {
int fill_bit_removal:1;
int transcoding_mmr:1;
int transcoding_jbig:1;
int no_ecm:1;
int no_v17:1;
int no_v27ter:1;
int no_v29:1;
int no_v34:1;
int no_iaf:1;
};

@ -917,7 +917,39 @@ rtpe_req('delete', "delete", { 'from-tag' => ft() });
new_call;
offer('T.38 FEC invite', { ICE => 'remove', 'T.38' => [ 'force', 'FEC' ],
}, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio 6000 RTP/AVP 8 0
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:t38UDPFEC
a=sendrecv
SDP
rtpe_req('delete', "delete", { 'from-tag' => ft() });
done_testing();
exit;
# github issue 850

Loading…
Cancel
Save