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

📄 rvmegacotrans.c

📁 h.248协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		rvMutexUnlock(&tcbPtr->lock);
	rvLogLeave(&rvLog, "rvMegacoTransMgrRecvRequest");
}

void rvMegacoTransMgrRecvReply( RvMegacoEntity *remote, const RvMegacoTransactionReply *reply)
{	
	RvMegacoTcbPtr tcbPtr;
	RvHrtime roundTripTimeInNs;
	RvHrtime currTime;
	RvMegacoTransactionId tId = rvMegacoTransactionReplyGetId(reply);
	RvMegacoEntity*	localEntity;
	RvBool 	doUnlock = rvTrue;

	rvLogEnter(&rvLog, "rvMegacoTransMgrRecvReply");

	localEntity = rvMegacoEntityGetLocalEntity(remote);

	/* Find the TCB using the transaction Id */
	tcbPtr = rvMegacoEntityFindTcb(localEntity, tId); 
	if (tcbPtr != NULL)
		{
		rvMutexLock(&tcbPtr->lock);
		switch (tcbPtr->state)
			{	
			case RV_MEGACOTCB_STATE_CMD_TO_SEND:
				/* LLL If there was a way to remove the TCB from the send list */
				/* we would do that here */
				/* WARNING: FALLING THROUGH TO NEXT CASE !!! */
			case RV_MEGACOTCB_STATE_CMDSENT:
				currTime = rvTimeGetHrtime();
				roundTripTimeInNs = rvTimeHrSubtract(currTime,tcbPtr->OrigSendTime);
				rvMegacoEntityUpdateRoundTripTime(remote, roundTripTimeInNs);
				tcbPtr->replyReceived = rvTrue;
				rvMutexUnlock(&tcbPtr->lock);			/* Unlock before callback */

				if(tcbPtr->ReplyCallBack != NULL)
					tcbPtr->ReplyCallBack(tcbPtr,reply,tcbPtr->data,RVTRANSACTIONSTATUS_RCV_REPLY);

				rvMegacoEntityAddResponseAck(remote,tId);
				if (tcbPtr->state == RV_MEGACOTCB_STATE_CMDSENT)
					{
					rvMutexLock(&tcbPtr->lock);				/* Re-lock after callback and entity update*/
					tcbPtr->state = RV_MEGACOTCB_STATE_INACTIVE;
					rvMegacoTcbStopNStartTimer(tcbPtr, RV_MEGACOTM_SHORTINACTIVE_TO);
					}
				else
					doUnlock = rvFalse;
				break;
			case RV_MEGACOTCB_STATE_IDLE:
				break;
			case RV_MEGACOTCB_STATE_RESPONDED:
			case RV_MEGACOTCB_STATE_RESP_TO_SEND:
				break;
			case RV_MEGACOTCB_STATE_WAITAPPLRESPONSE:
				break;

			case RV_MEGACOTCB_STATE_INACTIVE:
				break;
			}
		if (doUnlock)
			rvMutexUnlock(&tcbPtr->lock);
		}
	rvLogLeave(&rvLog, "rvMegacoTransMgrRecvReply");
}

void rvMegacoTransMgrRecvPending(RvMegacoEntity *remote, RvMegacoTransactionId tId)
{
	RvMegacoTcbPtr tcbPtr;
	RvMegacoEntity* localEntity;

	rvLogEnter(&rvLog, "rvMegacoTransMgrRecvPending");

	localEntity = rvMegacoEntityGetLocalEntity(remote);

	/* Find the TCB using the transaction Id */
	tcbPtr = rvMegacoEntityFindTcb(localEntity, tId); 
	if (tcbPtr != NULL)
		{
		rvMutexLock(&tcbPtr->lock);
		switch (tcbPtr->state)
			{
			case RV_MEGACOTCB_STATE_CMDSENT:
				/* LLL update the timer based on receipt of this pending response msg */
				/* According to page 127 of the spec. "The root termination has a property */
				/* (ProvisionalResponseTimerValue) which can be set to the reauested maximum number of ms between receipt */
				/* of a command and transmission of the TransactionPending response. */
				rvMutexUnlock(&tcbPtr->lock);	/* Unlock before callback */

				if(tcbPtr->ReplyCallBack != NULL)
					tcbPtr->ReplyCallBack(tcbPtr,NULL,tcbPtr->data,RVTRANSACTIONSTATUS_RCV_PENDING_REPLY);

				rvMutexLock(&tcbPtr->lock);	/* Re-lock after callback */
				rvMegacoTcbStopNStartTimer(tcbPtr,(unsigned int)(rvMegacoEntityGetNextRetransTimeout(remote) / RV_TIME_NSECPERMSEC));
				break;
			case RV_MEGACOTCB_STATE_CMD_TO_SEND:
			case RV_MEGACOTCB_STATE_RESP_TO_SEND:
			case RV_MEGACOTCB_STATE_IDLE:
			case RV_MEGACOTCB_STATE_RESPONDED:
			case RV_MEGACOTCB_STATE_WAITAPPLRESPONSE:
			case RV_MEGACOTCB_STATE_INACTIVE:
				/* This message doesn't make sense in any of these states */
				break;
			}
		rvMutexUnlock(&tcbPtr->lock);
		}

	rvLogLeave(&rvLog, "rvMegacoTransMgrRecvPending");
}

void rvMegacoTransMgrRecvRespAck(RvMegacoEntity *remote, RvMegacoTransactionId tId)
{
	RvMegacoTcbPtr tcbPtr;
	RvBool alreadyUnlocked = rvFalse;

	rvLogEnter(&rvLog, "rvMegacoTransMgrRecvRespAck");

	/* Find the TCB using the transaction Id */
	tcbPtr = rvMegacoEntityFindTcb(remote, tId); 
	if (tcbPtr != NULL)
		{
		rvMutexLock(&tcbPtr->lock);
		switch (tcbPtr->state)
			{
			case RV_MEGACOTCB_STATE_RESPONDED:
				tcbPtr->msgFreed = rvTrue;
				rvStrStreamDestruct(&tcbPtr->encodedTransaction);
				tcbPtr->state = RV_MEGACOTCB_STATE_INACTIVE;
				rvMegacoTcbStopNStartTimer(tcbPtr, RV_MEGACOTM_INACTIVE_TO);
				rvMutexUnlock(&tcbPtr->lock);		/* Unlock before callback */
				alreadyUnlocked = rvTrue;
				if (tcbPtr->AckCallBack != NULL)
					tcbPtr->AckCallBack(tcbPtr,tcbPtr->data, RVTRANSACTIONSTATUS_RCV_REPLYACK);
				break;
			case RV_MEGACOTCB_STATE_IDLE:
			case RV_MEGACOTCB_STATE_WAITAPPLRESPONSE:
			case RV_MEGACOTCB_STATE_CMDSENT:
			case RV_MEGACOTCB_STATE_INACTIVE:
			case RV_MEGACOTCB_STATE_CMD_TO_SEND:
			case RV_MEGACOTCB_STATE_RESP_TO_SEND:
				break;
			}
		if (!alreadyUnlocked)
			rvMutexUnlock(&tcbPtr->lock);
		}

	rvLogLeave(&rvLog, "rvMegacoTransMgrRecvRespAck");
}
/*$
{function:
	{name: rvMegacoEntitySendRequest}
	{class: RvMegacoEntity}
	{include: rvmegacoentity.h}
	{description:
		{p: Queues a request transaction to be sent to a particular entity.}
	}
	{proto: void rvMegacoEntitySendRequest(RvMegacoEntity *remote, RvMegacoTransaction *t, RvMegacoReplyCb f, void *data);}
	{params:
		{param: {n:remote} {d:The entity to send the request to.}}
		{param: {n:t} {d:The request transaction to be sent.}}
		{param: {n:f} {d:The callback to be invoked for this request.}}
		{param: {n:data} {d:The data to be passed to the callback.}}
	}
}
$*/
void rvMegacoEntitySendRequest(RvMegacoEntity *remote, RvMegacoTransaction *t, RvMegacoReplyCb f, void *data)
{	
	RvMegacoStack *stack = remote->stack;
	RvMegacoEntity *localEntity;
	RvMegacoTcbPtr tcbPtr;
	RvMegacoTransactionId tId;

	rvLogEnter(&rvLog, "rvMegacoEntitySendRequest");

	localEntity = rvMegacoEntityGetLocalEntity(remote);
	tId = rvMegacoEntityGetNextTransactionId(localEntity);
	rvMegacoTransactionSetId(t, tId);

	/* allocate a tcb */
	tcbPtr = (RvMegacoTcb *)rvAllocAllocate(stack->tcbAlloc, sizeof(RvMegacoTcb));
	rvMegacoTcbConstruct(tcbPtr, stack, localEntity, remote, rvTrue, t);
	rvMegacoEntityAddTcb(localEntity, tcbPtr);

	rvMutexLock(&remote->mutex);		/* Always lock entity first */
	rvMutexLock(&tcbPtr->lock);

	rvMegacoTransactionEncode(t, &tcbPtr->encodedTransaction, stack->encodeCompact);

	tcbPtr->ReplyCallBack = f;
	tcbPtr->data = data;
	tcbPtr->state = RV_MEGACOTCB_STATE_CMD_TO_SEND;
	
	/* put it in the entity's send list */
	rvMegacoEntitySendListInsert(remote, tcbPtr);
	
	rvMutexUnlock(&tcbPtr->lock);
	rvMutexUnlock(&remote->mutex);

	rvLogLeave(&rvLog, "rvMegacoEntitySendRequest");
}
/*$
{function:
	{name: rvMegacoTcbSendReply}
	{class: RvMegacoTcb}
	{include: rvmegacotrans.h}
	{description:
		{p: Queues a reply transaction to be sent.}
	}
	{proto: void rvMegacoTcbSendReply(RvMegacoTcb *tcbPtr,
		const RvMegacoTransactionReply *t, RvMegacoAckCB f, void *data);}
	{params:
		{param: {n:tcbPtr} {d:The transaction control block for this transaction.}}
		{param: {n:t} {d:The reply transaction to be sent.}}
		{param: {n:f} {d:The callback to be invoked for this reply.}}
		{param: {n:data} {d:The data to be passed to the callback.}}
	}
}
$*/

void rvMegacoTcbSendReply(RvMegacoTcb *tcbPtr, const RvMegacoTransactionReply *t, RvMegacoAckCB f, void *data)
{
	RvMegacoEntity *destEntity;

	rvLogEnter(&rvLog, "rvMegacoTcbSendReply");

	/* Get the entity */
	destEntity = rvMegacoTcbGetRemoteEntity(tcbPtr);

	/* Must Lock the entity first */	
	rvMutexLock(&destEntity->mutex);
	rvMutexLock(&tcbPtr->lock);

	if (tcbPtr->state == RV_MEGACOTCB_STATE_RESP_TO_SEND)
		/* Trigger the enitity to do a send */
		rvMegacoEntitySendNow(tcbPtr->destEntity);

	while (tcbPtr->state == RV_MEGACOTCB_STATE_RESP_TO_SEND)
		rvThreadSleep(100);
	if (tcbPtr->state == RV_MEGACOTCB_STATE_RESPONDED)
		{
		/* Need to rewind the string stream to clear out the existing transaction */
		rvStrStreamSeekPos(&tcbPtr->encodedTransaction,0);
		}
	rvMegacoTransactionReplyEncode(t, &tcbPtr->encodedTransaction, tcbPtr->localEntity->stack->encodeCompact);
	tcbPtr->AckCallBack = f;
	tcbPtr->data = data;
	tcbPtr->state = RV_MEGACOTCB_STATE_RESP_TO_SEND;

	rvMegacoEntitySendListInsert(tcbPtr->destEntity, tcbPtr);

	rvMutexUnlock(&tcbPtr->lock);
	rvMutexUnlock(&destEntity->mutex);

	rvLogLeave(&rvLog, "rvMegacoTcbSendReply");
}
/*$
{function:
	{name: rvMegacoTcbSendPending}
	{class: RvMegacoTcb}
	{include: rvmegacotrans.h}
	{description:
		{p: Queues a pending message to be sent.}
	}
	{proto: void rvMegacoTcbSendPending(RvMegacoTcb *tcbPtr, RvMegacoAckCB f, void *data);}
	{params:
		{param: {n:tcbPtr} {d:The transaction control block for this transaction.}}
		{param: {n:f} {d:The callback to be invoked for this pending reply.}}
		{param: {n:data} {d:The data to be passed to the callback.}}
	}
}
$*/
void rvMegacoTcbSendPending(RvMegacoTcb *tcbPtr, RvMegacoAckCB f, void *data)
{
	RvMegacoEntity *destEntity;

	rvLogEnter(&rvLog, "rvMegacoTcbSendPending");

	/* Get the entity */
	destEntity = rvMegacoTcbGetRemoteEntity(tcbPtr);

	/* Must Lock the entity first */	
	rvMutexLock(&destEntity->mutex);
	rvMutexLock(&tcbPtr->lock);

	rvStrStreamSeekPos(&tcbPtr->encodedTransaction,0);
	rvMegacoTransactionPendingEncode(tcbPtr->tId, &tcbPtr->encodedTransaction, tcbPtr->localEntity->stack->encodeCompact);
	if (tcbPtr->SentPending == rvTrue)
		{
		rvMutexUnlock(&tcbPtr->lock);
		rvMutexUnlock(&destEntity->mutex);
		return;
		}
	tcbPtr->AckCallBack = f;
	tcbPtr->data = data;
	tcbPtr->SentPending = rvTrue;

	rvMegacoEntitySendListInsert(tcbPtr->destEntity, tcbPtr);

	rvMutexUnlock(&tcbPtr->lock);
	rvMutexUnlock(&destEntity->mutex);

	rvLogLeave(&rvLog, "rvMegacoTcbSendPending");
}

void rvMegacoTcbUpdateOnSend (RvMegacoTcbPtr tcbPtr)
{

		rvMutexLock(&tcbPtr->lock);
		switch(tcbPtr->state)
		{
			case RV_MEGACOTCB_STATE_CMD_TO_SEND:
				if (tcbPtr->replyReceived)
					{
					tcbPtr->state = RV_MEGACOTCB_STATE_INACTIVE;
					rvMegacoTcbStopNStartTimer(tcbPtr, RV_MEGACOTM_SHORTINACTIVE_TO);
					}
				else
					{
					if (tcbPtr->firstSend == rvTrue)
						rvMegacoTcbStopNStartTimer(tcbPtr,(unsigned int) (rvMegacoEntityGetFirstRetransTimeout(tcbPtr->destEntity) / RV_TIME_NSECPERMSEC));
					else
						rvMegacoTcbStopNStartTimer(tcbPtr, (unsigned int)(rvMegacoEntityGetNextRetransTimeout(tcbPtr->destEntity) / RV_TIME_NSECPERMSEC));
					tcbPtr->state = RV_MEGACOTCB_STATE_CMDSENT;
					}
				break;
			case RV_MEGACOTCB_STATE_RESP_TO_SEND:
				rvMegacoTcbStopNStartTimer(tcbPtr, RV_MEGACOTM_RESPONDED_TO);
				tcbPtr->state = RV_MEGACOTCB_STATE_RESPONDED;
				break;
			case RV_MEGACOTCB_STATE_WAITAPPLRESPONSE:
				tcbPtr->SentPending = rvFalse;
				break;
			case RV_MEGACOTCB_STATE_INACTIVE:
				tcbPtr->firstSend = rvFalse;
				break;
		}
		if (tcbPtr->firstSend == rvTrue)
			tcbPtr->OrigSendTime = rvTimeGetHrtime();
		rvMutexUnlock(&tcbPtr->lock);
}

void rvMegacoTcbUpdateFailedSend (RvMegacoTcbPtr tcbPtr)
{

		rvMutexLock(&tcbPtr->lock);
		switch(tcbPtr->state)
		{
			case RV_MEGACOTCB_STATE_CMD_TO_SEND:
				tcbPtr->state = RV_MEGACOTCB_STATE_CMD_SEND_FAIL;
				break;
			case RV_MEGACOTCB_STATE_RESP_TO_SEND:

				tcbPtr->state = RV_MEGACOTCB_STATE_RESP_SEND_FAIL;
				break;
		}
		rvMegacoTcbStopNStartTimer(tcbPtr, 1);
		rvMutexUnlock(&tcbPtr->lock);

}

⌨️ 快捷键说明

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