diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-09-24 00:07:11 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-09-24 00:07:11 +0000 |
commit | e3f862fca94af0cb4812796055b18d2ba107b613 (patch) | |
tree | 1a49b7381865830cebba5a2b62a905d60c7f0483 /pjsip | |
parent | 6ff54be10fd9c0ceff14e10f83a1d1af82ede83f (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
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 15 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua_internal.h | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_acc.c | 117 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 10 |
4 files changed, 93 insertions, 50 deletions
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, |