Index: channels/chan_iax2.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v retrieving revision 1.237 diff -u -r1.237 chan_iax2.c --- channels/chan_iax2.c 14 Jan 2005 21:10:16 -0000 1.237 +++ channels/chan_iax2.c 15 Jan 2005 06:31:29 -0000 @@ -2367,6 +2367,44 @@ return tmp; } +/* Sub-function of iax2_call. Allows format and capability override. */ +static void iax2_call_set_codecs(struct iax_ie_data *ie_data, struct ast_channel *channel, struct chan_iax2_pvt* pvt) +{ + /* Shares code with chan_sip.c::sip_call */ + /* CODEC_OVERRIDE can override the selection for available codecs. + Ensure dialplan sets var with leading underscore so it gets passed. + Override does not check capabilities. This is so that a type=friend can limit what they accept via the .conf, + yet still allow different codecs at runtime. */ + + int format = channel->nativeformats; /* Default to using the current native format */ + int capability = pvt->capability; + int override_format = 0; + char *codec_override; + + codec_override = pbx_builtin_getvar_helper(channel, "CODEC_OVERRIDE"); + if (codec_override && !ast_strlen_zero(codec_override)) { + override_format = ast_getformatbyname(codec_override); + if (override_format) { + if ((override_format & pvt->capability) & (option_verbose > 2)) { + ast_verbose(VERBOSE_PREFIX_3 "CODEC_OVERRIDE: Forcing format for this call to %s\n", codec_override); + } else if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "CODEC_OVERRIDE: Forcing format for this call to %s (0x%x), even though not in current capabilities (0x%x).\n", + codec_override, + override_format, + pvt->capability); + } + format = override_format; + capability = override_format; + } else { + ast_log(LOG_NOTICE, "Ignoring CODEC_OVERRIDE variable: Unknown codec '%s'.\n", codec_override); + } + } + + pvt->capability = capability; + iax_ie_append_int(ie_data, IAX_IE_FORMAT, format); + iax_ie_append_int(ie_data, IAX_IE_CAPABILITY, capability); +} + static int iax2_call(struct ast_channel *c, char *dest, int timeout) { struct sockaddr_in sin; @@ -2499,8 +2537,7 @@ } else strncpy(iaxs[callno]->secret, secret, sizeof(iaxs[callno]->secret)-1); } - iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); - iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); + iax2_call_set_codecs(&ied, c, iaxs[callno]); iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(tz)); /* Transmit the string in a "NEW" request */ Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.631 diff -u -r1.631 chan_sip.c --- channels/chan_sip.c 13 Jan 2005 20:26:33 -0000 1.631 +++ channels/chan_sip.c 15 Jan 2005 06:31:39 -0000 @@ -1386,14 +1386,15 @@ struct varshead *headp; struct ast_var_t *current; int addsipheaders = 0; - + char *codec_override; + int override_format; + p = ast->pvt->pvt; if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); return -1; } /* Check whether there is vxml_url, distinctive ring variables */ - headp=&ast->varshead; AST_LIST_TRAVERSE(headp,current,entries) { /* Check whether there is a VXML_URL variable */ @@ -1432,7 +1433,31 @@ res = update_user_counter(p,INC_OUT_USE); if ( res != -1 ) { p->callingpres = ast->cid.cid_pres; + + /* Shares code with chan_iax2.c::iax2_call_set_codecs */ + /* Handle CODEC_OVERRIDE (override capabilities). Ensure dialplan sets var with leading underscore so it gets passed. + Override does not check capabilities. This is so that a type=friend can limit what they accept via the .conf, + yet still allow different codecs at runtime. */ + codec_override = pbx_builtin_getvar_helper(ast, "CODEC_OVERRIDE"); + if (codec_override && !ast_strlen_zero(codec_override)) { + override_format = ast_getformatbyname(codec_override); + if (override_format) { + if ((override_format & p->capability) & (option_verbose > 2)) { + ast_verbose(VERBOSE_PREFIX_3 "CODEC_OVERRIDE: Forcing format for this call to %s\n", codec_override); + } else if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "CODEC_OVERRIDE: Forcing format for this call to %s (0x%x), even though not in current capabilities (0x%x).\n", + codec_override, + override_format, + p->capability); + } + p->prefcodec = override_format; + p->capability = override_format; + } else { + ast_log(LOG_NOTICE, "Ignoring CODEC_OVERRIDE variable: Unknown codec '%s'.\n", codec_override); + } + } p->jointcapability = p->capability; + transmit_invite(p, "INVITE", 1, NULL, NULL, vxml_url,distinctive_ring, osptoken, addsipheaders, 1); if (p->maxtime) { /* Initialize auto-congest time */ @@ -3343,6 +3368,7 @@ add_line(req, tmp); return 0; } + /*--- add_sdp: Add Session Description Protocol message ---*/ static int add_sdp(struct sip_request *resp, struct sip_pvt *p)