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

📄 sip_reg.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (!pj_list_empty(&regc->route_set)) {	pjsip_hdr *route_pos;	const pjsip_route_hdr *route;	route_pos = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);	if (!route_pos)	    route_pos = &tdata->msg->hdr;	route = regc->route_set.next;	while (route != &regc->route_set) {	    pjsip_hdr *new_hdr = pjsip_hdr_shallow_clone(tdata->pool, route);	    pj_list_insert_after(route_pos, new_hdr);	    route_pos = new_hdr;	    route = route->next;	}    }    /* Add additional request headers */    if (!pj_list_empty(&regc->hdr_list)) {	const pjsip_hdr *hdr;	hdr = regc->hdr_list.next;	while (hdr != &regc->hdr_list) {	    pjsip_hdr *new_hdr = pjsip_hdr_shallow_clone(tdata->pool, hdr);	    pjsip_msg_add_hdr(tdata->msg, new_hdr);	    hdr = hdr->next;	}    }    /* Done. */    *p_tdata = tdata;    return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,					pjsip_tx_data **p_tdata){    pjsip_msg *msg;    pj_status_t status;    pjsip_tx_data *tdata;    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);    status = create_request(regc, &tdata);    if (status != PJ_SUCCESS)	return status;    /* Add Contact header. */    msg = tdata->msg;    pjsip_msg_add_hdr(msg, pjsip_hdr_shallow_clone(tdata->pool, 						   regc->contact_hdr));    if (regc->expires_hdr)	pjsip_msg_add_hdr(msg, pjsip_hdr_shallow_clone(tdata->pool,						       regc->expires_hdr));    if (regc->timer.id != 0) {	pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);	regc->timer.id = 0;    }    regc->auto_reg = autoreg;    /* Done */    *p_tdata = tdata;    return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc,					  pjsip_tx_data **p_tdata){    pjsip_tx_data *tdata;    pjsip_msg *msg;    pj_status_t status;    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);    if (regc->timer.id != 0) {	pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);	regc->timer.id = 0;    }    status = create_request(regc, &tdata);    if (status != PJ_SUCCESS)	return status;    msg = tdata->msg;    pjsip_msg_add_hdr(msg, pjsip_hdr_shallow_clone(tdata->pool, 						   regc->contact_hdr));    pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr);    *p_tdata = tdata;    return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_regc_unregister_all(pjsip_regc *regc,					      pjsip_tx_data **p_tdata){    pjsip_tx_data *tdata;    pjsip_msg *msg;    pj_status_t status;    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);    if (regc->timer.id != 0) {	pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);	regc->timer.id = 0;    }    status = create_request(regc, &tdata);    if (status != PJ_SUCCESS)	return status;    msg = tdata->msg;    pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_contact_hdr);    pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr);    *p_tdata = tdata;    return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_regc_update_contact(  pjsip_regc *regc,					        int contact_cnt,						const pj_str_t contact[] ){    PJ_ASSERT_RETURN(regc, PJ_EINVAL);    return set_contact( regc, contact_cnt, contact );}PJ_DEF(pj_status_t) pjsip_regc_update_expires(  pjsip_regc *regc,					        pj_uint32_t expires ){    PJ_ASSERT_RETURN(regc, PJ_EINVAL);    set_expires( regc, expires );    return PJ_SUCCESS;}static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code, 			  const pj_str_t *reason,			  pjsip_rx_data *rdata, pj_int32_t expiration,			  int contact_cnt, pjsip_contact_hdr *contact[]){    struct pjsip_regc_cbparam cbparam;    if (!regc->cb)	return;    cbparam.regc = regc;    cbparam.token = regc->token;    cbparam.status = status;    cbparam.code = st_code;    cbparam.reason = *reason;    cbparam.rdata = rdata;    cbparam.contact_cnt = contact_cnt;    cbparam.expiration = expiration;    if (contact_cnt) {	pj_memcpy( cbparam.contact, contact, 		   contact_cnt*sizeof(pjsip_contact_hdr*));    }    (*regc->cb)(&cbparam);}static void regc_refresh_timer_cb( pj_timer_heap_t *timer_heap,				   struct pj_timer_entry *entry){    pjsip_regc *regc = entry->user_data;    pjsip_tx_data *tdata;    pj_status_t status;        PJ_UNUSED_ARG(timer_heap);    /* Temporarily increase busy flag to prevent regc from being deleted     * in pjsip_regc_send()     */    regc->busy++;    entry->id = 0;    status = pjsip_regc_register(regc, 1, &tdata);    if (status == PJ_SUCCESS) {	status = pjsip_regc_send(regc, tdata);    }         if (status != PJ_SUCCESS && regc->cb) {	char errmsg[PJ_ERR_MSG_SIZE];	pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg));	call_callback(regc, status, 400, &reason, NULL, -1, 0, NULL);    }    regc->busy--;    /* Delete the record if user destroy regc during the callback. */    if (regc->_delete_flag && regc->busy==0) {	pjsip_regc_destroy(regc);    }}static void tsx_callback(void *token, pjsip_event *event){    pj_status_t status;    pjsip_regc *regc = token;    pjsip_transaction *tsx = event->body.tsx_state.tsx;        /* Decrement pending transaction counter. */    pj_assert(regc->has_tsx);    regc->has_tsx = PJ_FALSE;    /* Handle 401/407 challenge (even when _delete_flag is set) */    if (tsx->status_code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED ||	tsx->status_code == PJSIP_SC_UNAUTHORIZED)    {	pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;	pjsip_tx_data *tdata;	status = pjsip_auth_clt_reinit_req( &regc->auth_sess,					    rdata, 					    tsx->last_tx,  					    &tdata);	if (status == PJ_SUCCESS) {	    status = pjsip_regc_send(regc, tdata);	} 		if (status != PJ_SUCCESS) {	    /* Only call callback if application is still interested	     * in it.	     */	    if (regc->_delete_flag == 0) {		/* Increment busy flag temporarily to prevent regc from		 * being destroyed.		 */		++regc->busy;		call_callback(regc, status, tsx->status_code, 			      &rdata->msg_info.msg->line.status.reason,			      rdata, -1, 0, NULL);		/* Decrement busy flag */		--regc->busy;	    }	}    } else if (regc->_delete_flag) {	/* User has called pjsip_regc_destroy(), so don't call callback. 	 * This regc will be destroyed later in this function.	 */	/* Nothing to do */	;    } else {	int contact_cnt = 0;	pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT];	pjsip_rx_data *rdata;	pj_int32_t expiration = 0xFFFF;	if (tsx->status_code/100 == 2) {	    int i;	    pjsip_contact_hdr *hdr;	    pjsip_msg *msg;	    pjsip_expires_hdr *expires;	    rdata = event->body.tsx_state.src.rdata;	    msg = rdata->msg_info.msg;	    hdr = pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL);	    while (hdr) {		contact[contact_cnt++] = hdr;		hdr = hdr->next;		if (hdr == (void*)&msg->hdr)		    break;		hdr = pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, hdr);	    }	    expires = pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);	    if (expires)		expiration = expires->ivalue;	    	    for (i=0; i<contact_cnt; ++i) {		hdr = contact[i];		if (hdr->expires >= 0 && hdr->expires < expiration)		    expiration = contact[i]->expires;	    }	    if (regc->auto_reg && expiration != 0 && expiration != 0xFFFF) {		pj_time_val delay = { 0, 0};		delay.sec = expiration - DELAY_BEFORE_REFRESH;		if (regc->expires != PJSIP_REGC_EXPIRATION_NOT_SPECIFIED && 		    delay.sec > (pj_int32_t)regc->expires) 		{		    delay.sec = regc->expires;		}		if (delay.sec < DELAY_BEFORE_REFRESH) 		    delay.sec = DELAY_BEFORE_REFRESH;		regc->timer.cb = &regc_refresh_timer_cb;		regc->timer.id = REFRESH_TIMER;		regc->timer.user_data = regc;		pjsip_endpt_schedule_timer( regc->endpt, &regc->timer, &delay);		pj_gettimeofday(&regc->last_reg);		regc->next_reg = regc->last_reg;		regc->next_reg.sec += delay.sec;	    }	} else {	    rdata = (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? 			event->body.tsx_state.src.rdata : NULL;	}	/* Increment busy flag temporarily to prevent regc from	 * being destroyed.	 */	++regc->busy;	/* Call callback. */	if (expiration == 0xFFFF) expiration = -1;	call_callback(regc, PJ_SUCCESS, tsx->status_code, 		      (rdata ? &rdata->msg_info.msg->line.status.reason 			: pjsip_get_status_text(tsx->status_code)),		      rdata, expiration, 		      contact_cnt, contact);	/* Decrement busy flag */	--regc->busy;    }    /* Delete the record if user destroy regc during the callback. */    if (regc->_delete_flag && regc->busy==0) {	pjsip_regc_destroy(regc);    }}PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata){    pj_status_t status;    pjsip_cseq_hdr *cseq_hdr;    pj_uint32_t cseq;    /* Make sure we don't have pending transaction. */    if (regc->has_tsx) {	PJ_LOG(4,(THIS_FILE, "Unable to send request, regc has another "			     "transaction pending"));	pjsip_tx_data_dec_ref( tdata );	return PJSIP_EBUSY;    }    /* Invalidate message buffer. */    pjsip_tx_data_invalidate_msg(tdata);    /* Increment CSeq */    cseq = ++regc->cseq_hdr->cseq;    cseq_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);    cseq_hdr->cseq = cseq;    /* Increment pending transaction first, since transaction callback     * may be called even before send_request() returns!     */    regc->has_tsx = PJ_TRUE;    ++regc->busy;    status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,				      regc, &tsx_callback);    if (status!=PJ_SUCCESS) {	PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status));    }    --regc->busy;    /* Delete the record if user destroy regc during the callback. */    if (regc->_delete_flag && regc->busy==0) {	pjsip_regc_destroy(regc);    }    return status;}

⌨️ 快捷键说明

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