diff options
-rw-r--r-- | pjsip-apps/src/pjsua/pjsua_app.c | 37 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 26 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua_internal.h | 3 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_acc.c | 72 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 34 |
5 files changed, 138 insertions, 34 deletions
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c index 227beca8..c3d6ca08 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -192,8 +192,12 @@ static void usage(void) puts (" --contact-uri-params=S Append the specified parameters S in Contact URI"); puts (" --proxy=url Optional URL of proxy server to visit"); puts (" May be specified multiple times"); - puts (" --reg-timeout=SEC Optional registration interval (default 55)"); - puts (" --rereg-delay=SEC Optional auto retry registration interval (default 300)"); + printf(" --reg-timeout=SEC Optional registration interval (default %d)\n", + PJSUA_REG_INTERVAL); + printf(" --rereg-delay=SEC Optional auto retry registration interval (default %d)\n", + PJSUA_REG_RETRY_INTERVAL); + puts (" --reg-use-proxy=N Control the use of proxy settings in REGISTER."); + puts (" 0=no proxy, 1=outbound only, 2=acc only, 3=all (default)"); puts (" --realm=string Set realm"); puts (" --username=string Set authentication username"); puts (" --password=string Set authentication password"); @@ -201,7 +205,8 @@ static void usage(void) puts (" --mwi Subscribe to message summary/waiting indication"); puts (" --use-100rel Require reliable provisional response (100rel)"); puts (" --use-timer Require SIP session timers"); - puts (" --timer-se=N Session timers expiration period, in secs (def:1800)"); + printf(" --timer-se=N Session timers expiration period, in secs (def:%d)\n", + PJSIP_SESS_TIMER_DEF_SE); puts (" --timer-min-se=N Session timers minimum expiration period, in secs (def:90)"); puts (" --auto-update-nat=N Where N is 0 or 1 to enable/disable SIP traversal behind"); puts (" symmetric NAT (default 1)"); @@ -489,7 +494,7 @@ static pj_status_t parse_args(int argc, char *argv[], OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT, OPT_BOUND_ADDR, OPT_CONTACT_PARAMS, OPT_CONTACT_URI_PARAMS, OPT_100REL, OPT_USE_IMS, OPT_REALM, OPT_USERNAME, OPT_PASSWORD, - OPT_REG_RETRY_INTERVAL, + OPT_REG_RETRY_INTERVAL, OPT_REG_USE_PROXY, OPT_MWI, OPT_NAMESERVER, OPT_STUN_SRV, OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE, OPT_AUTO_ANSWER, OPT_AUTO_PLAY, OPT_AUTO_PLAY_HANGUP, OPT_AUTO_LOOP, @@ -558,6 +563,7 @@ static pj_status_t parse_args(int argc, char *argv[], { "username", 1, 0, OPT_USERNAME}, { "password", 1, 0, OPT_PASSWORD}, { "rereg-delay",1, 0, OPT_REG_RETRY_INTERVAL}, + { "reg-use-proxy", 1, 0, OPT_REG_USE_PROXY}, { "nameserver", 1, 0, OPT_NAMESERVER}, { "stun-srv", 1, 0, OPT_STUN_SRV}, { "add-buddy", 1, 0, OPT_ADD_BUDDY}, @@ -975,6 +981,15 @@ static pj_status_t parse_args(int argc, char *argv[], cur_acc->reg_retry_interval = pj_strtoul(pj_cstr(&tmp, pj_optarg)); break; + case OPT_REG_USE_PROXY: + cur_acc->reg_use_proxy = (unsigned)pj_strtoul(pj_cstr(&tmp, pj_optarg)); + if (cur_acc->reg_use_proxy > 3) { + PJ_LOG(1,(THIS_FILE, "Error: invalid --reg-use-proxy value '%s'", + pj_optarg)); + return PJ_EINVAL; + } + break; + case OPT_NEXT_CRED: /* next credential */ cur_acc->cred_count++; break; @@ -1571,6 +1586,20 @@ static void write_account_settings(int acc_index, pj_str_t *result) pj_strcat2(result, "--next-cred\n"); } + /* reg-use-proxy */ + if (acc_cfg->reg_use_proxy != 3) { + pj_ansi_sprintf(line, "--reg-use-proxy %d\n", + acc_cfg->reg_use_proxy); + pj_strcat2(result, line); + } + + /* rereg-delay */ + if (acc_cfg->reg_retry_interval != PJSUA_REG_RETRY_INTERVAL) { + pj_ansi_sprintf(line, "--rereg-delay %d\n", + acc_cfg->reg_retry_interval); + pj_strcat2(result, line); + } + /* 100rel extension */ if (acc_cfg->require_100rel) { pj_strcat2(result, "--use-100rel\n"); diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 2826c9fa..36a11489 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1924,6 +1924,20 @@ PJ_DECL(pj_status_t) pjsua_transport_close( pjsua_transport_id id, /** + * Bit value used in pjsua_acc_config.reg_use_proxy field to indicate that + * the global outbound proxy list should be added to the REGISTER request. + */ +#define PJSUA_REG_USE_OUTBOUND_PROXY 1 + + +/** + * Bit value used in pjsua_acc_config.reg_use_proxy field to indicate that + * the account proxy list should be added to the REGISTER request. + */ +#define PJSUA_REG_USE_ACC_PROXY 2 + + +/** * This structure describes account configuration to be specified when * adding a new account with #pjsua_acc_add(). Application MUST initialize * this structure first by calling #pjsua_acc_config_default(). @@ -2224,6 +2238,18 @@ typedef struct pjsua_acc_config */ pj_bool_t drop_calls_on_reg_fail; + /** + * Specify how the registration uses the outbound and account proxy + * settings. This controls if and what Route headers will appear in + * the REGISTER request of this account. The value is bitmask combination + * of PJSUA_REG_USE_OUTBOUND_PROXY and PJSUA_REG_USE_ACC_PROXY bits. + * If the value is set to 0, the REGISTER request will not use any proxy + * (i.e. it will not have any Route headers). + * + * Default: 3 (PJSUA_REG_USE_OUTBOUND_PROXY | PJSUA_REG_USE_ACC_PROXY) + */ + unsigned reg_use_proxy; + } pjsua_acc_config; diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index f20b73de..f9146fb7 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -285,6 +285,9 @@ struct pjsua_data pj_status_t nat_status; /**< Detection status. */ pj_bool_t nat_in_progress; /**< Detection in progress */ + /* List of outbound proxies: */ + pjsip_route_hdr outbound_proxy; + /* Account: */ unsigned acc_cnt; /**< Number of accounts. */ pjsua_acc_id default_acc; /**< Default account ID */ diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 925c71a9..9bd3020b 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -199,21 +199,15 @@ static pj_status_t initialize_acc(unsigned acc_id) */ pj_list_init(&acc->route_set); - for (i=0; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) { - pj_str_t hname = { "Route", 5}; + if (!pj_list_empty(&pjsua_var.outbound_proxy)) { pjsip_route_hdr *r; - pj_str_t tmp; - pj_strdup_with_null(acc->pool, &tmp, - &pjsua_var.ua_cfg.outbound_proxy[i]); - r = (pjsip_route_hdr*) - pjsip_parse_hdr(acc->pool, &hname, tmp.ptr, tmp.slen, NULL); - if (r == NULL) { - pjsua_perror(THIS_FILE, "Invalid outbound proxy URI", - PJSIP_EINVALIDURI); - return PJSIP_EINVALIDURI; + r = pjsua_var.outbound_proxy.next; + while (r != &pjsua_var.outbound_proxy) { + pj_list_push_back(&acc->route_set, + pjsip_hdr_shallow_clone(acc->pool, r)); + r = r->next; } - pj_list_push_back(&acc->route_set, r); } for (i=0; i<acc_cfg->proxy_cnt; ++i) { @@ -602,24 +596,14 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, pjsua_var.ua_cfg.outbound_proxy_cnt); if (global_route_crc != acc->global_route_crc) { pjsip_route_hdr *r; - unsigned i; - /* Validate the global route and save it to temporary var */ + /* Copy from global outbound proxies */ pj_list_init(&global_route); - for (i=0; i < pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) { - pj_str_t hname = { "Route", 5}; - pj_str_t tmp; - - pj_strdup_with_null(acc->pool, &tmp, - &pjsua_var.ua_cfg.outbound_proxy[i]); - r = (pjsip_route_hdr*) - pjsip_parse_hdr(acc->pool, &hname, tmp.ptr, tmp.slen, NULL); - if (r == NULL) { - status = PJSIP_EINVALIDURI; - pjsua_perror(THIS_FILE, "Invalid outbound proxy URI", status); - goto on_return; - } - pj_list_push_back(&global_route, r); + r = pjsua_var.outbound_proxy.next; + while (r != &pjsua_var.outbound_proxy) { + pj_list_push_back(&global_route, + pjsip_hdr_shallow_clone(acc->pool, r)); + r = r->next; } } @@ -1610,8 +1594,36 @@ static pj_status_t pjsua_regc_init(int acc_id) /* Set route-set */ - if (!pj_list_empty(&acc->route_set)) { - pjsip_regc_set_route_set( acc->regc, &acc->route_set ); + if (acc->cfg.reg_use_proxy) { + pjsip_route_hdr route_set; + const pjsip_route_hdr *r; + + pj_list_init(&route_set); + + if (acc->cfg.reg_use_proxy & PJSUA_REG_USE_OUTBOUND_PROXY) { + r = pjsua_var.outbound_proxy.next; + while (r != &pjsua_var.outbound_proxy) { + pj_list_push_back(&route_set, pjsip_hdr_shallow_clone(pool, r)); + r = r->next; + } + } + + if (acc->cfg.reg_use_proxy & PJSUA_REG_USE_ACC_PROXY && + acc->cfg.proxy_cnt) + { + int cnt = acc->cfg.proxy_cnt; + pjsip_route_hdr *pos = route_set.prev; + int i; + + r = acc->route_set.prev; + for (i=0; i<cnt; ++i) { + pj_list_push_front(pos, pjsip_hdr_shallow_clone(pool, r)); + r = r->prev; + } + } + + if (!pj_list_empty(&route_set)) + pjsip_regc_set_route_set( acc->regc, &route_set ); } /* Add other request headers. */ diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 888b3dbe..3d13f2eb 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -64,6 +64,7 @@ static void init_data() pjsua_var.stun_status = PJ_EUNKNOWN; pjsua_var.nat_status = PJ_EPENDING; pj_list_init(&pjsua_var.stun_res); + pj_list_init(&pjsua_var.outbound_proxy); pjsua_config_default(&pjsua_var.ua_cfg); } @@ -179,6 +180,8 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg) #endif cfg->reg_retry_interval = PJSUA_REG_RETRY_INTERVAL; cfg->contact_rewrite_method = PJSUA_CONTACT_REWRITE_METHOD; + cfg->reg_use_proxy = PJSUA_REG_USE_OUTBOUND_PROXY | + PJSUA_REG_USE_ACC_PROXY; } PJ_DEF(void) pjsua_buddy_config_default(pjsua_buddy_config *cfg) @@ -665,6 +668,7 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg, pjsua_media_config default_media_cfg; const pj_str_t STR_OPTIONS = { "OPTIONS", 7 }; pjsip_ua_init_param ua_init_param; + unsigned i; pj_status_t status; @@ -783,6 +787,36 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg, PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); } + /* Parse outbound proxies */ + for (i=0; i<ua_cfg->outbound_proxy_cnt; ++i) { + pj_str_t tmp; + pj_str_t hname = { "Route", 5}; + pjsip_route_hdr *r; + + pj_strdup_with_null(pjsua_var.pool, &tmp, &ua_cfg->outbound_proxy[i]); + + r = (pjsip_route_hdr*) + pjsip_parse_hdr(pjsua_var.pool, &hname, tmp.ptr, + (unsigned)tmp.slen, NULL); + if (r == NULL) { + pjsua_perror(THIS_FILE, "Invalid outbound proxy URI", + PJSIP_EINVALIDURI); + return PJSIP_EINVALIDURI; + } + + if (pjsua_var.ua_cfg.force_lr) { + pjsip_sip_uri *sip_url; + if (!PJSIP_URI_SCHEME_IS_SIP(r->name_addr.uri) && + !PJSIP_URI_SCHEME_IS_SIP(r->name_addr.uri)) + { + return PJSIP_EINVALIDSCHEME; + } + sip_url = (pjsip_sip_uri*)r->name_addr.uri; + sip_url->lr_param = 1; + } + + pj_list_push_back(&pjsua_var.outbound_proxy, r); + } /* Initialize PJSUA call subsystem: */ |