From: Joshua Colp Date: Fri, 17 Oct 2014 11:30:23 +0000 (+0000) Subject: res_pjsip: Add 'user_eq_phone' option to add a 'user=phone' parameter when applicable. X-Git-Tag: 14.0.0-beta1~1543 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7144c739e97aca9e69b2067238deeedeafbc478f;p=thirdparty%2Fasterisk.git res_pjsip: Add 'user_eq_phone' option to add a 'user=phone' parameter when applicable. This change adds a configuration option which adds a 'user=phone' parameter if the user portion of the request URI or the From URI is determined to be a number. Review: https://reviewboard.asterisk.org/r/4073/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@425804 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/CHANGES b/CHANGES index 3bef611608..3a6839f01e 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,10 @@ chan_sip ipaddress to bind the rtpengine to. For example, chan_sip might bind to eth0 (10.0.0.2) but rtpengine to eth1 (192.168.1.10). +chan_pjsip +------------------ + * New 'user_eq_phone' endpoint setting. This adds a 'user=phone' parameter + to the request URI and From URI if the user is determined to be a phone number. Functions ------------------ diff --git a/contrib/ast-db-manage/config/versions/371a3bf4143e_add_user_eq_phone_option_to_pjsip.py b/contrib/ast-db-manage/config/versions/371a3bf4143e_add_user_eq_phone_option_to_pjsip.py new file mode 100644 index 0000000000..145d6bea65 --- /dev/null +++ b/contrib/ast-db-manage/config/versions/371a3bf4143e_add_user_eq_phone_option_to_pjsip.py @@ -0,0 +1,30 @@ +"""add user_eq_phone option to pjsip + +Revision ID: 371a3bf4143e +Revises: 10aedae86a32 +Create Date: 2014-10-13 13:46:24.474675 + +""" + +# revision identifiers, used by Alembic. +revision = '371a3bf4143e' +down_revision = '10aedae86a32' + +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('user_eq_phone', yesno_values)) + +def downgrade(): + op.drop_column('ps_endpoints', 'user_eq_phone') diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 302a15d730..e7c01c43b9 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -607,6 +607,8 @@ struct ast_sip_endpoint { enum ast_sip_session_redirect redirect_method; /*! Variables set on channel creation */ struct ast_variable *channel_vars; + /*! Whether to place a 'user=phone' parameter into the request URI if user is a number */ + unsigned int usereqphone; }; /*! @@ -1483,6 +1485,15 @@ void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size); */ struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata); +/*! + * \brief Add 'user=phone' parameter to URI if enabled and user is a phone number. + * + * \param endpoint The endpoint to use for configuration + * \param pool The memory pool to allocate the parameter from + * \param uri The URI to check for user and to add parameter to + */ +void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri); + /*! * \brief Retrieve any endpoints available to sorcery. * diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 69feabafb2..354c43d075 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -35,6 +35,7 @@ #include "asterisk/taskprocessor.h" #include "asterisk/uuid.h" #include "asterisk/sorcery.h" +#include "asterisk/file.h" /*** MODULEINFO pjproject @@ -573,6 +574,9 @@ Determines whether SIP REFER transfers are allowed for this endpoint + + Determines whether a user=phone parameter is placed into the request URI if the user is determined to be a phone number + String placed as the username portion of an SDP origin (o=) line. @@ -1545,6 +1549,9 @@ + + + @@ -2104,6 +2111,41 @@ static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpo return 0; } +void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri) +{ + pjsip_sip_uri *sip_uri; + int i = 0; + pjsip_param *param; + const pj_str_t STR_USER = { "user", 4 }; + const pj_str_t STR_PHONE = { "phone", 5 }; + + if (!endpoint || !endpoint->usereqphone || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) { + return; + } + + sip_uri = pjsip_uri_get_uri(uri); + + if (!pj_strlen(&sip_uri->user)) { + return; + } + + /* Test URI user against allowed characters in AST_DIGIT_ANY */ + for (; i < pj_strlen(&sip_uri->user); i++) { + if (!strchr(AST_DIGIT_ANYNUM, pj_strbuf(&sip_uri->user)[i])) { + break; + } + } + + if (i < pj_strlen(&sip_uri->user)) { + return; + } + + param = PJ_POOL_ALLOC_T(pool, pjsip_param); + param->name = STR_USER; + param->value = STR_PHONE; + pj_list_insert_before(&sip_uri->other_param, param); +} + pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, const char *uri, const char *request_user) { char enclosed_uri[PJSIP_MAX_URL_SIZE]; @@ -2151,6 +2193,9 @@ pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, } } + /* Add the user=phone parameter if applicable */ + ast_sip_add_usereqphone(endpoint, dlg->pool, dlg->target); + /* We have to temporarily bump up the sess_count here so the dialog is not prematurely destroyed */ dlg->sess_count++; @@ -2350,6 +2395,9 @@ static int create_out_of_dialog_request(const pjsip_method *method, struct ast_s return -1; } + /* Add the user=phone parameter if applicable */ + ast_sip_add_usereqphone(endpoint, (*tdata)->pool, (*tdata)->msg->line.req.uri); + /* If an outbound proxy is specified on the endpoint apply it to this request */ if (endpoint && !ast_strlen_zero(endpoint->outbound_proxy) && ast_sip_set_outbound_proxy((*tdata), endpoint->outbound_proxy)) { diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 510afd71b6..dabbfaed8a 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1732,6 +1732,7 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod ast_sorcery_object_field_register(sip_sorcery, "endpoint", "record_on_feature", "automixmon", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, info.recording.onfeature)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "record_off_feature", "automixmon", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, info.recording.offfeature)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_transfer", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allowtransfer)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "user_eq_phone", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, usereqphone)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_owner", "-", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpowner)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_session", "Asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpsession)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "tos_audio", "0", tos_handler, tos_audio_to_str, NULL, 0, 0); diff --git a/res/res_pjsip_caller_id.c b/res/res_pjsip_caller_id.c index e22ce6a09e..c3757e06f1 100644 --- a/res/res_pjsip_caller_id.c +++ b/res/res_pjsip_caller_id.c @@ -669,11 +669,7 @@ static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx ast_party_id_copy(&connected_id, &effective_id); ast_channel_unlock(session->channel); - if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED && - ast_strlen_zero(session->endpoint->fromuser) && - (session->endpoint->id.trust_outbound || - ((connected_id.name.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED && - (connected_id.number.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED))) { + if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED) { /* Only change the From header on the initial outbound INVITE. Switching it * mid-call might confuse some UAs. */ @@ -683,8 +679,16 @@ static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx from = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, tdata->msg->hdr.next); dlg = session->inv_session->dlg; - modify_id_header(tdata->pool, from, &connected_id); - modify_id_header(dlg->pool, dlg->local.info, &connected_id); + if (ast_strlen_zero(session->endpoint->fromuser) && + (session->endpoint->id.trust_outbound || + ((connected_id.name.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED && + (connected_id.number.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED))) { + modify_id_header(tdata->pool, from, &connected_id); + modify_id_header(dlg->pool, dlg->local.info, &connected_id); + } + + ast_sip_add_usereqphone(session->endpoint, tdata->pool, from->uri); + ast_sip_add_usereqphone(session->endpoint, dlg->pool, dlg->local.info->uri); } add_id_headers(session, tdata, &connected_id); ast_party_id_free(&connected_id);