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

📄 sip_xaction.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * create a transaction. */static sip_xaction_t *sip_xaction_create(sip_conn_object_t obj, _sip_msg_t *msg, char *branchid,    int *error){	sip_xaction_t		*trans;	sip_message_type_t	*sip_msg_info;	int			state = 0;	int			prev_state = 0;	sip_method_t		method;	int			ret;	int			timer1 = sip_timer_T1;	int			timer4 = sip_timer_T4;	int			timerd = sip_timer_TD;	if (error != NULL)		*error = 0;	/*	 * Make sure we are not creating a transaction for	 * an ACK request.	 */	trans = (sip_xaction_t *)malloc(sizeof (sip_xaction_t));	if (trans == NULL) {		if (error != NULL)			*error = ENOMEM;		return (NULL);	}	bzero(trans, sizeof (sip_xaction_t));	if (branchid == NULL) {		trans->sip_xaction_branch_id = (char *)sip_branchid(NULL);		if (trans->sip_xaction_branch_id == NULL) {			free(trans);			if (error != NULL)				*error = ENOMEM;			return (NULL);		}	} else {		trans->sip_xaction_branch_id = (char *)malloc(strlen(branchid)		    + 1);		if (trans->sip_xaction_branch_id == NULL) {			free(trans);			if (error != NULL)				*error = ENOMEM;			return (NULL);		}		(void) strncpy(trans->sip_xaction_branch_id, branchid,		    strlen(branchid));		trans->sip_xaction_branch_id[strlen(branchid)] = '\0';	}	(void) pthread_mutex_init(&trans->sip_xaction_mutex, NULL);	SIP_MSG_REFCNT_INCR(msg);	trans->sip_xaction_orig_msg = msg;	assert(msg->sip_msg_req_res != NULL);	sip_msg_info = msg->sip_msg_req_res;	if (sip_msg_info->is_request) {		method = sip_msg_info->sip_req_method;	} else {		method = sip_get_callseq_method((sip_msg_t)msg, &ret);		if (ret != 0) {			free(trans->sip_xaction_branch_id);			free(trans);			if (error != NULL)				*error = ret;			return (NULL);		}		if (method == INVITE)			state = SIPS_SRV_INV_PROCEEDING;		else			state = SIPS_SRV_TRYING;	}	trans->sip_xaction_method = method;	trans->sip_xaction_state = state;	/* Get connection object specific timeouts, if present */	if (sip_conn_timer1 != NULL)		timer1 = sip_conn_timer1(obj);	if (sip_conn_timer4 != NULL)		timer4 = sip_conn_timer4(obj);	if (sip_conn_timerd != NULL)		timerd = sip_conn_timerd(obj);	SIP_INIT_TIMER(trans->sip_xaction_TA, 2 * timer1);	SIP_INIT_TIMER(trans->sip_xaction_TB, 64 * timer1)	SIP_INIT_TIMER(trans->sip_xaction_TD,  timerd);	SIP_INIT_TIMER(trans->sip_xaction_TE, timer1);	SIP_INIT_TIMER(trans->sip_xaction_TF, 64 * timer1);	SIP_INIT_TIMER(trans->sip_xaction_TG, 2 * timer1);	SIP_INIT_TIMER(trans->sip_xaction_TH, 64 * timer1);	SIP_INIT_TIMER(trans->sip_xaction_TI, timer4);	SIP_INIT_TIMER(trans->sip_xaction_TJ, 64 * timer1);	SIP_INIT_TIMER(trans->sip_xaction_TK, timer4);	if ((ret = sip_xaction_add(trans, branchid, msg, method)) != 0) {		(void) pthread_mutex_destroy(&trans->sip_xaction_mutex);		free(trans->sip_xaction_branch_id);		free(trans);		if (error != NULL)			*error = ret;		return (NULL);	}	if (sip_xaction_ulp_state_cb != NULL &&	    prev_state != trans->sip_xaction_state) {		sip_xaction_ulp_state_cb((sip_transaction_t)trans,		    (sip_msg_t)msg, prev_state, trans->sip_xaction_state);	}	return (trans);}/* Find a transaction, create if asked for */sip_xaction_t *sip_xaction_get(sip_conn_object_t obj, sip_msg_t msg, boolean_t create,    int which, int *error){	char			*branchid;	sip_xaction_t		*sip_trans;	_sip_msg_t		*_msg;	sip_message_type_t	*sip_msg_info;	if (error != NULL)		*error = 0;	_msg = (_sip_msg_t *)msg;	sip_msg_info = ((_sip_msg_t *)msg)->sip_msg_req_res;	branchid = sip_get_branchid(msg, NULL);	sip_trans = sip_xaction_find(branchid, _msg, which);	if (sip_trans == NULL && create) {		/*		 * If we are sending a request, must be conformant to RFC 3261.		 */		if (sip_msg_info->is_request &&		    (branchid == NULL || strncmp(branchid,		    RFC_3261_BRANCH, strlen(RFC_3261_BRANCH) != 0))) {			if (error != NULL)				*error = EINVAL;			if (branchid != NULL)				free(branchid);			return (NULL);		}		sip_trans = sip_xaction_create(obj, _msg, branchid, error);		if (sip_trans != NULL)			SIP_XACTION_REFCNT_INCR(sip_trans);	}	if (branchid != NULL)		free(branchid);	return (sip_trans);}/* * Delete a transaction if the reference count is 0. Passed to * sip_hash_delete(). */boolean_tsip_xaction_remove(void *obj, void *hindex, int *found){	sip_xaction_t	*tmp = (sip_xaction_t *)obj;	*found = 0;	tmp = (sip_xaction_t *)obj;	if (bcmp(tmp->sip_xaction_hash_digest, hindex,	    sizeof (tmp->sip_xaction_hash_digest)) == 0) {		*found = 1;		if (tmp->sip_xaction_ref_cnt != 0)			return (B_FALSE);		(void) pthread_mutex_destroy(&tmp->sip_xaction_mutex);		SIP_CANCEL_TIMER(tmp->sip_xaction_TA);		SIP_CANCEL_TIMER(tmp->sip_xaction_TB);		SIP_CANCEL_TIMER(tmp->sip_xaction_TD);		SIP_CANCEL_TIMER(tmp->sip_xaction_TE);		SIP_CANCEL_TIMER(tmp->sip_xaction_TF);		SIP_CANCEL_TIMER(tmp->sip_xaction_TG);		SIP_CANCEL_TIMER(tmp->sip_xaction_TH);		SIP_CANCEL_TIMER(tmp->sip_xaction_TI);		SIP_CANCEL_TIMER(tmp->sip_xaction_TJ);		SIP_CANCEL_TIMER(tmp->sip_xaction_TK);		free(tmp->sip_xaction_branch_id);		if (tmp->sip_xaction_last_msg != NULL) {			SIP_MSG_REFCNT_DECR(tmp->sip_xaction_last_msg);			tmp->sip_xaction_last_msg = NULL;		}		if (tmp->sip_xaction_orig_msg != NULL) {			SIP_MSG_REFCNT_DECR(tmp->sip_xaction_orig_msg);			tmp->sip_xaction_orig_msg = NULL;		}		if (tmp->sip_xaction_conn_obj != NULL) {			sip_del_conn_obj_cache(tmp->sip_xaction_conn_obj,			    (void *)tmp);		}		free(tmp);		return (B_TRUE);	}	return (B_FALSE);}/* * Delete a SIP transaction */voidsip_xaction_delete(sip_xaction_t *trans){	int	hindex;	hindex = SIP_DIGEST_TO_HASH(trans->sip_xaction_hash_digest);	sip_hash_delete(sip_xaction_hash, trans->sip_xaction_hash_digest,	    hindex, sip_xaction_remove);}/* * Add a SIP transaction into the hash list. */intsip_xaction_add(sip_xaction_t *trans, char *branchid, _sip_msg_t *msg,    sip_method_t method){	uint16_t	hash_index[8];	if (sip_find_md5_digest(branchid, msg, hash_index, method) != 0)		return (EINVAL);	/* trans is not in the list as yet, so no need to hold the lock */	bcopy(hash_index, trans->sip_xaction_hash_digest, sizeof (hash_index));	if (sip_hash_add(sip_xaction_hash, (void *)trans,	    SIP_DIGEST_TO_HASH(hash_index)) != 0) {		return (ENOMEM);	}	return (0);}/* Utility routine *//* Given a state, return the  string - This is mostly for debug purposes */char *sip_get_xaction_state(int state){	switch (state) {		case SIPS_CLNT_CALLING:			return ("SIPS_CLNT_CALLING");		case SIPS_CLNT_INV_PROCEEDING:			return ("SIPS_CLNT_INV_PROCEEDING");		case SIPS_CLNT_INV_TERMINATED:			return ("SIPS_CLNT_INV_TERMINATED");		case SIPS_CLNT_INV_COMPLETED:			return ("SIPS_CLNT_INV_COMPLETED");		case SIPS_CLNT_TRYING:			return ("SIPS_CLNT_TRYING");		case SIPS_CLNT_NONINV_PROCEEDING:			return ("SIPS_CLNT_NONINV_PROCEEDING");		case SIPS_CLNT_NONINV_TERMINATED:			return ("SIPS_CLNT_NONINV_TERMINATED");		case SIPS_CLNT_NONINV_COMPLETED:			return ("SIPS_CLNT_NONINV_COMPLETED");		case SIPS_SRV_INV_PROCEEDING:			return ("SIPS_SRV_INV_PROCEEDING");		case SIPS_SRV_INV_COMPLETED:			return ("SIPS_SRV_INV_COMPLETED");		case SIPS_SRV_CONFIRMED:			return ("SIPS_SRV_CONFIRMED");		case SIPS_SRV_INV_TERMINATED:			return ("SIPS_SRV_INV_TERMINATED");		case SIPS_SRV_TRYING:			return ("SIPS_SRV_TRYING");		case SIPS_SRV_NONINV_PROCEEDING:			return ("SIPS_SRV_NONINV_PROCEEDING");		case SIPS_SRV_NONINV_COMPLETED:			return ("SIPS_SRV_NONINV_COMPLETED");		case SIPS_SRV_NONINV_TERMINATED:			return ("SIPS_SRV_NONINV_TERMINATED");		default :			return ("unknown");	}}/* * Initialize the hash table etc. */voidsip_xaction_init(int (*ulp_trans_err)(sip_transaction_t, int, void *),    void (*ulp_state_cb)(sip_transaction_t, sip_msg_t, int, int)){	int	cnt;	for (cnt = 0; cnt < SIP_HASH_SZ; cnt++) {		sip_xaction_hash[cnt].hash_count = 0;		sip_xaction_hash[cnt].hash_head = NULL;		sip_xaction_hash[cnt].hash_tail = NULL;		(void) pthread_mutex_init(		    &sip_xaction_hash[cnt].sip_hash_mutex, NULL);	}	if (ulp_trans_err != NULL)		sip_xaction_ulp_trans_err = ulp_trans_err;	if (ulp_state_cb != NULL)		sip_xaction_ulp_state_cb = ulp_state_cb;}

⌨️ 快捷键说明

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