📄 pjsua_acc.c
字号:
pj_strdup_with_null(pjsua_var.pool, &tmp, url);
uri = pjsip_parse_uri(pjsua_var.pool, tmp.ptr, tmp.slen, 0);
if (!uri) {
PJSUA_UNLOCK();
return pjsua_var.default_acc;
}
if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
!PJSIP_URI_SCHEME_IS_SIPS(uri))
{
/* Return the first account with proxy */
for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) {
if (!pjsua_var.acc[i].valid)
continue;
if (!pj_list_empty(&pjsua_var.acc[i].route_set))
break;
}
if (i != PJ_ARRAY_SIZE(pjsua_var.acc)) {
/* Found rather matching account */
PJSUA_UNLOCK();
return 0;
}
/* Not found, use default account */
PJSUA_UNLOCK();
return pjsua_var.default_acc;
}
sip_uri = pjsip_uri_get_uri(uri);
/* Find matching domain AND port */
for (i=0; i<pjsua_var.acc_cnt; ++i) {
unsigned acc_id = pjsua_var.acc_ids[i];
if (pj_stricmp(&pjsua_var.acc[acc_id].srv_domain, &sip_uri->host)==0 &&
pjsua_var.acc[acc_id].srv_port == sip_uri->port)
{
PJSUA_UNLOCK();
return acc_id;
}
}
/* If no match, try to match the domain part only */
for (i=0; i<pjsua_var.acc_cnt; ++i) {
unsigned acc_id = pjsua_var.acc_ids[i];
if (pj_stricmp(&pjsua_var.acc[acc_id].srv_domain, &sip_uri->host)==0)
{
PJSUA_UNLOCK();
return acc_id;
}
}
/* Still no match, just use default account */
PJSUA_UNLOCK();
return pjsua_var.default_acc;
}
/*
* This is an internal function to find the most appropriate account to be
* used to handle incoming calls.
*/
PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
{
pjsip_uri *uri;
pjsip_sip_uri *sip_uri;
unsigned i;
uri = rdata->msg_info.to->uri;
/* Just return default account if To URI is not SIP: */
if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
!PJSIP_URI_SCHEME_IS_SIPS(uri))
{
return pjsua_var.default_acc;
}
PJSUA_LOCK();
sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
/* Find account which has matching username and domain. */
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 (acc->valid && pj_stricmp(&acc->user_part, &sip_uri->user)==0 &&
pj_stricmp(&acc->srv_domain, &sip_uri->host)==0)
{
/* Match ! */
PJSUA_UNLOCK();
return acc_id;
}
}
/* No matching account, try match domain part 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 (acc->valid && pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) {
/* Match ! */
PJSUA_UNLOCK();
return acc_id;
}
}
/* 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 (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;
}
}
/* Still no match, use default account */
PJSUA_UNLOCK();
return pjsua_var.default_acc;
}
/*
* Create arbitrary requests for this account.
*/
PJ_DEF(pj_status_t) pjsua_acc_create_request(pjsua_acc_id acc_id,
const pjsip_method *method,
const pj_str_t *target,
pjsip_tx_data **p_tdata)
{
pjsip_tx_data *tdata;
pjsua_acc *acc;
pjsip_route_hdr *r;
pj_status_t status;
PJ_ASSERT_RETURN(method && target && p_tdata, PJ_EINVAL);
PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL);
acc = &pjsua_var.acc[acc_id];
status = pjsip_endpt_create_request(pjsua_var.endpt, method, target,
&acc->cfg.id, target,
NULL, NULL, -1, NULL, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create request", status);
return status;
}
/* Copy routeset */
r = acc->route_set.next;
while (r != &acc->route_set) {
pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_clone(tdata->pool, r));
r = r->next;
}
/* Done */
*p_tdata = tdata;
return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool,
pj_str_t *contact,
pjsua_acc_id acc_id,
const pj_str_t *suri)
{
pjsua_acc *acc;
pjsip_sip_uri *sip_uri;
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 force_contact is configured, then use use it */
if (acc->cfg.force_contact.slen) {
*contact = acc->cfg.force_contact;
return PJ_SUCCESS;
}
/* If route-set is configured for the account, then URI is the
* first entry of the route-set.
*/
if (!pj_list_empty(&acc->route_set)) {
sip_uri = (pjsip_sip_uri*)
pjsip_uri_get_uri(acc->route_set.next->name_addr.uri);
} else {
pj_str_t tmp;
pjsip_uri *uri;
pj_strdup_with_null(pool, &tmp, suri);
uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
if (uri == NULL)
return PJSIP_EINVALIDURI;
/* For non-SIP scheme, route set should be configured */
if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))
return PJSIP_EINVALIDREQURI;
sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
}
/* Get transport type of the URI */
if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri))
tp_type = PJSIP_TRANSPORT_TLS;
else if (sip_uri->transport_param.slen == 0) {
tp_type = PJSIP_TRANSPORT_UDP;
} else
tp_type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED)
return PJSIP_EUNSUPTRANSPORT;
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, &tp_sel,
&local_addr, &local_port);
if (status != PJ_SUCCESS)
return status;
/* Create the contact header */
contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
"%.*s%s<%s:%.*s%s%.*s:%d;transport=%s>",
(int)acc->display.slen,
acc->display.ptr,
(acc->display.slen?" " : ""),
(secure ? "sips" : "sip"),
(int)acc->user_part.slen,
acc->user_part.ptr,
(acc->user_part.slen?"@":""),
(int)local_addr.slen,
local_addr.ptr,
local_port,
pjsip_transport_get_type_name(tp_type));
return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool,
pj_str_t *contact,
pjsua_acc_id acc_id,
pjsip_rx_data *rdata )
{
/*
* Section 12.1.1, paragraph about using SIPS URI in Contact.
* If the request that initiated the dialog contained a SIPS URI
* in the Request-URI or in the top Record-Route header field value,
* if there was any, or the Contact header field if there was no
* Record-Route header field, the Contact header field in the response
* MUST be a SIPS URI.
*/
pjsua_acc *acc;
pjsip_sip_uri *sip_uri;
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 force_contact is configured, then use use it */
if (acc->cfg.force_contact.slen) {
*contact = acc->cfg.force_contact;
return PJ_SUCCESS;
}
/* If Record-Route is present, then URI is the top Record-Route. */
if (rdata->msg_info.record_route) {
sip_uri = (pjsip_sip_uri*)
pjsip_uri_get_uri(rdata->msg_info.record_route->name_addr.uri);
} else {
pjsip_contact_hdr *h_contact;
pjsip_uri *uri = NULL;
/* Otherwise URI is Contact URI */
h_contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
if (h_contact)
uri = pjsip_uri_get_uri(h_contact->uri);
/* Or if Contact URI is not present, take the remote URI from
* the From URI.
*/
if (uri == NULL)
uri = pjsip_uri_get_uri(rdata->msg_info.from->uri);
/* Can only do sip/sips scheme at present. */
if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))
return PJSIP_EINVALIDREQURI;
sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
}
/* Get transport type of the URI */
if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri))
tp_type = PJSIP_TRANSPORT_TLS;
else if (sip_uri->transport_param.slen == 0) {
tp_type = PJSIP_TRANSPORT_UDP;
} else
tp_type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED)
return PJSIP_EUNSUPTRANSPORT;
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, &tp_sel,
&local_addr, &local_port);
if (status != PJ_SUCCESS)
return status;
/* Create the contact header */
contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
"%.*s%s<%s:%.*s%s%.*s:%d;transport=%s>",
(int)acc->display.slen,
acc->display.ptr,
(acc->display.slen?" " : ""),
(secure ? "sips" : "sip"),
(int)acc->user_part.slen,
acc->user_part.ptr,
(acc->user_part.slen?"@":""),
(int)local_addr.slen,
local_addr.ptr,
local_port,
pjsip_transport_get_type_name(tp_type));
return PJ_SUCCESS;
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -