transacmng.c
来自「mgcp协议源代码和测试程序,还有一个编译器」· C语言 代码 · 共 1,780 行 · 第 1/5 页
C
1,780 行
void ProcessTransacIncomingMgcpRsp(H_MGCP_TRANSAC_MANAGER pTransacMng,
MGCP_INCOMING_RESPONSE *pMgcpRsp)
{
MGCP_STACK_MSG Msg;
TRANSAC_CMD_OUT *pTranCmdOut = NULL;
MGCP_RSP_IN *pRspIn = NULL;
BOOL bRspNeedProcess = FALSE;
Assert(pTransacMng);
Assert(pMgcpRsp);
/* Check if the incoming response is a response ack */
if (pMgcpRsp->wRspCode <= RSP_ACK_MAX)
{
/* Find the response wait this ack */
if (SListFind(&pTransacMng->MsgList.RspSentWaitAckList,
&pMgcpRsp->dwTransacId,
FindMgcpRspOutWaitAckByTranID) != NULL)
{
TRANSAC_RSP_WAIT_ACK *pRspOutWaitAck
= SListGetCurData(&pTransacMng->MsgList.RspSentWaitAckList);
Assert(pRspOutWaitAck);
/* Free the response data */
ClearMgcpRspOut(pRspOutWaitAck->pRspOut);
free(pRspOutWaitAck->pRspOut);
pRspOutWaitAck->pRspOut = NULL;
/* Move this response wait ack into the response acked list */
SListDelCurNode(&pTransacMng->MsgList.RspSentWaitAckList);
SListAppend(&pTransacMng->MsgList.RspAckReceivedList, pRspOutWaitAck);
}
return;
}
/* Check if the incoming response has been acked */
if (SListFind(&pTransacMng->MsgList.AckRspSentList, &pMgcpRsp->dwTransacId,
FindMgcpRspAckOutByTranID) != NULL)
{
/* Check if this response still need ack */
if (pTransacMng->bUseProvisionalRspProcedure
&& pMgcpRsp->ParamLineList.pResponseAck != NULL
&& pMgcpRsp->ParamLineList.pResponseAck->wNum == 0)
{
/* Re-send the response ack */
SendMgcpRspAckOut(pTransacMng, pMgcpRsp->dwTransacId);
}
return;
}
/* Find the associate command of this incoming response, firstly search in
the command out list */
if (SListFind(&pTransacMng->MsgList.CmdSentList, &pMgcpRsp->dwTransacId,
FindMgcpCmdOutByTranID) != NULL)
{
pTranCmdOut = SListGetCurData(&pTransacMng->MsgList.CmdSentList);
Assert(pTranCmdOut);
/* Check if the incoming response is a provisional response*/
if (pMgcpRsp->wRspCode >= RSP_PROVISIONAL_MIN
&& pMgcpRsp->wRspCode <= RSP_PROVISIONAL_MAX)
{
/* Stretch the RTO to be the LONGTRAN-TIMER */
pTranCmdOut->dwRTO = pTransacMng->dwTimerLongTR;
}
else
{
/* Remove the command from the command out list */
SListDelCurNode(&pTransacMng->MsgList.CmdSentList);
bRspNeedProcess = TRUE;
}
}
/* Command not found in CmdSent list, search the CmdSentPiggybackList */
else if (SListFind(&pTransacMng->MsgList.CmdSentPiggybackList,
&pMgcpRsp->dwTransacId,
FindMgcpCmdOutByTranID) != NULL)
{
pTranCmdOut = SListGetCurData(&pTransacMng->MsgList.CmdSentPiggybackList);
Assert(pTranCmdOut);
/* Check if the incoming response is a provisional response*/
if (pMgcpRsp->wRspCode >= RSP_PROVISIONAL_MIN
&& pMgcpRsp->wRspCode <= RSP_PROVISIONAL_MAX)
{
/* Stretch the RTO to be the LONGTRAN-TIMER */
pTranCmdOut->dwRTO = pTransacMng->dwTimerLongTR;
}
else
{
/* Remove the command from the piggybacking command out list */
SListDelCurNode(&pTransacMng->MsgList.CmdSentPiggybackList);
bRspNeedProcess = TRUE;
}
}
/* Command associated this response found and need further process ? */
if (bRspNeedProcess && pTranCmdOut != NULL)
{
/* Firstly check if this response need ack, if yes, send Ack response */
if (pTransacMng->bUseProvisionalRspProcedure
&& pMgcpRsp->ParamLineList.pResponseAck != NULL
&& pMgcpRsp->ParamLineList.pResponseAck->wNum == 0)
{
TRANSAC_RSPACK_OUT *pRspAck
= (TRANSAC_RSPACK_OUT*)calloc(1, sizeof(TRANSAC_RSPACK_OUT));
Assert(pRspAck);
// memset(pRspAck, 0, sizeof(TRANSAC_RSPACK_OUT));
pRspAck->dwTransacId = pMgcpRsp->dwTransacId;
Assert(pRspAck->dwTransacId == pTranCmdOut->dwTransacId);
/* Add the Transaction response ack into RSP ACK list */
SListAppend(&pTransacMng->MsgList.AckRspSentList, pRspAck);
/* Send out response ack */
SendMgcpRspAckOut(pTransacMng, pMgcpRsp->dwTransacId);
}
/* Check if the piggybacking commands/responses piggybacked the command
associated to this incoming response, if yes, remove the command ID
from the piggybacking CmdID table */
RemovePiggyBackingCmdID(pTranCmdOut->pCmdOut->dwCmdId,
&pTransacMng->MsgList);
/* Create the mgcp response message */
pRspIn = (MGCP_RSP_IN*)calloc(1, sizeof(MGCP_RSP_IN));
Assert(pRspIn);
// memset(pRspIn, 0, sizeof(MGCP_RSP_IN));
pRspIn->wRspCode = pMgcpRsp->wRspCode;
pRspIn->dwCmdId = pTranCmdOut->pCmdOut->dwCmdId;
pRspIn->hEndpointHandle = pTranCmdOut->pCmdOut->hEndpointHandle;
Assert(pRspIn->hEndpointHandle);
/* Recompute deviation of Round Trip delay (RTT). NOTE: This is only done
if the response is not to a retransmission to avoid
"Retransmission ambiguity problem" mentioned in (TCP/IP standard) */
if (pTranCmdOut->wRetranCounter == 0)
pRspIn->dwRTTDelay = pTranCmdOut->dwTimeDuration;
/* Fill response message data */
switch(pTranCmdOut->pCmdOut->eType)
{
case MGCP_CMD_RSIP:
pRspIn->eType = MGCP_RSP_RSIP;
pRspIn->u.pRsipRsp = (MGCP_RSIP_RSP*)calloc(1, sizeof(MGCP_RSIP_RSP));
Assert(pRspIn->u.pRsipRsp);
// memset(pRspIn->u.pRsipRsp, 0, sizeof(MGCP_RSIP_RSP));
if (pMgcpRsp->ParamLineList.pNotifiedEntity != NULL)
{
pRspIn->u.pRsipRsp->pNotifiedEntity = pMgcpRsp->ParamLineList.pNotifiedEntity;
pMgcpRsp->ParamLineList.pNotifiedEntity = NULL;
}
CopyExperimentalParameters(&pRspIn->u.pRsipRsp->ExperiParamList,
&pMgcpRsp->ParamLineList.ExperiParamList);
break;
case MGCP_CMD_NTFY:
pRspIn->eType = MGCP_RSP_NTFY;
pRspIn->u.pNtfyRsp = (MGCP_NTFY_RSP*)calloc(1, sizeof(MGCP_NTFY_RSP));
Assert(pRspIn->u.pNtfyRsp);
// memset(pRspIn->u.pNtfyRsp, 0, sizeof(MGCP_NTFY_RSP));
CopyExperimentalParameters(&pRspIn->u.pNtfyRsp->ExperiParamList,
&pMgcpRsp->ParamLineList.ExperiParamList);
break;
case MGCP_CMD_DLCX:
pRspIn->eType = MGCP_RSP_DLCX;
pRspIn->u.pDlcxRsp = (MGCP_DLCX_RSP*)calloc(1, sizeof(MGCP_DLCX_RSP));
Assert(pRspIn->u.pDlcxRsp);
// memset(pRspIn->u.pDlcxRsp, 0, sizeof(MGCP_DLCX_RSP));
CopyExperimentalParameters(&pRspIn->u.pDlcxRsp->ExperiParamList,
&pMgcpRsp->ParamLineList.ExperiParamList);
break;
default:
Assert(0);
DEBUG(LogMSG(LOG_ERROR, "\nUnSupported Incoming response for MG!"););
return;
}
/* Construct a message and send to EndpointCtrl */
memset(&Msg, 0, sizeof(MGCP_STACK_MSG));
Msg.eMsgCode = M_INCOMING_RSP;
Msg.pMsgData = pRspIn;
SendMsgToEndpointCtrl((H_MGCP_ENDPOINT_CONTROL)
pTransacMng->pStack->pEndpointCtl, &Msg);
/* Clear this responsed MGCP command */
ClearTranCmdOut(pTranCmdOut);
free(pTranCmdOut);
}
}
/******************************************************************************
* Function : ProcessOutGoingMgcpCmd
*
* Description : Process the Mgcp outgoing command requested by
* EndpointCtrl; construct a transaction outgoing command
* and send out.
*
* Input parameters : pTransacMng - TransactionManager handle
* pCmdOut - Pointer to outgoing Mgcp command sent by
* EndpointCtrl
*
* Output parameters :
*
* Return value : None
*
* Comments :
*
* History :
* 2005/09/05 : Creation
*
* Date : Sep 05 2005, Frank Zhang
******************************************************************************/
void ProcessOutGoingMgcpCmd(H_MGCP_TRANSAC_MANAGER pTransacMng, MGCP_CMD_OUT *pCmdOut)
{
TRANSAC_CMD_OUT *pTranCmdOut = NULL;
Assert(pTransacMng);
Assert(pCmdOut);
pTranCmdOut = (TRANSAC_CMD_OUT*)calloc(1, sizeof(TRANSAC_CMD_OUT));
Assert(pTranCmdOut);
// memset(pTranCmdOut, 0, sizeof(TRANSAC_CMD_OUT));
/* Transaction ID of the outgoing command */
pTranCmdOut->dwTransacId = GetNewTransacID(pTransacMng);
/* RTO value of the outgoing command */
pTranCmdOut->dwRTO = pCmdOut->dwInitRTO;
/* Command data */
pTranCmdOut->pCmdOut = pCmdOut;
/* Add this outgoing command into cmd send list */
if (pCmdOut->wPiggyCmdNum > 0)
SListAppend(&pTransacMng->MsgList.CmdSentPiggybackList, pTranCmdOut);
else
SListAppend(&pTransacMng->MsgList.CmdSentList, pTranCmdOut);
/* Send the command out */
SendMgcpCmdOut(pTransacMng, pTranCmdOut);
}
/******************************************************************************
* Function : ProcessOutGoingMgcpRsp
*
* Description : Process the Mgcp outgoing response requested by
* EndpointCtrl; if find the incoming command associated with
* this response, construct a transaction outgoing response
* and send out.
*
* Input parameters : pTransacMng - TransactionManager handle
* pRspOut - Pointer to outgoing Mgcp response sent by
* EndpointCtrl
*
* Output parameters :
*
* Return value : None
*
* Comments :
*
* History :
* 2005/09/07 : Creation
*
* Date : Sep 07 2005, Frank Zhang
******************************************************************************/
void ProcessOutGoingMgcpRsp(H_MGCP_TRANSAC_MANAGER pTransacMng, MGCP_RSP_OUT *pRspOut)
{
TRANSAC_CMD_IN *pTranCmdIn = NULL;
Assert(pTransacMng);
Assert(pRspOut);
/* Find the incoming transaction command associated with this response */
if (SListFind(&pTransacMng->MsgList.CmdInProcessList,
&pRspOut->dwTransacId, FindMgcpCmdInByTranID) != NULL)
{
pTranCmdIn = SListGetCurData(&pTransacMng->MsgList.CmdInProcessList);
Assert(pTranCmdIn);
/* Check if the outgoing rsp need ack */
if (pTranCmdIn->bProvisionalRspOut && pTransacMng->bUseProvisionalRspProcedure)
{
/* Provisional response to this incoming command has been sent out, so
this response need ack */
TRANSAC_RSP_WAIT_ACK *pTranPiggyRspOut
= (TRANSAC_RSP_WAIT_ACK*)calloc(1, sizeof(TRANSAC_RSP_WAIT_ACK));
Assert(pTranPiggyRspOut);
// memset(pTranPiggyRspOut, 0, sizeof(TRANSAC_RSP_WAIT_ACK));
/* Calculate RTO */
pTranPiggyRspOut->dwRTO = RTO_DEFAULT;
/* Response data */
pTranPiggyRspOut->pRspOut = pRspOut;
/* Add this outgoing response into RspSendWaitAck list */
if (pRspOut->wPiggyCmdNum > 0)
SListAppend(&pTransacMng->MsgList.RspSentPiggyWaitAckList, pTranPiggyRspOut);
else
SListAppend(&pTransacMng->MsgList.RspSentWaitAckList, pTranPiggyRspOut);
/* Send the response out */
SendMgcpRspOut(pTransacMng, pRspOut, TRUE);
}
else
{
TRANSAC_RSP_OUT *pTranRspOut
= (TRANSAC_RSP_OUT*)calloc(1, sizeof(TRANSAC_RSP_OUT));
Assert(pTranRspOut);
// memset(pTranRspOut, 0, sizeof(TRANSAC_RSP_OUT));
/* Response data */
pTranRspOut->pRspOut = pRspOut;
/* Add this outgoing response into Rspsend list */
if (pRspOut->wPiggyCmdNum > 0)
SListAppend(&pTransacMng->MsgList.RspSentPiggybackList, pTranRspOut);
else
SListAppend(&pTransacMng->MsgList.RspSentList, pTranRspOut);
}
/* Free the memory allocated for the incoming transaction command */
free(pTranCmdIn);
/* Remove the incoming transaction command from the command list*/
SListDelCurNode(&pTransacMng->MsgList.CmdInProcessList);
/* Check if the command list is bellow the low water mark */
if (pTransacMng->MsgList.CmdInProcessList.count <= pTransacMng->MsgList.wLowWaterMark)
pTransacMng->MsgList.bQueueIsFull = FALSE;
/* Send the response out */
SendMgcpRspOut(pTransacMng, pRspOut, FALSE);
}
else
{
Assert(0);
DEBUG(LogMSG(LOG_ERROR, "\nCannot find the outgoing response's associate command!"););
}
}
/******************************************************************************
* Function : ProcessUpdataNotifiedEntityMsg
*
* Description : Process the NotifiedEntity updata message requested by
* EndpointCtrl; According to RFC3435, if NE is update, all
* the outgoing commands need retransmission.
*
* Input parameters : pTransacMng - TransactionManager handle
* pRspOut - Pointer to M_UPDATE_NE message data sent by
* EndpointCtrl.
*
* Output parameters :
*
* Return value : None
*
* Comments :
*
* History :
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?