From 2a50c2910144e1b4095d171b1386fd5ebb0c5b5a Mon Sep 17 00:00:00 2001 From: Aaron An Date: Tue, 30 Aug 2016 11:26:03 +0800 Subject: res/res_pjsip: Add preferred_codec_only config to pjsip endpoint. This patch add config to pjsip by endpoint. ;preferred_codec_only=yes ; Respond to a SIP invite with the single most preferred codec ; rather than advertising all joint codec capabilities. This ; limits the other side's codec choice to exactly what we prefer. ASTERISK-26317 #close Reported by: AaronAn Tested by: AaronAn Change-Id: Iad04dc55055403bbf5ec050997aee2dadc4f0762 --- CHANGES | 7 +++++ configs/samples/pjsip.conf.sample | 4 +++ ...318_add_preferred_codec_only_option_to_pjsip.py | 30 ++++++++++++++++++++++ include/asterisk/res_pjsip.h | 2 ++ res/res_pjsip.c | 6 +++++ res/res_pjsip/pjsip_configuration.c | 1 + res/res_pjsip_sdp_rtp.c | 9 +++++-- res/res_pjsip_session.c | 8 ++++-- 8 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 contrib/ast-db-manage/config/versions/7f3e21abe318_add_preferred_codec_only_option_to_pjsip.py diff --git a/CHANGES b/CHANGES index 5857165c8..6032dd8a0 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,13 @@ ------------------------------------------------------------------------------ +res_pjsip +------------------ + * Added endpoint configuration parameter "preferred_codec_only". + This allow asterisk response to a SIP invite with the single most + preferred codec rather than advertising all joint codec capabilities. + This limits the other side's codec choice to exactly what we prefer. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 14.0.0 to Asterisk 14.1.0 ---------- ------------------------------------------------------------------------------ diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample index 0d1c03909..e6b32495b 100644 --- a/configs/samples/pjsip.conf.sample +++ b/configs/samples/pjsip.conf.sample @@ -764,6 +764,10 @@ ; "0" or not enabled) ;contact_user= ; On outgoing requests, force the user portion of the Contact ; header to this value (default: "") +;preferred_codec_only=yes ; Respond to a SIP invite with the single most preferred codec + ; rather than advertising all joint codec capabilities. This + ; limits the other side's codec choice to exactly what we prefer. + ; default is no. ;==========================AUTH SECTION OPTIONS========================= ;[auth] diff --git a/contrib/ast-db-manage/config/versions/7f3e21abe318_add_preferred_codec_only_option_to_pjsip.py b/contrib/ast-db-manage/config/versions/7f3e21abe318_add_preferred_codec_only_option_to_pjsip.py new file mode 100644 index 000000000..083d08966 --- /dev/null +++ b/contrib/ast-db-manage/config/versions/7f3e21abe318_add_preferred_codec_only_option_to_pjsip.py @@ -0,0 +1,30 @@ +"""add preferred_codec_only option to pjsip + +Revision ID: 7f3e21abe318 +Revises: 4e2493ef32e6 +Create Date: 2016-09-02 11:00:23.534748 + +""" + +# revision identifiers, used by Alembic. +revision = '7f3e21abe318' +down_revision = '4e2493ef32e6' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects.postgresql import ENUM + +YESNO_NAME = 'yesno_values' +YESNO_VALUES = ['yes', 'no'] + +def upgrade(): + ############################# Enums ############################## + + # yesno_values have already been created, so use postgres enum object + # type to get around "already created" issue - works okay with mysql + yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False) + + op.add_column('ps_endpoints', sa.Column('preferred_codec_only', yesno_values)) + +def downgrade(): + op.drop_column('ps_endpoints', 'preferred_codec_only') diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 4cede4391..8a5ad29c5 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -757,6 +757,8 @@ struct ast_sip_endpoint { unsigned int faxdetect_timeout; /*! Override the user on the outgoing Contact header with this value. */ char *contact_user; + /*! Whether to response SDP offer with single most preferred codec. */ + unsigned int preferred_codec_only; }; /*! diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 34edc8ca5..7bb10c07f 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -833,6 +833,9 @@ have this accountcode set on it. + + Respond to a SIP invite with the single most preferred codec rather than advertising all joint codec capabilities. This limits the other side's codec choice to exactly what we prefer. + Number of seconds between RTP comfort noise keepalive packets. @@ -2022,6 +2025,9 @@ + + + The aggregate device state for this endpoint. diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 333be7143..97c357a9e 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1933,6 +1933,7 @@ int ast_res_pjsip_initialize_configuration(void) ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_acl", "", endpoint_acl_handler, contact_acl_to_str, NULL, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "subscribe_context", "", OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct ast_sip_endpoint, subscription.context)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_user", "", contact_user_handler, contact_user_to_str, NULL, 0, 0); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "preferred_codec_only", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, preferred_codec_only)); if (ast_sip_initialize_sorcery_transport()) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n"); diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 6610ef126..68d5fdb56 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -360,8 +360,13 @@ static int set_caps(struct ast_sip_session *session, ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(session->channel), AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_remove_by_type(caps, media_type); - ast_format_cap_append_from_cap(caps, joint, media_type); - + if (session->endpoint->preferred_codec_only){ + struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0); + ast_format_cap_append(caps, preferred_fmt, 0); + ao2_ref(preferred_fmt, -1); + } else { + ast_format_cap_append_from_cap(caps, joint, media_type); + } /* * Apply the new formats to the channel, potentially changing * raw read/write formats and translation path while doing so. diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 315393fdb..0ab45c74e 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -1247,7 +1247,9 @@ int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data pjsip_inv_set_local_sdp(session->inv_session, offer); pjmedia_sdp_neg_set_prefer_remote_codec_order(session->inv_session->neg, PJ_FALSE); #ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS - pjmedia_sdp_neg_set_answer_multiple_codecs(session->inv_session->neg, PJ_TRUE); + if (!session->endpoint->preferred_codec_only) { + pjmedia_sdp_neg_set_answer_multiple_codecs(session->inv_session->neg, PJ_TRUE); + } #endif /* @@ -2141,7 +2143,9 @@ static int new_invite(void *data) pjsip_inv_set_local_sdp(invite->session->inv_session, local); pjmedia_sdp_neg_set_prefer_remote_codec_order(invite->session->inv_session->neg, PJ_FALSE); #ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS - pjmedia_sdp_neg_set_answer_multiple_codecs(invite->session->inv_session->neg, PJ_TRUE); + if (!invite->session->endpoint->preferred_codec_only) { + pjmedia_sdp_neg_set_answer_multiple_codecs(invite->session->inv_session->neg, PJ_TRUE); + } #endif } -- cgit v1.2.3