diff --git a/CHANGES b/CHANGES
index a546bf86ee..8456f1f18d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -11,6 +11,11 @@
--- Functionality changes from Asterisk 13.1.0 to Asterisk 13.2.0 ------------
------------------------------------------------------------------------------
+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.
+
res_pjsip_config_wizard
------------------
* This is a new module that adds streamlined configuration capability for
@@ -122,7 +127,6 @@ included in Asterisk 13.
Finally, all users upgrading to Asterisk 13 should read the UPGRADE.txt file
delivered with this release.
-
Build System
------------------
* Sample config files have been moved from configs/ to a sub-folder of that
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 2617e95502..95dec46ad9 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -609,6 +609,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;
};
/*!
@@ -1486,6 +1488,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 f597f27a46..481d3b0a44 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
@@ -580,6 +581,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.
@@ -1568,6 +1572,9 @@
+
+
+
@@ -2127,6 +2134,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];
@@ -2174,6 +2216,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++;
@@ -2374,6 +2419,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 63e63fb140..3b58cea49d 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1740,6 +1740,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);