Make chan_h323 respect packetization settings and fix small reload issue.

Previously, packetization settings were ignored and now they are not. A new
config option 'autoframing' has been added to mirror the way chan_sip handles
it. Turning on the autoframing option (available both as a global option or per
peer) overrides the local settings with the remote packetization settings.
Testing was performed with varying packetization levels with the following
codecs: ulaw, alaw, gsm, and g729.

Also, an unrelated config reload issue has been fixed in the case of the config
file not changing.

(closes issue #12415)
Reported by: pj
Patches:
      2009012200_h323packetization.diff.txt uploaded by mvanbaak (license 7), 
      modified by me


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@189993 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/1.8.6
Jeff Peeler 16 years ago
parent 3b64f588e2
commit 2f8da7106d

@ -1251,6 +1251,8 @@ static int update_common_options(struct ast_variable *v, struct call_options *op
if (!strcasecmp(v->name, "allow")) { if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1); ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
} else if (!strcasecmp(v->name, "autoframing")) {
options->autoframing = ast_true(v->value);
} else if (!strcasecmp(v->name, "disallow")) { } else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0); ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
} else if (!strcasecmp(v->name, "dtmfmode")) { } else if (!strcasecmp(v->name, "dtmfmode")) {
@ -2450,8 +2452,15 @@ static void set_peer_capabilities(unsigned call_reference, const char *token, in
ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]); ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]);
} }
} }
if (pvt->rtp) if (pvt->rtp) {
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->peer_prefs); if (pvt->options.autoframing) {
ast_debug(2, "Autoframing option set, using peer's packetization settings\n");
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->peer_prefs);
} else {
ast_debug(2, "Autoframing option not set, ignoring peer's packetization settings\n");
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->options.prefs);
}
}
} }
ast_mutex_unlock(&pvt->lock); ast_mutex_unlock(&pvt->lock);
} }
@ -2475,8 +2484,15 @@ static void set_local_capabilities(unsigned call_reference, const char *token)
ast_mutex_unlock(&pvt->lock); ast_mutex_unlock(&pvt->lock);
h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec); h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
if (h323debug) if (h323debug) {
int i;
for (i = 0; i < 32; i++) {
if (!prefs.order[i])
break;
ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(1 << (prefs.order[i]-1)) : "<none>"), prefs.framing[i]);
}
ast_debug(1, "Capabilities for connection %s is set\n", token); ast_debug(1, "Capabilities for connection %s is set\n", token);
}
} }
static void remote_hold(unsigned call_reference, const char *token, int is_hold) static void remote_hold(unsigned call_reference, const char *token, int is_hold)
@ -2838,7 +2854,7 @@ static int reload_config(int is_reload)
return 0; return 0;
} }
ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
if ((cfg = ast_config_load(config, config_flags))) { if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config); ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
ast_config_destroy(ucfg); ast_config_destroy(ucfg);
return 0; return 0;
@ -2878,6 +2894,7 @@ static int reload_config(int is_reload)
global_options.holdHandling = 0; global_options.holdHandling = 0;
global_options.capability = GLOBAL_CAPABILITY; global_options.capability = GLOBAL_CAPABILITY;
global_options.bridge = 1; /* Do native bridging by default */ global_options.bridge = 1; /* Do native bridging by default */
global_options.autoframing = 0;
strcpy(default_context, "default"); strcpy(default_context, "default");
h323_signalling_port = 1720; h323_signalling_port = 1720;
gatekeeper_disable = 1; gatekeeper_disable = 1;

@ -1773,8 +1773,6 @@ PBoolean MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remo
format = ast_codec_pref_getsize(&prefs, ast_codec); format = ast_codec_pref_getsize(&prefs, ast_codec);
if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) { if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) {
ms = remoteCapabilities[i].GetTxFramesInPacket(); ms = remoteCapabilities[i].GetTxFramesInPacket();
if (ms > 60)
ms = format.cur_ms;
} else } else
ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms; ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms;
ast_codec_pref_setsize(&prefs, ast_codec, ms); ast_codec_pref_setsize(&prefs, ast_codec, ms);
@ -1900,7 +1898,6 @@ void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, in
struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs; struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs;
struct ast_format_list format; struct ast_format_list format;
int frames_per_packet; int frames_per_packet;
int max_frames_per_packet;
H323Capability *cap; H323Capability *cap;
localCapabilities.RemoveAll(); localCapabilities.RemoveAll();
@ -1925,9 +1922,9 @@ void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, in
if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK)) if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))
continue; continue;
alreadysent |= codec; alreadysent |= codec;
/* format.cur_ms will be set to default if packetization is not explicitly set */
format = ast_codec_pref_getsize(prefs, codec); format = ast_codec_pref_getsize(prefs, codec);
frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms); frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms);
max_frames_per_packet = (format.inc_ms ? format.max_ms / format.inc_ms : 0);
switch(codec) { switch(codec) {
#if 0 #if 0
case AST_FORMAT_SPEEX: case AST_FORMAT_SPEEX:
@ -1947,43 +1944,35 @@ void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, in
AST_G729Capability *g729Cap; AST_G729Capability *g729Cap;
lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability(frames_per_packet)); lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability(frames_per_packet));
lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability(frames_per_packet)); lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability(frames_per_packet));
if (max_frames_per_packet) { g729aCap->SetTxFramesInPacket(format.cur_ms);
g729aCap->SetTxFramesInPacket(max_frames_per_packet); g729Cap->SetTxFramesInPacket(format.cur_ms);
g729Cap->SetTxFramesInPacket(max_frames_per_packet);
}
break; break;
case AST_FORMAT_G723_1: case AST_FORMAT_G723_1:
AST_G7231Capability *g7231Cap; AST_G7231Capability *g7231Cap;
lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, TRUE)); lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, TRUE));
if (max_frames_per_packet) g7231Cap->SetTxFramesInPacket(format.cur_ms);
g7231Cap->SetTxFramesInPacket(max_frames_per_packet);
lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, FALSE)); lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, FALSE));
if (max_frames_per_packet) g7231Cap->SetTxFramesInPacket(format.cur_ms);
g7231Cap->SetTxFramesInPacket(max_frames_per_packet);
break; break;
case AST_FORMAT_GSM: case AST_FORMAT_GSM:
AST_GSM0610Capability *gsmCap; AST_GSM0610Capability *gsmCap;
lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new AST_GSM0610Capability(frames_per_packet)); lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new AST_GSM0610Capability(frames_per_packet));
if (max_frames_per_packet) gsmCap->SetTxFramesInPacket(format.cur_ms);
gsmCap->SetTxFramesInPacket(max_frames_per_packet);
break; break;
case AST_FORMAT_ULAW: case AST_FORMAT_ULAW:
AST_G711Capability *g711uCap; AST_G711Capability *g711uCap;
lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::muLaw)); lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::muLaw));
if (format.max_ms) g711uCap->SetTxFramesInPacket(format.cur_ms);
g711uCap->SetTxFramesInPacket(format.max_ms);
break; break;
case AST_FORMAT_ALAW: case AST_FORMAT_ALAW:
AST_G711Capability *g711aCap; AST_G711Capability *g711aCap;
lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::ALaw)); lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::ALaw));
if (format.max_ms) g711aCap->SetTxFramesInPacket(format.cur_ms);
g711aCap->SetTxFramesInPacket(format.max_ms);
break; break;
case AST_FORMAT_G726_AAL2: case AST_FORMAT_G726_AAL2:
AST_CiscoG726Capability *g726Cap; AST_CiscoG726Capability *g726Cap;
lastcap = localCapabilities.SetCapability(0, 0, g726Cap = new AST_CiscoG726Capability(frames_per_packet)); lastcap = localCapabilities.SetCapability(0, 0, g726Cap = new AST_CiscoG726Capability(frames_per_packet));
if (max_frames_per_packet) g726Cap->SetTxFramesInPacket(format.cur_ms);
g726Cap->SetTxFramesInPacket(max_frames_per_packet);
break; break;
default: default:
alreadysent &= ~codec; alreadysent &= ~codec;

@ -69,6 +69,7 @@ typedef struct call_options {
int nat; int nat;
int tunnelOptions; int tunnelOptions;
int holdHandling; int holdHandling;
int autoframing; /*!< turn on to override local settings with remote framing length */
struct ast_codec_pref prefs; struct ast_codec_pref prefs;
} call_options_t; } call_options_t;

Loading…
Cancel
Save