summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-09-24 00:07:11 +0000
committerBenny Prijono <bennylp@teluu.com>2006-09-24 00:07:11 +0000
commite3f862fca94af0cb4812796055b18d2ba107b613 (patch)
tree1a49b7381865830cebba5a2b62a905d60c7f0483
parent6ff54be10fd9c0ceff14e10f83a1d1af82ede83f (diff)
Fixed several bugs in PJSUA-API:
- in some condition, when outgoing call fails, call count incorrectly decremented to -1 - introduce account priority in pjsua_acc_config, and improve the account searching for incoming calls - pjsua will hangup call after sending transfer/REFER request. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@737 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/pjsua/pjsua_app.c3
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h15
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h1
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c117
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c10
5 files changed, 96 insertions, 50 deletions
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index be4cc418..1b354915 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -2138,6 +2138,9 @@ void console_app_main(const pj_str_t *uri_to_call)
tmp = pj_str(result.uri_result);
pjsua_call_xfer( current_call, &tmp, &msg_data);
}
+
+ /* Hangup call regardless of xfer status */
+ pjsua_call_hangup(current_call, PJSIP_SC_GONE, NULL, NULL);
}
break;
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 0a106f47..82e22abe 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1020,10 +1020,25 @@ PJ_DECL(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
/**
+ * Default account priority.
+ */
+#ifndef PJSUA_DEFAULT_ACC_PRIORITY
+# define PJSUA_DEFAULT_ACC_PRIORITY 0
+#endif
+
+
+/**
* Account configuration.
*/
typedef struct pjsua_acc_config
{
+ /**
+ * Account priority, which is used to control the order of matching
+ * incoming/outgoing requests. The higher the number means the higher
+ * the priority is, and the account will be matched first.
+ */
+ int priority;
+
/**
* The full SIP URL for the account. The value can take name address or
* URL format, and will look something like "sip:account@serviceprovider".
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index 10e76635..ca9a51d0 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -189,6 +189,7 @@ struct pjsua_data
unsigned acc_cnt; /**< Number of accounts. */
pjsua_acc_id default_acc; /**< Default account ID */
pjsua_acc acc[PJSUA_MAX_ACC]; /**< Account array. */
+ pjsua_acc_id acc_ids[PJSUA_MAX_ACC]; /**< Acc sorted by prio*/
/* Calls: */
pjsua_config ua_cfg; /**< UA config. */
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index d545bdfb..5578e7f8 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -229,6 +229,16 @@ static pj_status_t initialize_acc(unsigned acc_id)
/* Mark account as valid */
pjsua_var.acc[acc_id].valid = PJ_TRUE;
+ /* Insert account ID into account ID array, sorted by priority */
+ for (i=0; i<pjsua_var.acc_cnt; ++i) {
+ if ( pjsua_var.acc[pjsua_var.acc_ids[i]].cfg.priority <
+ pjsua_var.acc[acc_id].cfg.priority)
+ {
+ break;
+ }
+ }
+ pj_array_insert(pjsua_var.acc_ids, sizeof(pjsua_var.acc_ids[0]),
+ pjsua_var.acc_cnt, i, &acc_id);
return PJ_SUCCESS;
}
@@ -321,6 +331,9 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid,
pjsua_acc_config_default(&cfg);
+ /* Lower the priority of local account */
+ --cfg.priority;
+
/* Build URI for the account */
pj_ansi_snprintf(uri, PJSIP_MAX_URL_SIZE,
"<sip:%.*s:%d;transport=%s>",
@@ -340,6 +353,8 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid,
*/
PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id)
{
+ unsigned i;
+
PJ_ASSERT_RETURN(acc_id>=0 && acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc),
PJ_EINVAL);
PJ_ASSERT_RETURN(pjsua_var.acc[acc_id].valid, PJ_EINVALIDOP);
@@ -356,6 +371,17 @@ PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id)
/* Invalidate */
pjsua_var.acc[acc_id].valid = PJ_FALSE;
+ /* Remove from array */
+ for (i=0; i<pjsua_var.acc_cnt; ++i) {
+ if (pjsua_var.acc_ids[i] == acc_id)
+ break;
+ }
+ if (i != pjsua_var.acc_cnt) {
+ pj_array_erase(pjsua_var.acc_ids, sizeof(pjsua_var.acc_ids[0]),
+ pjsua_var.acc_cnt, i);
+ --pjsua_var.acc_cnt;
+ }
+
PJ_TODO(may_need_to_scan_calls);
PJSUA_UNLOCK();
@@ -709,7 +735,7 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *url)
pj_str_t tmp;
pjsip_uri *uri;
pjsip_sip_uri *sip_uri;
- unsigned acc_id;
+ unsigned i;
PJSUA_LOCK();
@@ -719,74 +745,59 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *url)
uri = pjsip_parse_uri(pjsua_var.pool, tmp.ptr, tmp.slen, 0);
if (!uri) {
- acc_id = pjsua_var.default_acc;
- goto on_return;
+ 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 (acc_id=0; acc_id<PJ_ARRAY_SIZE(pjsua_var.acc); ++acc_id) {
- if (!pjsua_var.acc[acc_id].valid)
+ 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[acc_id].route_set))
+ if (!pj_list_empty(&pjsua_var.acc[i].route_set))
break;
}
- if (acc_id != PJ_ARRAY_SIZE(pjsua_var.acc)) {
+ if (i != PJ_ARRAY_SIZE(pjsua_var.acc)) {
/* Found rather matching account */
- goto on_return;
+ PJSUA_UNLOCK();
+ return 0;
}
/* Not found, use default account */
- acc_id = pjsua_var.default_acc;
- goto on_return;
+ PJSUA_UNLOCK();
+ return pjsua_var.default_acc;
}
sip_uri = pjsip_uri_get_uri(uri);
- /* See if default acc match */
- if (pjsua_var.default_acc != PJSUA_INVALID_ID &&
- pj_stricmp(&pjsua_var.acc[pjsua_var.default_acc].srv_domain, &sip_uri->host)==0 &&
- pjsua_var.acc[pjsua_var.default_acc].srv_port == sip_uri->port)
- {
- acc_id = pjsua_var.default_acc;
- } else {
- acc_id = PJ_ARRAY_SIZE(pjsua_var.acc);
- }
-
/* Find matching domain AND port */
- if (acc_id == PJ_ARRAY_SIZE(pjsua_var.acc)) {
- for (acc_id=0; acc_id<PJ_ARRAY_SIZE(pjsua_var.acc); ++acc_id) {
- if (!pjsua_var.acc[acc_id].valid)
- continue;
- if (pj_stricmp(&pjsua_var.acc[acc_id].srv_domain, &sip_uri->host)==0 &&
- pjsua_var.acc[acc_id].srv_port == sip_uri->port)
- break;
+ 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 */
- if (acc_id == PJ_ARRAY_SIZE(pjsua_var.acc)) {
- /* Just use default account */
- for (acc_id=0; acc_id<PJ_ARRAY_SIZE(pjsua_var.acc); ++acc_id) {
- if (!pjsua_var.acc[acc_id].valid)
- continue;
- if (pj_stricmp(&pjsua_var.acc[acc_id].srv_domain, &sip_uri->host)==0)
- break;
+ 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;
}
}
- if (acc_id == PJ_ARRAY_SIZE(pjsua_var.acc)) {
- /* Just use default account */
- acc_id = pjsua_var.default_acc;
- }
-on_return:
+ /* Still no match, just use default account */
PJSUA_UNLOCK();
-
- return acc_id;
+ return pjsua_var.default_acc;
}
@@ -798,7 +809,7 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
{
pjsip_uri *uri;
pjsip_sip_uri *sip_uri;
- unsigned acc_id;
+ unsigned i;
uri = rdata->msg_info.to->uri;
@@ -815,8 +826,8 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
/* Find account which has matching username and domain. */
- for (acc_id=0; acc_id < pjsua_var.acc_cnt; ++acc_id) {
-
+ 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 &&
@@ -828,9 +839,9 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
}
}
- /* No matching, try match domain part only. */
- for (acc_id=0; acc_id < pjsua_var.acc_cnt; ++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 (pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) {
@@ -840,6 +851,18 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
}
}
+ /* No matching account, try match user 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 (pj_stricmp(&acc->user_part, &sip_uri->user)==0) {
+ /* Match ! */
+ PJSUA_UNLOCK();
+ return acc_id;
+ }
+ }
+
/* Still no match, use default account */
PJSUA_UNLOCK();
return pjsua_var.default_acc;
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 35eee940..bb2ccd18 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -237,6 +237,9 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id,
call = &pjsua_var.calls[call_id];
+ PJ_LOG(4,(THIS_FILE, "Making call with acc #%d to %.*s", acc_id,
+ (int)dest_uri->slen, dest_uri->ptr));
+
/* Mark call start time. */
pj_gettimeofday(&call->start_time);
@@ -316,6 +319,9 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id,
pjsua_process_msg_data( tdata, msg_data);
+ /* Must increment call counter now */
+ ++pjsua_var.call_cnt;
+
/* Send initial INVITE: */
status = pjsip_inv_send_msg(inv, tdata);
@@ -333,8 +339,6 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id,
/* Done. */
- ++pjsua_var.call_cnt;
-
if (p_call_id)
*p_call_id = call_id;
@@ -462,7 +466,7 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
* call. We need the account to find which contact URI to put for
* the call.
*/
- acc_id = pjsua_acc_find_for_incoming(rdata);
+ acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
/* Get suitable Contact header */
status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact,