diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2013-02-13 10:19:25 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2013-02-13 10:19:25 +0000 |
commit | daf6fa9d2e92d91df192d59540058f5f0f99a477 (patch) | |
tree | cd01de82578fc751dfbd623ca8267903a7f492c7 | |
parent | c0eaf417c356756c1dee311fdad96c284ec08941 (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.c | 14 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_util.h | 7 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 14 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_inv.c | 47 |
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)); |