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

📄 pjsua_core.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    } else if (type == PJSIP_TRANSPORT_TCP) {	/*	 * Create TCP transport.	 */	pjsua_transport_config config;	pjsip_host_port a_name;	pjsip_tpfactory *tcp;	pj_sockaddr_in local_addr;	/* Supply default config if it's not specified */	if (cfg == NULL) {	    pjsua_transport_config_default(&config);	    cfg = &config;	}	/* Init local address */	pj_sockaddr_in_init(&local_addr, 0, 0);	if (cfg->port)	    local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port);	if (cfg->bound_addr.slen) {	    status = pj_sockaddr_in_set_str_addr(&local_addr,&cfg->bound_addr);	    if (status != PJ_SUCCESS) {		pjsua_perror(THIS_FILE, 			     "Unable to resolve transport bound address", 			     status);		goto on_return;	    }	}	/* Init published name */	pj_bzero(&a_name, sizeof(pjsip_host_port));	if (cfg->public_addr.slen)	    a_name.host = cfg->public_addr;	/* Create the TCP transport */	status = pjsip_tcp_transport_start2(pjsua_var.endpt, &local_addr, 					    &a_name, 1, &tcp);	if (status != PJ_SUCCESS) {	    pjsua_perror(THIS_FILE, "Error creating SIP TCP listener", 			 status);	    goto on_return;	}	/* Save the transport */	pjsua_var.tpdata[id].type = type;	pjsua_var.tpdata[id].local_name = tcp->addr_name;	pjsua_var.tpdata[id].data.factory = tcp;#endif	/* PJ_HAS_TCP */#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0    } else if (type == PJSIP_TRANSPORT_TLS) {	/*	 * Create TLS transport.	 */	/*	 * Create TCP transport.	 */	pjsua_transport_config config;	pjsip_host_port a_name;	pjsip_tpfactory *tls;	pj_sockaddr_in local_addr;	/* Supply default config if it's not specified */	if (cfg == NULL) {	    pjsua_transport_config_default(&config);	    config.port = 5061;	    cfg = &config;	}	/* Init local address */	pj_sockaddr_in_init(&local_addr, 0, 0);	if (cfg->port)	    local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port);	if (cfg->bound_addr.slen) {	    status = pj_sockaddr_in_set_str_addr(&local_addr,&cfg->bound_addr);	    if (status != PJ_SUCCESS) {		pjsua_perror(THIS_FILE, 			     "Unable to resolve transport bound address", 			     status);		goto on_return;	    }	}	/* Init published name */	pj_bzero(&a_name, sizeof(pjsip_host_port));	if (cfg->public_addr.slen)	    a_name.host = cfg->public_addr;	status = pjsip_tls_transport_start(pjsua_var.endpt, 					   &cfg->tls_setting, 					   &local_addr, &a_name, 1, &tls);	if (status != PJ_SUCCESS) {	    pjsua_perror(THIS_FILE, "Error creating SIP TLS listener", 			 status);	    goto on_return;	}	/* Save the transport */	pjsua_var.tpdata[id].type = type;	pjsua_var.tpdata[id].local_name = tls->addr_name;	pjsua_var.tpdata[id].data.factory = tls;#endif    } else {	status = PJSIP_EUNSUPTRANSPORT;	pjsua_perror(THIS_FILE, "Error creating transport", status);	goto on_return;    }    /* Return the ID */    if (p_id) *p_id = id;    status = PJ_SUCCESS;on_return:    PJSUA_UNLOCK();    return status;}/* * Register transport that has been created by application. */PJ_DEF(pj_status_t) pjsua_transport_register( pjsip_transport *tp,					      pjsua_transport_id *p_id){    unsigned id;    PJSUA_LOCK();    /* Find empty transport slot */    for (id=0; id < PJ_ARRAY_SIZE(pjsua_var.tpdata); ++id) {	if (pjsua_var.tpdata[id].data.ptr == NULL)	    break;    }    if (id == PJ_ARRAY_SIZE(pjsua_var.tpdata)) {	pjsua_perror(THIS_FILE, "Error creating transport", PJ_ETOOMANY);	PJSUA_UNLOCK();	return PJ_ETOOMANY;    }    /* Save the transport */    pjsua_var.tpdata[id].type = tp->key.type;    pjsua_var.tpdata[id].local_name = tp->local_name;    pjsua_var.tpdata[id].data.tp = tp;    /* Return the ID */    if (p_id) *p_id = id;    PJSUA_UNLOCK();    return PJ_SUCCESS;}/* * Enumerate all transports currently created in the system. */PJ_DEF(pj_status_t) pjsua_enum_transports( pjsua_transport_id id[],					   unsigned *p_count ){    unsigned i, count;    PJSUA_LOCK();    for (i=0, count=0; i<PJ_ARRAY_SIZE(pjsua_var.tpdata) && count<*p_count; 	 ++i)     {	if (!pjsua_var.tpdata[i].data.ptr)	    continue;	id[count++] = i;    }    *p_count = count;    PJSUA_UNLOCK();    return PJ_SUCCESS;}/* * Get information about transports. */PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id,					      pjsua_transport_info *info){    pjsua_transport_data *t = &pjsua_var.tpdata[id];    pj_status_t status;    pj_bzero(info, sizeof(*info));    /* Make sure id is in range. */    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.tpdata), PJ_EINVAL);    /* Make sure that transport exists */    PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL);    PJSUA_LOCK();    if (pjsua_var.tpdata[id].type == PJSIP_TRANSPORT_UDP) {	pjsip_transport *tp = t->data.tp;	if (tp == NULL) {	    PJSUA_UNLOCK();	    return PJ_EINVALIDOP;	}    	info->id = id;	info->type = tp->key.type;	info->type_name = pj_str(tp->type_name);	info->info = pj_str(tp->info);	info->flag = tp->flag;	info->addr_len = tp->addr_len;	info->local_addr = tp->local_addr;	info->local_name = tp->local_name;	info->usage_count = pj_atomic_get(tp->ref_cnt);	status = PJ_SUCCESS;    } else if (pjsua_var.tpdata[id].type == PJSIP_TRANSPORT_TCP) {	pjsip_tpfactory *factory = t->data.factory;	if (factory == NULL) {	    PJSUA_UNLOCK();	    return PJ_EINVALIDOP;	}    	info->id = id;	info->type = t->type;	info->type_name = pj_str("TCP");	info->info = pj_str("TCP transport");	info->flag = factory->flag;	info->addr_len = sizeof(factory->local_addr);	info->local_addr = factory->local_addr;	info->local_name = factory->addr_name;	info->usage_count = 0;	status = PJ_SUCCESS;    } else {	pj_assert(!"Unsupported transport");	status = PJ_EINVALIDOP;    }    PJSUA_UNLOCK();    return status;}/* * Disable a transport or re-enable it. */PJ_DEF(pj_status_t) pjsua_transport_set_enable( pjsua_transport_id id,						pj_bool_t enabled){    /* Make sure id is in range. */    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.tpdata), PJ_EINVAL);    /* Make sure that transport exists */    PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL);    /* To be done!! */    PJ_TODO(pjsua_transport_set_enable);    PJ_UNUSED_ARG(enabled);    return PJ_EINVALIDOP;}/* * Close the transport. */PJ_DEF(pj_status_t) pjsua_transport_close( pjsua_transport_id id,					   pj_bool_t force ){    pj_status_t status;    /* Make sure id is in range. */    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.tpdata), PJ_EINVAL);    /* Make sure that transport exists */    PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL);    /* Note: destroy() may not work if there are objects still referencing     *	     the transport.     */    if (force) {	switch (pjsua_var.tpdata[id].type) {	case PJSIP_TRANSPORT_UDP:	    status = pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);	    if (status  != PJ_SUCCESS)		return status;	    status = pjsip_transport_destroy(pjsua_var.tpdata[id].data.tp);	    if (status != PJ_SUCCESS)		return status;	    break;	case PJSIP_TRANSPORT_TLS:	case PJSIP_TRANSPORT_TCP:	    /* This will close the TCP listener, but existing TCP/TLS	     * connections (if any) will still linger 	     */	    status = (*pjsua_var.tpdata[id].data.factory->destroy)			(pjsua_var.tpdata[id].data.factory);	    if (status != PJ_SUCCESS)		return status;	    break;	default:	    return PJ_EINVAL;	}	    } else {	/* If force is not specified, transports will be closed at their	 * convenient time. However this will leak PJSUA-API transport	 * descriptors as PJSUA-API wouldn't know when exactly the	 * transport is closed thus it can't cleanup PJSUA transport	 * descriptor.	 */	switch (pjsua_var.tpdata[id].type) {	case PJSIP_TRANSPORT_UDP:	    return pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);	case PJSIP_TRANSPORT_TLS:	case PJSIP_TRANSPORT_TCP:	    return (*pjsua_var.tpdata[id].data.factory->destroy)			(pjsua_var.tpdata[id].data.factory);	default:	    return PJ_EINVAL;	}    }    /* Cleanup pjsua data when force is applied */    if (force) {	pjsua_var.tpdata[id].type = PJSIP_TRANSPORT_UNSPECIFIED;	pjsua_var.tpdata[id].data.ptr = NULL;    }    return PJ_SUCCESS;}/* * Add additional headers etc in msg_data specified by application * when sending requests. */void pjsua_process_msg_data(pjsip_tx_data *tdata,			    const pjsua_msg_data *msg_data){    pj_bool_t allow_body;    const pjsip_hdr *hdr;    /* Always add User-Agent */    if (pjsua_var.ua_cfg.user_agent.slen && 	tdata->msg->type == PJSIP_REQUEST_MSG)     {	const pj_str_t STR_USER_AGENT = { "User-Agent", 10 };	pjsip_hdr *h;	h = (pjsip_hdr*)pjsip_generic_string_hdr_create(tdata->pool, 							&STR_USER_AGENT, 							&pjsua_var.ua_cfg.user_agent);	pjsip_msg_add_hdr(tdata->msg, h);    }    if (!msg_data)	return;    hdr = msg_data->hdr_list.next;    while (hdr && hdr != &msg_data->hdr_list) {	pjsip_hdr *new_hdr;	new_hdr = pjsip_hdr_clone(tdata->pool, hdr);	pjsip_msg_add_hdr(tdata->msg, new_hdr);	hdr = hdr->next;    }    allow_body = (tdata->msg->body == NULL);    if (allow_body && msg_data->content_type.slen && msg_data->msg_body.slen) {	pjsip_media_type ctype;	pjsip_msg_body *body;		pjsua_parse_media_type(tdata->pool, &msg_data->content_type, &ctype);	body = pjsip_msg_body_create(tdata->pool, &ctype.type, &ctype.subtype,				     &msg_data->msg_body);	tdata->msg->body = body;    }}/* * Add route_set to outgoing requests */void pjsua_set_msg_route_set( pjsip_tx_data *tdata,			      const pjsip_route_hdr *route_set ){    const pjsip_route_hdr *r;    r = route_set->next;    while (r != route_set) {	pjsip_route_hdr *new_r;	new_r = pjsip_hdr_clone(tdata->pool, r);	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)new_r);	r = r->next;    }}/* * Simple version of MIME type parsing (it doesn't support parameters) */void pjsua_parse_media_type( pj_pool_t *pool,			     const pj_str_t *mime,			     pjsip_media_type *media_type){    pj_str_t tmp;    char *pos;    pj_bzero(media_type, sizeof(*media_type));    pj_strdup_with_null(pool, &tmp, mime);    pos = pj_strchr(&tmp, '/');    if (pos) {	media_type->type.ptr = tmp.ptr; 	media_type->type.slen = (pos-tmp.ptr);	media_type->subtype.ptr = pos+1; 	media_type->subtype.slen = tmp.ptr+tmp.slen-pos-1;    } else {	media_type->type = tmp;    }}/* * Internal function to init transport selector from transport id. */void pjsua_init_tpselector(pjsua_transport_id tp_id,			   pjsip_tpselector *sel){    pjsua_transport_data *tpdata;    unsigned flag;    pj_bzero(sel, sizeof(*sel));    if (tp_id == PJSUA_INVALID_ID)	return;    pj_assert(tp_id >= 0 && tp_id < PJ_ARRAY_SIZE(pjsua_var.tpdata));    tpdata = &pjsua_var.tpdata[tp_id];    flag = pjsip_transport_get_flag_from_type(tpdata->type);    if (flag & PJSIP_TRANSPORT_DATAGRAM) {	sel->type = PJSIP_TPSELECTOR_TRANSPORT;	sel->u.transport = tpdata->data.tp;    } else {	sel->type = PJSIP_TPSELECTOR_LISTENER;	sel->u.listener = tpdata->data.factory;    }}/* * Verify that valid SIP url is given. */PJ_DEF(pj_status_t) pjsua_verify_sip_url(const char *c_url){    pjsip_uri *p;    pj_pool_t *pool;    char *url;    int len = (c_url ? pj_ansi_strlen(c_url) : 0);    if (!len) return -1;    pool = pj_pool_create(&pjsua_var.cp.factory, "check%p", 1024, 0, NULL);    if (!pool) return -1;    url = pj_pool_alloc(pool, len+1);    pj_ansi_strcpy(url, c_url);    p = pjsip_parse_uri(pool, url, len, 0);    if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0)	p = NULL;    pj_pool_release(pool);    return p ? 0 : -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -