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

📄 sip_xaction_state_mc.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 3 页
字号:
	sip_xaction_time_obj_t	*timer_obj_K = NULL;	sip_message_type_t	*sip_msg_info;	int			prev_state;	_sip_msg_t		*msg = *sip_msg;	boolean_t		isreliable;	assert(msg->sip_msg_req_res != NULL);	assert(sip_trans != NULL);	sip_msg_info = msg->sip_msg_req_res;	isreliable = sip_is_conn_reliable(conn_obj);	resp_code = sip_msg_info->sip_resp_code;	(void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex);	prev_state = sip_trans->sip_xaction_state;	switch (sip_trans->sip_xaction_state) {		case SIPS_CLNT_TRYING:			if (SIP_PROVISIONAL_RESP(resp_code)) {				sip_trans->sip_xaction_state =				    SIPS_CLNT_NONINV_PROCEEDING;			} else if (SIP_FINAL_RESP(resp_code)) {				SIP_CANCEL_TIMER(				    sip_trans->sip_xaction_TE);				SIP_CANCEL_TIMER(				    sip_trans->sip_xaction_TF);				/* Start timer K for unreliable transports */				if (!isreliable) {					timer_obj_K = sip_setup_timer(					    conn_obj, sip_trans,					    NULL, sip_trans->sip_xaction_TK,					    SIP_XACTION_TIMER_K);					if (timer_obj_K == NULL) {						(void) pthread_mutex_unlock(&						    sip_trans->						    sip_xaction_mutex);						return (ENOMEM);					}					SIP_SCHED_TIMER(					    sip_trans->sip_xaction_TK,					    timer_obj_K,					    sip_xaction_state_timer_fire);					if (!SIP_IS_TIMER_RUNNING(					    sip_trans->sip_xaction_TK)) {						(void) pthread_mutex_unlock(						    &sip_trans->						    sip_xaction_mutex);						free(timer_obj_K);						return (ENOMEM);					}					sip_trans->sip_xaction_state =					    SIPS_CLNT_NONINV_COMPLETED;				} else {					sip_trans->sip_xaction_state =					    SIPS_CLNT_NONINV_TERMINATED;				}			}			break;		case SIPS_CLNT_NONINV_PROCEEDING:			if (SIP_PROVISIONAL_RESP(resp_code)) {				break;			} else if (SIP_FINAL_RESP(resp_code)) {				SIP_CANCEL_TIMER(				    sip_trans->sip_xaction_TE);				SIP_CANCEL_TIMER(				    sip_trans->sip_xaction_TF);				/* Start timer K for unreliable transports */				if (!isreliable) {					timer_obj_K = sip_setup_timer(					    conn_obj, sip_trans,					    NULL, sip_trans->sip_xaction_TK,					    SIP_XACTION_TIMER_K);					if (timer_obj_K == NULL) {						(void) pthread_mutex_unlock(&						    sip_trans->						    sip_xaction_mutex);						return (ENOMEM);					}					SIP_SCHED_TIMER(					    sip_trans->sip_xaction_TK,					    timer_obj_K,					    sip_xaction_state_timer_fire);					if (!SIP_IS_TIMER_RUNNING(					    sip_trans->sip_xaction_TK)) {						(void) pthread_mutex_unlock(						    &sip_trans->						    sip_xaction_mutex);						free(timer_obj_K);						return (ENOMEM);					}					sip_trans->sip_xaction_state =					    SIPS_CLNT_NONINV_COMPLETED;				} else {					sip_trans->sip_xaction_state =					    SIPS_CLNT_NONINV_TERMINATED;				}			}			break;		default:			(void) pthread_mutex_unlock(			    &sip_trans->sip_xaction_mutex);			return (EPROTO);	}	(void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex);	if (prev_state != sip_trans->sip_xaction_state &&	    sip_xaction_ulp_state_cb != NULL) {		sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans,		    (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state);	}	return (0);}/* * * If there is a transport error, sending the message out, terminate the * transaction. *//* ARGSUSED */voidsip_xaction_terminate(sip_xaction_t *sip_trans, _sip_msg_t *msg, int transport){	sip_message_type_t	*sip_msg_info;	int			state;	int			prev_state;	sip_msg_info = msg->sip_msg_req_res;	(void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex);	if (sip_msg_info->is_request) {		if (sip_trans->sip_xaction_method == INVITE)			state = SIPS_CLNT_INV_TERMINATED;		else			state = SIPS_CLNT_NONINV_TERMINATED;	} else {		if (sip_trans->sip_xaction_method == INVITE)			state = SIPS_SRV_INV_TERMINATED;		else			state = SIPS_SRV_NONINV_TERMINATED;	}	prev_state = sip_trans->sip_xaction_state;	sip_trans->sip_xaction_state = state;	(void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex);	if (sip_xaction_ulp_state_cb != NULL) {		sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans,		    (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state);	}	sip_xaction_delete(sip_trans);}/* * --------------------------- Timer Routine --------------------------- */voidsip_xaction_state_timer_fire(void *args){	sip_xaction_time_obj_t	*time_obj = (sip_xaction_time_obj_t *)args;	sip_xaction_t		*sip_trans = time_obj->sip_trans;	_sip_msg_t		*new_msg;	boolean_t		destroy_trans = B_FALSE;	sip_conn_object_t	conn_obj;	int			prev_state;	assert(time_obj != NULL);	(void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex);	prev_state = sip_trans->sip_xaction_state;	switch (time_obj->sip_xaction_timer_type) {		case SIP_XACTION_TIMER_A:			if (sip_trans->sip_xaction_state != SIPS_CLNT_CALLING)				break;			/* Assert candidate */			if (sip_trans->sip_xaction_last_msg == NULL)				break;			if (sip_trans->sip_xaction_conn_obj == NULL)				break;			new_msg = sip_trans->sip_xaction_last_msg;			conn_obj = sip_trans->sip_xaction_conn_obj;			if (sip_stack_send(conn_obj, new_msg->sip_msg_buf,			    new_msg->sip_msg_len) != 0) {				sip_del_conn_obj_cache(				    sip_trans->sip_xaction_conn_obj,				    (void *)sip_trans);				sip_trans->sip_xaction_state =				    SIPS_CLNT_INV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			SIP_SET_TIMEOUT(sip_trans->sip_xaction_TA,			    2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TA));			/* Reschedule the timer */			SIP_SCHED_TIMER(sip_trans->sip_xaction_TA,			    time_obj, sip_xaction_state_timer_fire);			if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TA)) {				sip_del_conn_obj_cache(				    sip_trans->sip_xaction_conn_obj,				    (void *)sip_trans);				sip_trans->sip_xaction_state =				    SIPS_CLNT_INV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			(void) pthread_mutex_unlock(			    &sip_trans->sip_xaction_mutex);			return;		case SIP_XACTION_TIMER_B:			SIP_CANCEL_TIMER(sip_trans->sip_xaction_TA);			if (sip_trans->sip_xaction_state == SIPS_CLNT_CALLING) {				sip_trans->sip_xaction_state =				    SIPS_CLNT_INV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			break;		case SIP_XACTION_TIMER_D:			if (sip_trans->sip_xaction_state ==			    SIPS_CLNT_INV_COMPLETED) {				SIP_CANCEL_TIMER(				    sip_trans->sip_xaction_TB);				sip_trans->sip_xaction_state =				    SIPS_CLNT_INV_TERMINATED;				destroy_trans = B_TRUE;			}			break;		case SIP_XACTION_TIMER_E:			/* Assert candidate */			if (sip_trans->sip_xaction_state != SIPS_CLNT_TRYING &&			    sip_trans->sip_xaction_state !=			    SIPS_CLNT_NONINV_PROCEEDING) {				break;			}			/* Assert candidate */			if (sip_trans->sip_xaction_last_msg == NULL)				break;			if (sip_trans->sip_xaction_conn_obj == NULL)				break;			conn_obj = sip_trans->sip_xaction_conn_obj;			new_msg = sip_trans->sip_xaction_last_msg;			if (sip_stack_send(conn_obj, new_msg->sip_msg_buf,			    new_msg->sip_msg_len) != 0) {				sip_del_conn_obj_cache(				    sip_trans->sip_xaction_conn_obj,				    (void *)sip_trans);				sip_trans->sip_xaction_state =				    SIPS_CLNT_NONINV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			SIP_SET_TIMEOUT(sip_trans->sip_xaction_TE,			    MIN(SIP_TIMER_T2,			    2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TE)));			/* Reschedule the timer */			SIP_SCHED_TIMER(sip_trans->sip_xaction_TE,			    time_obj, sip_xaction_state_timer_fire);			if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TE)) {				sip_del_conn_obj_cache(				    sip_trans->sip_xaction_conn_obj,				    (void *)sip_trans);				sip_trans->sip_xaction_state =				    SIPS_CLNT_NONINV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			(void) pthread_mutex_unlock(			    &sip_trans->sip_xaction_mutex);			return;		case SIP_XACTION_TIMER_F:			SIP_CANCEL_TIMER(sip_trans->sip_xaction_TE);			/* XXXCheck for deleting sip_xaction_last_msg */			if (sip_trans->sip_xaction_state == SIPS_CLNT_TRYING ||			    sip_trans->sip_xaction_state ==			    SIPS_CLNT_NONINV_PROCEEDING) {				sip_trans->sip_xaction_state =				    SIPS_CLNT_NONINV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			break;		case SIP_XACTION_TIMER_G:			/* Assert candidate */			if (sip_trans->sip_xaction_last_msg == NULL)				break;			if (sip_trans->sip_xaction_conn_obj == NULL)				break;			if (sip_trans->sip_xaction_state !=			    SIPS_SRV_INV_COMPLETED) {				break;			}			new_msg = sip_trans->sip_xaction_last_msg;			conn_obj = sip_trans->sip_xaction_conn_obj;			if (sip_stack_send(conn_obj, new_msg->sip_msg_buf,			    new_msg->sip_msg_len) != 0) {				sip_del_conn_obj_cache(				    sip_trans->sip_xaction_conn_obj,				    (void *)sip_trans);				sip_trans->sip_xaction_state =				    SIPS_SRV_INV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			SIP_SET_TIMEOUT(sip_trans->sip_xaction_TG,			    MIN(SIP_TIMER_T2,			    2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TG)));			SIP_SCHED_TIMER(sip_trans->sip_xaction_TG,			    time_obj, sip_xaction_state_timer_fire);			if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TG)) {				sip_del_conn_obj_cache(				    sip_trans->sip_xaction_conn_obj,				    (void *)sip_trans);				sip_trans->sip_xaction_state =				    SIPS_SRV_INV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			(void) pthread_mutex_unlock(			    &sip_trans->sip_xaction_mutex);			return;		case SIP_XACTION_TIMER_H:			SIP_CANCEL_TIMER(sip_trans->sip_xaction_TG);			/* XXXCheck for deleting sip_xaction_last_msg */			if (sip_trans->sip_xaction_state ==			    SIPS_SRV_INV_COMPLETED) {				sip_trans->sip_xaction_state =				    SIPS_SRV_INV_TERMINATED;				(void) pthread_mutex_unlock(				    &sip_trans->sip_xaction_mutex);				if (sip_xaction_ulp_state_cb != NULL) {				    sip_xaction_ulp_state_cb(				    (sip_transaction_t)sip_trans, NULL,				    prev_state, sip_trans->sip_xaction_state);				}				if (sip_xaction_ulp_trans_err != NULL) {					sip_xaction_ulp_trans_err(sip_trans, 0,					    NULL);				}				sip_xaction_delete(sip_trans);				free(time_obj);				return;			}			break;		case SIP_XACTION_TIMER_I:			if (sip_trans->sip_xaction_state ==			    SIPS_SRV_CONFIRMED) {				SIP_CANCEL_TIMER(				    sip_trans->sip_xaction_TH);				sip_trans->sip_xaction_state =				    SIPS_SRV_INV_TERMINATED;				destroy_trans = B_TRUE;			}			break;		case SIP_XACTION_TIMER_J:			if (sip_trans->sip_xaction_state ==			    SIPS_SRV_NONINV_COMPLETED) {				sip_trans->sip_xaction_state =				    SIPS_SRV_NONINV_TERMINATED;				destroy_trans = B_TRUE;			}			break;		case SIP_XACTION_TIMER_K:			if (sip_trans->sip_xaction_state ==			    SIPS_CLNT_NONINV_COMPLETED) {				SIP_CANCEL_TIMER(				    sip_trans->sip_xaction_TF);				sip_trans->sip_xaction_state =				    SIPS_CLNT_NONINV_TERMINATED;				destroy_trans = B_TRUE;			}			break;		default:			break;	}	if (destroy_trans) {		(void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex);		if (sip_xaction_ulp_state_cb != NULL &&		    prev_state != sip_trans->sip_xaction_state) {			sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans,			    NULL, prev_state, sip_trans->sip_xaction_state);		}		sip_xaction_delete(sip_trans);		free(time_obj);		return;	}	(void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex);	if (sip_xaction_ulp_state_cb != NULL &&	    prev_state != sip_trans->sip_xaction_state) {		sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, NULL,		    prev_state, sip_trans->sip_xaction_state);	}	free(time_obj);}

⌨️ 快捷键说明

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