summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2013-02-13 10:19:25 +0000
committerNanang Izzuddin <nanang@teluu.com>2013-02-13 10:19:25 +0000
commitdaf6fa9d2e92d91df192d59540058f5f0f99a477 (patch)
treecd01de82578fc751dfbd623ca8267903a7f492c7
parentc0eaf417c356756c1dee311fdad96c284ec08941 (diff)
Close #1614: Added call redirect option PJSIP_REDIRECT_ACCEPT_REPLACE to accept call redirection with replaced 'To' header.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4347 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/pjsua/pjsua_app.c14
-rw-r--r--pjsip/include/pjsip/sip_util.h7
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h14
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c47
4 files changed, 71 insertions, 11 deletions
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index 1f99992e..ac0708e5 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -377,7 +377,8 @@ static void usage(void)
puts (" --use-compact-form Minimize SIP message size");
puts (" --no-force-lr Allow strict-route to be used (i.e. do not force lr)");
puts (" --accept-redirect=N Specify how to handle call redirect (3xx) response.");
- puts (" 0: reject, 1: follow automatically (default), 2: ask");
+ puts (" 0: reject, 1: follow automatically,");
+ puts (" 2: follow + replace To header (default), 3: ask");
puts ("");
puts ("When URL is specified, pjsua will immediately initiate call to that URL");
@@ -404,7 +405,7 @@ static void default_config(struct app_config *cfg)
cfg->udp_cfg.port = 5060;
pjsua_transport_config_default(&cfg->rtp_cfg);
cfg->rtp_cfg.port = 4000;
- cfg->redir_op = PJSIP_REDIRECT_ACCEPT;
+ cfg->redir_op = PJSIP_REDIRECT_ACCEPT_REPLACE;
cfg->duration = NO_LIMIT;
cfg->wav_id = PJSUA_INVALID_ID;
cfg->rec_id = PJSUA_INVALID_ID;
@@ -2241,7 +2242,7 @@ static int write_settings(const struct app_config *config,
}
/* accept-redirect */
- if (config->redir_op != PJSIP_REDIRECT_ACCEPT) {
+ if (config->redir_op != PJSIP_REDIRECT_ACCEPT_REPLACE) {
pj_ansi_sprintf(line, "--accept-redirect %d\n",
config->redir_op);
pj_strcat2(&cfg, line);
@@ -3051,8 +3052,8 @@ static pjsip_redirect_op call_on_redirected(pjsua_call_id call_id,
}
PJ_LOG(3,(THIS_FILE, "Call %d is being redirected to %.*s. "
- "Press 'Ra' to accept, 'Rr' to reject, or 'Rd' to "
- "disconnect.",
+ "Press 'Ra' to accept+replace To header, 'RA' to accept, "
+ "'Rr' to reject, or 'Rd' to disconnect.",
call_id, len, uristr));
}
@@ -5381,6 +5382,9 @@ void console_app_main(const pj_str_t *uri_to_call)
PJ_LOG(1,(THIS_FILE, "Call %d has gone", current_call));
} else if (menuin[1] == 'a') {
pjsua_call_process_redirect(current_call,
+ PJSIP_REDIRECT_ACCEPT_REPLACE);
+ } else if (menuin[1] == 'A') {
+ pjsua_call_process_redirect(current_call,
PJSIP_REDIRECT_ACCEPT);
} else if (menuin[1] == 'r') {
pjsua_call_process_redirect(current_call,
diff --git a/pjsip/include/pjsip/sip_util.h b/pjsip/include/pjsip/sip_util.h
index 5be44729..226dccd6 100644
--- a/pjsip/include/pjsip/sip_util.h
+++ b/pjsip/include/pjsip/sip_util.h
@@ -92,6 +92,13 @@ typedef enum pjsip_redirect_op
PJSIP_REDIRECT_ACCEPT,
/**
+ * Accept the redirection to the current target and replace the To
+ * header in the INVITE request with the current target. The INVITE
+ * request will be resent to the current target.
+ */
+ PJSIP_REDIRECT_ACCEPT_REPLACE,
+
+ /**
* Defer the redirection decision, for example to request permission
* from the end user.
*/
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index e3d9dd31..5a4a0fa4 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1125,9 +1125,8 @@ typedef struct pjsua_callback
* INVITE request to the specified target, following the previously
* received redirection response.
*
- * Application may accept the redirection to the specified target
- * (the default behavior if this callback is implemented), reject
- * this target only and make the session continue to try the next
+ * Application may accept the redirection to the specified target,
+ * reject this target only and make the session continue to try the next
* target in the list if such target exists, stop the whole
* redirection process altogether and cause the session to be
* disconnected, or defer the decision to ask for user confirmation.
@@ -1147,9 +1146,12 @@ typedef struct pjsua_callback
* @return Action to be performed for the target. Set this
* parameter to one of the value below:
* - PJSIP_REDIRECT_ACCEPT: immediately accept the
- * redirection (default value). When set, the
- * call will immediately resend INVITE request
- * to the target.
+ * redirection. When set, the call will immediately
+ * resend INVITE request to the target.
+ * - PJSIP_REDIRECT_ACCEPT_REPLACE: immediately accept
+ * the redirection and replace the To header with the
+ * current target. When set, the call will immediately
+ * resend INVITE request to the target.
* - PJSIP_REDIRECT_REJECT: immediately reject this
* target. The call will continue retrying with
* next target if present, or disconnect the call
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index 815da53a..fef2318a 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -2329,6 +2329,7 @@ static pj_bool_t inv_uac_recurse(pjsip_inv_session *inv, int code,
/* Check what the application wants to do now */
switch (op) {
case PJSIP_REDIRECT_ACCEPT:
+ case PJSIP_REDIRECT_ACCEPT_REPLACE:
case PJSIP_REDIRECT_STOP:
/* Must increment session counter, that's the convention of the
* pjsip_inv_process_redirect().
@@ -2394,6 +2395,7 @@ PJ_DEF(pj_status_t) pjsip_inv_process_redirect( pjsip_inv_session *inv,
/* See what the application wants to do now */
switch (op) {
case PJSIP_REDIRECT_ACCEPT:
+ case PJSIP_REDIRECT_ACCEPT_REPLACE:
/* User accept the redirection. Reset the session and resend the
* INVITE request.
*/
@@ -2419,6 +2421,51 @@ PJ_DEF(pj_status_t) pjsip_inv_process_redirect( pjsip_inv_session *inv,
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
via->branch_param.slen = 0;
+ /* Process PJSIP_REDIRECT_ACCEPT_REPLACE */
+ if (op == PJSIP_REDIRECT_ACCEPT_REPLACE) {
+ pjsip_to_hdr *to;
+ pjsip_dialog *dlg = inv->dlg;
+ enum { TMP_LEN = 128 };
+ char tmp[TMP_LEN];
+ int len;
+
+ /* Replace To header */
+ to = PJSIP_MSG_TO_HDR(tdata->msg);
+ to->uri = (pjsip_uri*)
+ pjsip_uri_clone(tdata->pool,
+ dlg->target_set.current->uri);
+ to->tag.slen = 0;
+ pj_list_init(&to->other_param);
+
+ /* Re-init dialog remote info */
+ dlg->remote.info = (pjsip_to_hdr*)
+ pjsip_hdr_clone(dlg->pool, to);
+
+ /* Remove header param from remote info */
+ if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) ||
+ PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri))
+ {
+ pjsip_sip_uri *sip_uri = (pjsip_sip_uri *)
+ pjsip_uri_get_uri(dlg->remote.info->uri);
+ if (!pj_list_empty(&sip_uri->header_param)) {
+ /* Remove all header param */
+ pj_list_init(&sip_uri->header_param);
+ }
+ }
+
+ /* Print the remote info. */
+ len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
+ dlg->remote.info->uri, tmp, TMP_LEN);
+ if (len < 1) {
+ pj_ansi_strcpy(tmp, "<-error: uri too long->");
+ len = pj_ansi_strlen(tmp);
+ }
+ pj_strdup2_with_null(dlg->pool, &dlg->remote.info_str, tmp);
+
+ /* Secure? */
+ dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(to->uri);
+ }
+
/* Reset message destination info (see #1248). */
pj_bzero(&tdata->dest_info, sizeof(tdata->dest_info));