diff --git a/CHANGES b/CHANGES index d1cc9009f8d0090ca6517d7b01bdb9bd246f9a9b..0d397303cf43becbc0fa37a2494f040a5748e285 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,13 @@ res_pjsip RECOMMENDED), keep the current behavior, or trigger only on pjsip taskprocessor overloads. +chan_pjsip +------------------ + * A new configuration parameter 'ignore_183_without_sdp' has been added + to the pjsip.conf "endpoints" section. If enabled, will make chan_pjsip + discard 183s that do not contain an SDP body, which can resolve no + ringback tone issues as well as making the behavior match chan_sip. + MWI ------------------ * A new module "res_mwi_devstate" has been added that allows subscriptions diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 062fb7ccc3c7e650096d85f6684db0b536e26217..36cc0ad3b99ad7bb71a5e1d5fbc0672bfccb72e2 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -2742,7 +2742,14 @@ static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct ast_channel_unlock(session->channel); break; case 183: - ast_queue_control(session->channel, AST_CONTROL_PROGRESS); + if (session->endpoint->ignore_183_without_sdp) { + pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata); + if (sdp && sdp->body.ptr) { + ast_queue_control(session->channel, AST_CONTROL_PROGRESS); + } + } else { + ast_queue_control(session->channel, AST_CONTROL_PROGRESS); + } break; case 200: ast_queue_control(session->channel, AST_CONTROL_ANSWER); diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample index 18d8d223e35eabe4c070dfc4ca9881a36ebe9fce..574efeef9dae0e3ac10b83d5b458cd0d025cfae1 100644 --- a/configs/samples/pjsip.conf.sample +++ b/configs/samples/pjsip.conf.sample @@ -826,6 +826,15 @@ ; headers are received. This option allows the ; 'Q.850' Reason header to be suppressed. ; (default: no) +;ignore_183_without_sdp = + ; Do not forward 183 when it doesn't contain SDP. + ; Certain SS7 internetworking scenarios can result in + ; a 183 to be generated for reasons other than early + ; media. Forwarding this 183 can cause loss of + ; ringback tone. This flag emulates the behavior of + ; chan_sip and prevents these 183 responses from + ; being forwarded. + ; (default: no) ;==========================AUTH SECTION OPTIONS========================= ;[auth] diff --git a/contrib/ast-db-manage/config/versions/80473bad3c16_ignore_183_without_sdp.py b/contrib/ast-db-manage/config/versions/80473bad3c16_ignore_183_without_sdp.py new file mode 100644 index 0000000000000000000000000000000000000000..d05e2d5658a9f56b9c9b9974e4c4ac7c6a3639e7 --- /dev/null +++ b/contrib/ast-db-manage/config/versions/80473bad3c16_ignore_183_without_sdp.py @@ -0,0 +1,38 @@ +"""ignore 183 without sdp + +Revision ID: 80473bad3c16 +Revises: f3c0b8695b66 +Create Date: 2019-03-04 08:30:51.592907 + +""" + +# revision identifiers, used by Alembic. +revision = '80473bad3c16' +down_revision = 'f3c0b8695b66' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects.postgresql import ENUM + +AST_BOOL_NAME = 'ast_bool_values' +# We'll just ignore the n/y and f/t abbreviations as Asterisk does not write +# those aliases. +AST_BOOL_VALUES = [ '0', '1', + 'off', 'on', + 'false', 'true', + 'no', 'yes' ] + +def upgrade(): + ############################# Enums ############################## + + # ast_bool_values has already been created, so use postgres enum object + # type to get around "already created" issue - works okay with mysql + ast_bool_values = ENUM(*AST_BOOL_VALUES, name=AST_BOOL_NAME, create_type=False) + + op.add_column('ps_endpoints', sa.Column('ignore_183_without_sdp', ast_bool_values)) + +def downgrade(): + if op.get_context().bind.dialect.name == 'mssql': + op.drop_constraint('ck_ps_endpoints_ignore_183_without_sdp_ast_bool_values', 'ps_endpoints') + op.drop_column('ps_endpoints', 'ignore_183_without_sdp') + pass diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 681814c774ee2276c2aa4ed3076d86dd2316ae4d..79c29cc90a1123058f3ebccacdd7ce2965db4be8 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -800,6 +800,8 @@ struct ast_sip_endpoint { unsigned int trust_connected_line; /*! Do we send connected line updates to this endpoint? */ unsigned int send_connected_line; + /*! Ignore 183 if no SDP is present */ + unsigned int ignore_183_without_sdp; }; /*! URI parameter for symmetric transport */ diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 32277b1ab8998136c69149d28ec5a584cb6342c8..2d5f0da1ac2910a1e03a1f8d57dd074c77604d01 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1074,6 +1074,16 @@ option allows the 'Q.850' Reason header to be suppressed.</para> </description> </configOption> + <configOption name="ignore_183_without_sdp" default="no"> + <synopsis>Do not forward 183 when it doesn't contain SDP</synopsis> + <description><para> + Certain SS7 internetworking scenarios can result in a 183 + to be generated for reasons other than early media. Forwarding + this 183 can cause loss of ringback tone. This flag emulates + the behavior of chan_sip and prevents these 183 responses from + being forwarded.</para> + </description> + </configOption> </configObject> <configObject name="auth"> <synopsis>Authentication type</synopsis> diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 40948c38abf96fc9006789bab14918ed9ae94cde..4f7beb6098ece5d4c2d07c1c6859d1f787293878 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1901,6 +1901,7 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod ast_sorcery_object_field_register(sip_sorcery, "endpoint", "follow_early_media_fork", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, follow_early_media_fork)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "accept_multiple_sdp_answers", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, accept_multiple_sdp_answers)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "suppress_q850_reason_headers", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, suppress_q850_reason_headers)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "ignore_183_without_sdp", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, ignore_183_without_sdp)); if (ast_sip_initialize_sorcery_transport()) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");