diff options
Diffstat (limited to 'pjsip/src')
-rw-r--r-- | pjsip/src/pjsip/sip_dialog.c | 4 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_errno.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 17 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_acc.c | 72 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 19 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 30 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_im.c | 20 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_pres.c | 20 |
8 files changed, 171 insertions, 12 deletions
diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c index bf8eef40..7b97e5b8 100644 --- a/pjsip/src/pjsip/sip_dialog.c +++ b/pjsip/src/pjsip/sip_dialog.c @@ -101,6 +101,10 @@ static void destroy_dialog( pjsip_dialog *dlg ) pj_mutex_destroy(dlg->mutex_); dlg->mutex_ = NULL; } + if (dlg->tp_sel.type != PJSIP_TPSELECTOR_NONE) { + pjsip_tpselector_dec_ref(&dlg->tp_sel); + pj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector)); + } pjsip_endpt_release_pool(dlg->endpt, dlg->pool); } diff --git a/pjsip/src/pjsip/sip_errno.c b/pjsip/src/pjsip/sip_errno.c index 7ca4d215..b9ca4dd3 100644 --- a/pjsip/src/pjsip/sip_errno.c +++ b/pjsip/src/pjsip/sip_errno.c @@ -67,6 +67,7 @@ static const struct PJ_BUILD_ERR( PJSIP_EPENDINGTX, "Transmit buffer already pending"), PJ_BUILD_ERR( PJSIP_ERXOVERFLOW, "Rx buffer overflow"), PJ_BUILD_ERR( PJSIP_EBUFDESTROYED, "Buffer destroyed"), + PJ_BUILD_ERR( PJSIP_ETPNOTSUITABLE, "Unsuitable transport selected"), /* Transaction errors */ PJ_BUILD_ERR( PJSIP_ETSXDESTROYED, "Transaction has been destroyed"), diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 9a3ae6a1..b01676bb 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -940,6 +940,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, pj_pool_t *pool, pjsip_transport_type_e type, + const pjsip_tpselector *sel, pj_str_t *ip_addr, int *port) { @@ -954,7 +955,21 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, flag = pjsip_transport_get_flag_from_type(type); - if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { + if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT && + sel->u.transport) + { + pj_strdup(pool, ip_addr, &sel->u.transport->local_name.host); + *port = sel->u.transport->local_name.port; + status = PJ_SUCCESS; + + } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && + sel->u.listener) + { + pj_strdup(pool, ip_addr, &sel->u.listener->addr_name.host); + *port = sel->u.listener->addr_name.port; + status = PJ_SUCCESS; + + } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { pj_sockaddr_in remote; pjsip_transport *tp; diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index fd71f993..37f36ce7 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -225,7 +225,6 @@ static pj_status_t initialize_acc(unsigned acc_id) if (status != PJ_SUCCESS) return status; - /* Mark account as valid */ pjsua_var.acc[acc_id].valid = PJ_TRUE; @@ -258,7 +257,6 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg, PJ_ETOOMANY); /* Must have a transport */ - PJ_TODO(associate_acc_with_transport); PJ_ASSERT_RETURN(pjsua_var.tpdata[0].data.ptr != NULL, PJ_EINVALIDOP); PJSUA_LOCK(); @@ -320,7 +318,7 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid, pjsua_acc_id *p_acc_id) { pjsua_acc_config cfg; - struct transport_data *t = &pjsua_var.tpdata[tid]; + pjsua_transport_data *t = &pjsua_var.tpdata[tid]; char uri[PJSIP_MAX_URL_SIZE]; /* ID must be valid */ @@ -382,7 +380,10 @@ PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id) --pjsua_var.acc_cnt; } - PJ_TODO(may_need_to_scan_calls); + /* Leave the calls intact, as I don't think calls need to + * access account once it's created + */ + PJSUA_UNLOCK(); @@ -491,6 +492,7 @@ static pj_status_t pjsua_regc_init(int acc_id) pj_pool_t *pool; pj_status_t status; + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); acc = &pjsua_var.acc[acc_id]; if (acc->cfg.reg_uri.slen == 0) { @@ -538,6 +540,17 @@ static pj_status_t pjsua_regc_init(int acc_id) return status; } + /* If account is locked to specific transport, then set transport to + * the client registration. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_regc_set_transport(acc->regc, &tp_sel); + } + + /* Set credentials */ if (acc->cred_cnt) { @@ -640,6 +653,7 @@ PJ_DEF(pj_status_t) pjsua_acc_get_info( pjsua_acc_id acc_id, pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; PJ_ASSERT_RETURN(info != NULL, PJ_EINVAL); + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); pj_bzero(info, sizeof(pjsua_acc_info)); @@ -854,7 +868,7 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata) unsigned acc_id = pjsua_var.acc_ids[i]; pjsua_acc *acc = &pjsua_var.acc[acc_id]; - if (pj_stricmp(&acc->user_part, &sip_uri->user)==0 && + if (acc->valid && pj_stricmp(&acc->user_part, &sip_uri->user)==0 && pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) { /* Match ! */ @@ -868,19 +882,30 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata) unsigned acc_id = pjsua_var.acc_ids[i]; pjsua_acc *acc = &pjsua_var.acc[acc_id]; - if (pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) { + if (acc->valid && pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) { /* Match ! */ PJSUA_UNLOCK(); return acc_id; } } - /* No matching account, try match user part only. */ + /* No matching account, try match user part (and transport type) only. */ for (i=0; i < pjsua_var.acc_cnt; ++i) { unsigned acc_id = pjsua_var.acc_ids[i]; pjsua_acc *acc = &pjsua_var.acc[acc_id]; - if (pj_stricmp(&acc->user_part, &sip_uri->user)==0) { + if (acc->valid && pj_stricmp(&acc->user_part, &sip_uri->user)==0) { + + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_transport_type_e type; + type = pjsip_transport_get_type_from_name(&sip_uri->transport_param); + if (type == PJSIP_TRANSPORT_UNSPECIFIED) + type = PJSIP_TRANSPORT_UDP; + + if (pjsua_var.tpdata[acc->cfg.transport_id].type != type) + continue; + } + /* Match ! */ PJSUA_UNLOCK(); return acc_id; @@ -903,10 +928,12 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, pj_status_t status; pjsip_transport_type_e tp_type = PJSIP_TRANSPORT_UNSPECIFIED; pj_str_t local_addr; + pjsip_tpselector tp_sel; unsigned flag; int secure; int local_port; + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); acc = &pjsua_var.acc[acc_id]; /* If route-set is configured for the account, then URI is the @@ -945,9 +972,13 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, flag = pjsip_transport_get_flag_from_type(tp_type); secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; + /* Init transport selector. */ + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + /* Get local address suitable to send request from */ status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), - pool, tp_type, &local_addr, &local_port); + pool, tp_type, &tp_sel, + &local_addr, &local_port); if (status != PJ_SUCCESS) return status; @@ -990,10 +1021,12 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, pj_status_t status; pjsip_transport_type_e tp_type = PJSIP_TRANSPORT_UNSPECIFIED; pj_str_t local_addr; + pjsip_tpselector tp_sel; unsigned flag; int secure; int local_port; + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); acc = &pjsua_var.acc[acc_id]; /* If Record-Route is present, then URI is the top Record-Route. */ @@ -1038,9 +1071,13 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, flag = pjsip_transport_get_flag_from_type(tp_type); secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; + /* Init transport selector. */ + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + /* Get local address suitable to send request from */ status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), - pool, tp_type, &local_addr, &local_port); + pool, tp_type, &tp_sel, + &local_addr, &local_port); if (status != PJ_SUCCESS) return status; @@ -1064,4 +1101,19 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, } +PJ_DEF(pj_status_t) pjsua_acc_set_transport( pjsua_acc_id acc_id, + pjsua_transport_id tp_id) +{ + pjsua_acc *acc; + + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); + acc = &pjsua_var.acc[acc_id]; + + PJ_ASSERT_RETURN(tp_id >= 0 && tp_id < PJ_ARRAY_SIZE(pjsua_var.tpdata), + PJ_EINVAL); + + acc->cfg.transport_id = tp_id; + + return PJ_SUCCESS; +} diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index f7b77348..6b40becf 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -330,6 +330,16 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, /* Attach user data */ call->user_data = user_data; + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } + /* Set dialog Route-Set: */ if (!pj_list_empty(&acc->route_set)) pjsip_dlg_set_route_set(dlg, &acc->route_set); @@ -619,6 +629,15 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) dlg->mod_data[pjsua_var.mod.id] = call; inv->mod_data[pjsua_var.mod.id] = call; + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } /* Must answer with some response to initial INVITE. */ diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 21864833..b7194111 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -1189,7 +1189,7 @@ PJ_DEF(pj_status_t) pjsua_enum_transports( pjsua_transport_id id[], PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id, pjsua_transport_info *info) { - struct transport_data *t = &pjsua_var.tpdata[id]; + pjsua_transport_data *t = &pjsua_var.tpdata[id]; pj_status_t status; pj_bzero(info, sizeof(*info)); @@ -1416,6 +1416,34 @@ void pjsua_parse_media_type( pj_pool_t *pool, /* + * Internal function to init transport selector from transport id. + */ +void pjsua_init_tpselector(pjsua_transport_id tp_id, + pjsip_tpselector *sel) +{ + pjsua_transport_data *tpdata; + unsigned flag; + + pj_bzero(sel, sizeof(*sel)); + if (tp_id == PJSUA_INVALID_ID) + return; + + pj_assert(tp_id >= 0 && tp_id < PJ_ARRAY_SIZE(pjsua_var.tpdata)); + tpdata = &pjsua_var.tpdata[tp_id]; + + flag = pjsip_transport_get_flag_from_type(tpdata->type); + + if (flag & PJSIP_TRANSPORT_DATAGRAM) { + sel->type = PJSIP_TPSELECTOR_TRANSPORT; + sel->u.transport = tpdata->data.tp; + } else { + sel->type = PJSIP_TPSELECTOR_LISTENER; + sel->u.listener = tpdata->data.factory; + } +} + + +/* * Verify that valid SIP url is given. */ PJ_DEF(pj_status_t) pjsua_verify_sip_url(const char *c_url) diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c index 462796a0..0e29b43e 100644 --- a/pjsip/src/pjsua-lib/pjsua_im.c +++ b/pjsip/src/pjsua-lib/pjsua_im.c @@ -433,6 +433,16 @@ PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, return status; } + /* If account is locked to specific transport, then set transport to + * the request. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_tx_data_set_transport(tdata, &tp_sel); + } + /* Add accept header. */ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); @@ -520,6 +530,16 @@ PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id, } + /* If account is locked to specific transport, then set transport to + * the request. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_tx_data_set_transport(tdata, &tp_sel); + } + /* Add accept header. */ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index 78f913d1..f9f87550 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -501,6 +501,16 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) return PJ_TRUE; } + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } + /* Attach our data to the subscription: */ uapres = pj_pool_alloc(dlg->pool, sizeof(pjsua_srv_pres)); uapres->sub = sub; @@ -988,6 +998,16 @@ static void subscribe_buddy_presence(unsigned index) return; } + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } + /* Set route-set */ if (!pj_list_empty(&acc->route_set)) { pjsip_dlg_set_route_set(dlg, &acc->route_set); |