コード例 #1
0
ファイル: t_hooks.c プロジェクト: BackupTheBerlios/ser
void run_onsend_callbacks(int type, struct retr_buf* rbuf,
					struct sip_msg* req, struct sip_msg* repl, short flags)
{
	struct tmcb_params params;
	struct cell * trans;

	trans=rbuf->my_T;
	if ( trans==0 || trans->tmcb_hl.first==0 || 
			((trans->tmcb_hl.reg_types)&type)==0 )
		return;
	INIT_TMCB_ONSEND_PARAMS(params, req, repl, rbuf, &rbuf->dst, rbuf->buffer,
					rbuf->buffer_len, flags, rbuf->branch, rbuf->activ_type);
	/* req, rpl */
	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
}
コード例 #2
0
ファイル: uac.c プロジェクト: tsudot/kamailio
/**
 * @return: 
 * 	0: success
 * 	-1: internal error
 * 	-2: insane call :)
 */
int ack_local_uac(struct cell *trans, str *hdrs, str *body)
{
	struct retr_buf *local_ack, *old_lack;
	int ret;
	struct tmcb_params onsend_params;

	/* sanity checks */

#ifdef EXTRA_DEBUG
	if (! trans) {
		BUG("no transaction to ACK.\n");
		abort();
	}
#endif

#define RET_INVALID \
		ret = -2; \
		goto fin

	if (! is_local(trans)) {
		ERR("trying to ACK non local transaction (T@%p).\n", trans);
		RET_INVALID;
	}
	if (! is_invite(trans)) {
		ERR("trying to ACK non INVITE local transaction (T@%p).\n", trans);
		RET_INVALID;
	}
	if (! trans->uac[0].reply) {
		ERR("trying to ACK un-completed INVITE transaction (T@%p).\n", trans);
		RET_INVALID;
	}

	if (! (trans->flags & T_NO_AUTO_ACK)) {
		ERR("trying to ACK an auto-ACK transaction (T@%p).\n", trans);
		RET_INVALID;
	}
	if (trans->uac[0].local_ack) {
		ERR("trying to rebuild ACK retransmission buffer (T@%p).\n", trans);
		RET_INVALID;
	}

	/* looks sane: build the retransmission buffer */

	if (! (local_ack = local_ack_rb(trans->uac[0].reply, trans, /*branch*/0, 
			hdrs, body))) {
		ERR("failed to build ACK retransmission buffer");
		RET_INVALID;
	} else {
		/* set the new buffer, but only if not already set (conc. invok.) */
		if ((old_lack = (struct retr_buf *)atomic_cmpxchg_long(
				(void *)&trans->uac[0].local_ack, 0, (long)local_ack))) {
			/* buffer already set: deny current attempt */
			ERR("concurrent ACKing for local INVITE detected (T@%p).\n",trans);
			free_local_ack(local_ack);
			RET_INVALID;
		}
	}

	if (msg_send(&local_ack->dst, local_ack->buffer, local_ack->buffer_len)<0){
		/* hopefully will succeed on next 2xx retransmission */
		ERR("failed to send local ACK (T@%p).\n", trans);
		ret = -1;
		goto fin;
	}
	else {
		INIT_TMCB_ONSEND_PARAMS(onsend_params, 0, 0, &trans->uac[0].request,
								&local_ack->dst,
								local_ack->buffer, local_ack->buffer_len,
								TMCB_LOCAL_F, 0 /* branch */, TYPE_LOCAL_ACK);
		run_trans_callbacks_off_params(TMCB_REQUEST_SENT, trans, &onsend_params);
	}

	ret = 0;
fin:
	/* TODO: ugly! */
	/* FIXME: the T had been obtain by t_lookup_ident()'ing for it, so, it is
	 * ref-counted. The t_unref() can not be used, as it requests a valid SIP
	 * message (all available might be the reply, but if AS goes wrong and
	 * tries to ACK before the final reply is received, we still have to
	 * lookup the T to find this out). */
	UNREF( trans );
	return ret;

#undef RET_INVALID
}