⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pjsua_acc.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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, &regc_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);    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 + -