📄 pjsua_acc.c
字号:
return PJ_SUCCESS;
}
/*
* Modify account information.
*/
PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
const pjsua_acc_config *cfg)
{
PJ_TODO(pjsua_acc_modify);
PJ_UNUSED_ARG(acc_id);
PJ_UNUSED_ARG(cfg);
return PJ_EINVALIDOP;
}
/*
* Modify account's presence status to be advertised to remote/presence
* subscribers.
*/
PJ_DEF(pj_status_t) pjsua_acc_set_online_status( pjsua_acc_id acc_id,
pj_bool_t is_online)
{
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);
pjsua_var.acc[acc_id].online_status = is_online;
pjsua_pres_refresh();
return PJ_SUCCESS;
}
/*
* This callback is called by pjsip_regc when outgoing register
* request has completed.
*/
static void regc_cb(struct pjsip_regc_cbparam *param)
{
pjsua_acc *acc = param->token;
PJSUA_LOCK();
/*
* Print registration status.
*/
if (param->status!=PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "SIP registration error",
param->status);
pjsip_regc_destroy(acc->regc);
acc->regc = NULL;
} else if (param->code < 0 || param->code >= 300) {
PJ_LOG(2, (THIS_FILE, "SIP registration failed, status=%d (%.*s)",
param->code,
(int)param->reason.slen, param->reason.ptr));
pjsip_regc_destroy(acc->regc);
acc->regc = NULL;
} else if (PJSIP_IS_STATUS_IN_CLASS(param->code, 200)) {
if (param->expiration < 1) {
pjsip_regc_destroy(acc->regc);
acc->regc = NULL;
PJ_LOG(3,(THIS_FILE, "%s: unregistration success",
pjsua_var.acc[acc->index].cfg.id.ptr));
} else {
PJ_LOG(3, (THIS_FILE,
"%s: registration success, status=%d (%.*s), "
"will re-register in %d seconds",
pjsua_var.acc[acc->index].cfg.id.ptr,
param->code,
(int)param->reason.slen, param->reason.ptr,
param->expiration));
/* Send initial PUBLISH if it is enabled */
if (acc->cfg.publish_enabled && acc->publish_sess==NULL)
pjsua_pres_init_publish_acc(acc->index);
}
} else {
PJ_LOG(4, (THIS_FILE, "SIP registration updated status=%d", param->code));
}
acc->reg_last_err = param->status;
acc->reg_last_code = param->code;
if (pjsua_var.ua_cfg.cb.on_reg_state)
(*pjsua_var.ua_cfg.cb.on_reg_state)(acc->index);
PJSUA_UNLOCK();
}
/*
* Initialize client registration.
*/
static pj_status_t pjsua_regc_init(int acc_id)
{
pjsua_acc *acc;
pj_str_t contact;
char contact_buf[1024];
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) {
PJ_LOG(3,(THIS_FILE, "Registrar URI is not specified"));
return PJ_SUCCESS;
}
/* Destroy existing session, if any */
if (acc->regc) {
pjsip_regc_destroy(acc->regc);
acc->regc = NULL;
}
/* initialize SIP registration if registrar is configured */
status = pjsip_regc_create( pjsua_var.endpt,
acc, ®c_cb, &acc->regc);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create client registration",
status);
return status;
}
pool = pj_pool_create_on_buf(NULL, contact_buf, sizeof(contact_buf));
status = pjsua_acc_create_uac_contact( pool, &contact,
acc_id, &acc->cfg.reg_uri);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to generate suitable Contact header"
" for registration",
status);
return status;
}
status = pjsip_regc_init( acc->regc,
&acc->cfg.reg_uri,
&acc->cfg.id,
&acc->cfg.id,
1, &contact,
acc->cfg.reg_timeout);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE,
"Client registration initialization error",
status);
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) {
pjsip_regc_set_credentials( acc->regc, acc->cred_cnt, acc->cred);
}
/* Set route-set
*/
if (!pj_list_empty(&acc->route_set)) {
pjsip_regc_set_route_set( acc->regc, &acc->route_set );
}
/* Add other request headers. */
if (pjsua_var.ua_cfg.user_agent.slen) {
pjsip_hdr hdr_list;
const pj_str_t STR_USER_AGENT = { "User-Agent", 10 };
pjsip_generic_string_hdr *h;
pool = pj_pool_create_on_buf(NULL, contact_buf, sizeof(contact_buf));
pj_list_init(&hdr_list);
h = pjsip_generic_string_hdr_create(pool, &STR_USER_AGENT,
&pjsua_var.ua_cfg.user_agent);
pj_list_push_back(&hdr_list, (pjsip_hdr*)h);
pjsip_regc_add_headers(acc->regc, &hdr_list);
}
return PJ_SUCCESS;
}
/*
* Update registration or perform unregistration.
*/
PJ_DEF(pj_status_t) pjsua_acc_set_registration( pjsua_acc_id acc_id,
pj_bool_t renew)
{
pj_status_t status = 0;
pjsip_tx_data *tdata = 0;
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);
PJSUA_LOCK();
if (renew) {
if (pjsua_var.acc[acc_id].regc == NULL) {
status = pjsua_regc_init(acc_id);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create registration",
status);
goto on_return;
}
}
if (!pjsua_var.acc[acc_id].regc) {
status = PJ_EINVALIDOP;
goto on_return;
}
status = pjsip_regc_register(pjsua_var.acc[acc_id].regc, 1,
&tdata);
} else {
if (pjsua_var.acc[acc_id].regc == NULL) {
PJ_LOG(3,(THIS_FILE, "Currently not registered"));
status = PJ_EINVALIDOP;
goto on_return;
}
status = pjsip_regc_unregister(pjsua_var.acc[acc_id].regc, &tdata);
}
if (status == PJ_SUCCESS) {
//pjsua_process_msg_data(tdata, NULL);
status = pjsip_regc_send( pjsua_var.acc[acc_id].regc, tdata );
}
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create/send REGISTER",
status);
} else {
PJ_LOG(3,(THIS_FILE, "%s sent",
(renew? "Registration" : "Unregistration")));
}
on_return:
PJSUA_UNLOCK();
return status;
}
/*
* Get account information.
*/
PJ_DEF(pj_status_t) pjsua_acc_get_info( pjsua_acc_id acc_id,
pjsua_acc_info *info)
{
pjsua_acc *acc = &pjsua_var.acc[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));
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);
PJSUA_LOCK();
if (pjsua_var.acc[acc_id].valid == PJ_FALSE) {
PJSUA_UNLOCK();
return PJ_EINVALIDOP;
}
info->id = acc_id;
info->is_default = (pjsua_var.default_acc == acc_id);
info->acc_uri = acc_cfg->id;
info->has_registration = (acc->cfg.reg_uri.slen > 0);
info->online_status = acc->online_status;
if (acc->reg_last_err) {
info->status = acc->reg_last_err;
pj_strerror(acc->reg_last_err, info->buf_, sizeof(info->buf_));
info->status_text = pj_str(info->buf_);
} else if (acc->reg_last_code) {
if (info->has_registration) {
info->status = acc->reg_last_code;
info->status_text = *pjsip_get_status_text(acc->reg_last_code);
} else {
info->status = 0;
info->status_text = pj_str("not registered");
}
} else if (acc->cfg.reg_uri.slen) {
info->status = 100;
info->status_text = pj_str("In Progress");
} else {
info->status = 0;
info->status_text = pj_str("does not register");
}
if (acc->regc) {
pjsip_regc_info regc_info;
pjsip_regc_get_info(acc->regc, ®c_info);
info->expires = regc_info.next_reg;
} else {
info->expires = -1;
}
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* Enum accounts all account ids.
*/
PJ_DEF(pj_status_t) pjsua_enum_accs(pjsua_acc_id ids[],
unsigned *count )
{
unsigned i, c;
PJ_ASSERT_RETURN(ids && *count, PJ_EINVAL);
PJSUA_LOCK();
for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) {
if (!pjsua_var.acc[i].valid)
continue;
ids[c] = i;
++c;
}
*count = c;
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* Enum accounts info.
*/
PJ_DEF(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
unsigned *count )
{
unsigned i, c;
PJ_ASSERT_RETURN(info && *count, PJ_EINVAL);
PJSUA_LOCK();
for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) {
if (!pjsua_var.acc[i].valid)
continue;
pjsua_acc_get_info(i, &info[c]);
++c;
}
*count = c;
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* This is an internal function to find the most appropriate account to
* used to reach to the specified URL.
*/
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 i;
PJSUA_LOCK();
PJ_TODO(dont_use_pjsua_pool);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -