transacmng.c
来自「mgcp协议源代码和测试程序,还有一个编译器」· C语言 代码 · 共 1,780 行 · 第 1/5 页
C
1,780 行
/* If piggybacked command number is 0, move this transaction command into
none piggybacking command list */
if (pCmdPiggy->pCmdOut->wPiggyCmdNum == 0)
{
SListAppend(&pMsgList->CmdSentList, pCmdPiggy);
SListDelCurNode(&pMsgList->CmdSentPiggybackList);
}
else
SListNextNode(&pMsgList->CmdSentPiggybackList);
}
SListReset(&pMsgList->RspSentPiggybackList);
while((pRspPiggy = SListGetCurData(&pMsgList->RspSentPiggybackList))!= NULL)
{
Assert(pRspPiggy->pRspOut->wPiggyCmdNum > 0);
for (i = 0; i < pRspPiggy->pRspOut->wPiggyCmdNum; i++)
{
if (pRspPiggy->pRspOut->PiggybackCmdIDTable[i] == dwCommandID)
{
WORD j;
/* Advance the following command IDs after the found Command ID */
for (j = i+1; j < pRspPiggy->pRspOut->wPiggyCmdNum; j++)
{
pRspPiggy->pRspOut->PiggybackCmdIDTable[i] =
pRspPiggy->pRspOut->PiggybackCmdIDTable[j];
}
pRspPiggy->pRspOut->wPiggyCmdNum--;
break;
}
}
/* If piggybacked command number is 0, move this transaction response into
none piggybacking response list */
if (pRspPiggy->pRspOut->wPiggyCmdNum == 0)
{
SListAppend(&pMsgList->RspSentList, pRspPiggy);
SListDelCurNode(&pMsgList->RspSentPiggybackList);
}
else
SListNextNode(&pMsgList->RspSentPiggybackList);
}
SListReset(&pMsgList->RspSentPiggyWaitAckList);
while((pRspPiggyWaitAck = SListGetCurData(&pMsgList->RspSentPiggyWaitAckList))!= NULL)
{
Assert(pRspPiggyWaitAck->pRspOut->wPiggyCmdNum > 0);
for (i = 0; i < pRspPiggyWaitAck->pRspOut->wPiggyCmdNum; i++)
{
if (pRspPiggyWaitAck->pRspOut->PiggybackCmdIDTable[i] == dwCommandID)
{
WORD j;
/* Advance the following command IDs after the found Command ID */
for (j = i+1; j < pRspPiggy->pRspOut->wPiggyCmdNum; j++)
{
pRspPiggyWaitAck->pRspOut->PiggybackCmdIDTable[i] =
pRspPiggyWaitAck->pRspOut->PiggybackCmdIDTable[j];
}
pRspPiggyWaitAck->pRspOut->wPiggyCmdNum--;
break;
}
}
/* If piggybacked response waiting ack number is 0, move this transaction
response into none piggybacking response waiting ack list */
if (pRspPiggyWaitAck->pRspOut->wPiggyCmdNum == 0)
{
SListAppend(&pMsgList->RspSentWaitAckList, pRspPiggyWaitAck);
SListDelCurNode(&pMsgList->RspSentPiggyWaitAckList);
}
else
SListNextNode(&pMsgList->RspSentPiggyWaitAckList);
}
}
/******************************************************************************
* Function : SendProvisonalResponse
*
* Description : Construct a Mgcp provisonal response and send out
*
* Input parameters : dwTransactionId - Transaction ID of the response
* dwRspCode - Response code of the response
* iSocket_fd - Socket to send this response
* dwDesAddress - Destination IP address of the response
* wDesPort - Destination port of the response
*
* Output parameters :
*
* Return value : None
*
* Comments :
*
* History :
* 2005/09/03 : Creation
*
* Date : Sep 03 2005, Frank Zhang
******************************************************************************/
void SendProvisonalResponse(DWORD dwTransactionId, DWORD dwRspCode,
int iSocket_fd, DWORD dwDesAddress,
WORD wDesPort)
{
TMGCPMsgList AbnfMsgList;
TMGCPResponse *pRsp = NULL;
TCtx ctx;
char EnBuffer[ABNF_ENCODE_BUF_LEN];
char *pcRspString;
struct sockaddr_in DesAddress;
socklen_t SocketLen = sizeof(struct sockaddr);
memset(&AbnfMsgList, 0, sizeof(TMGCPMsgList));
memset(EnBuffer, 0, sizeof(EnBuffer));
CtxInitial(&ctx, EnBuffer, ABNF_ENCODE_BUF_LEN);
AbnfMsgList.MGCPMessage.iNum = 1;
AbnfMsgList.MGCPMessage.pNode = calloc(1, sizeof(TMGCPMessage));
Assert(AbnfMsgList.MGCPMessage.pNode);
// memset(AbnfMsgList.MGCPMessage.pNode, 0, sizeof(TMGCPMessage));
((TMGCPMessage*)AbnfMsgList.MGCPMessage.pNode)->iType = MGCPMessage_MGCPResponse;
pRsp = &((TMGCPMessage*)AbnfMsgList.MGCPMessage.pNode)->u.MGCPResponse;
/* Response code */
StrClone(&pRsp->MGCPResponseLine.responseCode, Ultoa(dwRspCode));
/* Transaction ID */
StrClone(&pRsp->MGCPResponseLine.transaction_id, Ultoa(dwTransactionId));
/* Response string */
if ((pcRspString = FindRspStringByCode(dwRspCode)) != NULL)
{
pRsp->MGCPResponseLine.responseString.flag = 1;
StrClone((char**)&pRsp->MGCPResponseLine.responseString.pRuleData,
pcRspString);
}
if (EN_MGCPMsgList(&ctx, &AbnfMsgList) == OK)
{
DesAddress.sin_family = AF_INET;
DesAddress.sin_port = htons(wDesPort);
DesAddress.sin_addr.s_addr = htonl(dwDesAddress);
sendto(iSocket_fd, ctx.pHead, ctx.pCur-ctx.pHead, 0,
(struct sockaddr*)&DesAddress, SocketLen);
}
/* Free the AbnfMessages */
Free_MGCPMsgList(&AbnfMsgList);
}
/******************************************************************************
* Function : ProcessTransacIncomingMgcpCmd
*
* Description : Process the transaction incoming mgcp command, if the
* command is a old, resend the response or ignor it; if it
* is a new one, add it into incoming command list and send
* it to EndpointCtrl for further process
*
* Input parameters : H_MGCP_TRANSAC_MANAGER - TransactionManager handle
* pMgcpCmd - pointer to Mgcp incoming command to be processed
*
* Output parameters :
*
* Return value : None
*
* Comments :
*
* History :
* 2005/09/03 : Creation
*
* Date : Sep 03 2005, Frank Zhang
******************************************************************************/
void ProcessTransacIncomingMgcpCmd(H_MGCP_TRANSAC_MANAGER pTransacMng,
MGCP_INCOMING_COMMAND *pMgcpCmd)
{
TRANSAC_CMD_IN *pTransCmd;
TRANSAC_RSP_OUT *pTransRsp;
TRANSAC_RSP_WAIT_ACK *pTransRspWaitAck;
Assert(pTransacMng);
Assert(pMgcpCmd);
/* Check command type validity */
if (pMgcpCmd->eType == MGCP_CMD_RSIP || pMgcpCmd->eType == MGCP_CMD_NTFY)
{
DEBUG(LogMSG(LOG_ERROR, "\nUnsupported incoming cmd for MG, it is outgoing cmd!");)
return;
}
/* Search the CmdInProcess queue to check if this command is being processed */
if (SListFind(&pTransacMng->MsgList.CmdInProcessList,
&pMgcpCmd->dwTransacId, FindMgcpCmdInByTranID) != NULL)
{
DWORD dwRspCode = pTransacMng->MsgList.bQueueIsFull ?
RSP_TRANSACTION_QUEUED : RSP_TRANSACTION_IN_PROGRESS;
/* Send provisional response */
if (pTransacMng->MsgList.bQueueIsFull)
{
SendProvisonalResponse(pMgcpCmd->dwTransacId, dwRspCode,
pTransacMng->iSocket_fd, pMgcpCmd->dwSrcIpAddr,
pMgcpCmd->wSrcPort);
}
/* Set the provisional response sent flag of this command */
pTransCmd = SListGetCurData(&pTransacMng->MsgList.CmdInProcessList);
Assert(pTransCmd);
pTransCmd->bProvisionalRspOut = TRUE;
}
/* Check if the command has been responsed */
else if (SListFind(&pTransacMng->MsgList.RspSentList,
&pMgcpCmd->dwTransacId, FindMgcpRspOutByTranID) != NULL)
{
/* Re-Send the response */
pTransRsp = SListGetCurData(&pTransacMng->MsgList.RspSentList);
Assert(pTransRsp);
SendMgcpRspOut(pTransacMng, pTransRsp->pRspOut, FALSE); // 该反馈不需要确认
}
// 检查命令是否已经被响应, 响应消息是以附带在命令上的方式发送给对方的
/* Check if the command has been responsed with piggybacking commands */ // piggyback : 附带
else if (SListFind(&pTransacMng->MsgList.RspSentPiggybackList,
&pMgcpCmd->dwTransacId, FindMgcpRspOutByTranID) != NULL)
{
/* Re-Send the response */
pTransRsp = SListGetCurData(&pTransacMng->MsgList.RspSentPiggybackList);
Assert(pTransRsp);
SendMgcpRspOut(pTransacMng, pTransRsp->pRspOut, FALSE); // 该反馈不需要确认
}
/* Check if the command has been responsed and waiting ack */
else if (SListFind(&pTransacMng->MsgList.RspSentWaitAckList,
&pMgcpCmd->dwTransacId, FindMgcpRspOutWaitAckByTranID) != NULL)
{
/* Re-Send the response waiting ack */
pTransRspWaitAck = SListGetCurData(&pTransacMng->MsgList.RspSentWaitAckList);
Assert(pTransRspWaitAck);
SendMgcpRspOut(pTransacMng, pTransRspWaitAck->pRspOut, TRUE); // 该反馈需要确认
}
/* Check if the command has been responsed with piggybacking commands
and waiting ack */
else if (SListFind(&pTransacMng->MsgList.RspSentPiggyWaitAckList,
&pMgcpCmd->dwTransacId, FindMgcpRspOutWaitAckByTranID) != NULL)
{
/* Re-Send the piggybacking response waiting ack */
pTransRspWaitAck = SListGetCurData(&pTransacMng->MsgList.RspSentPiggyWaitAckList);
Assert(pTransRspWaitAck);
SendMgcpRspOut(pTransacMng, pTransRspWaitAck->pRspOut, TRUE); // 该反馈需要确认
}
/* Check if the command has been responsed and response has been acked */
else if (SListFind(&pTransacMng->MsgList.RspAckReceivedList,
&pMgcpCmd->dwTransacId, FindMgcpRspACKByTranID) != NULL)
{
/* Response ack has been received, need no process */
}
else /* New incoming command */
{
MGCP_STACK_MSG Msg;
MGCP_CMD_IN *pNewMgcpCmd = NULL;
if (pMgcpCmd->eType == MGCP_CMD_EXPR &&
(StrCaseCmp(pMgcpCmd->u.pExprCmd->pcCmdName, "Auth") == 0))
{
MGCP_RSP_OUT MgcpRspOut;
memset(&MgcpRspOut, 0, sizeof(MGCP_RSP_OUT));
MgcpRspOut.wRspCode = 200;
MgcpRspOut.pcRspString = "Frank ZHANG@2006";
MgcpRspOut.dwTransacId = pMgcpCmd->dwTransacId;
MgcpRspOut.dwDesIpAddr = pMgcpCmd->dwSrcIpAddr;
MgcpRspOut.wDesPort = pMgcpCmd->wSrcPort;
SendMgcpRspOut(pTransacMng, &MgcpRspOut, FALSE); // 该反馈不需要确认
return;
}
pNewMgcpCmd = (MGCP_CMD_IN*)calloc(1, sizeof(MGCP_CMD_IN));
Assert(pNewMgcpCmd);
/* Create a new transaction command */
pTransCmd = (TRANSAC_CMD_IN*)calloc(1, sizeof(TRANSAC_CMD_IN));
Assert(pTransCmd);
pTransCmd->dwTransacId = pMgcpCmd->dwTransacId;
pTransCmd->bProvisionalRspOut = FALSE;
/* Add this new command into incoming command queue */
SListAppend(&pTransacMng->MsgList.CmdInProcessList, pTransCmd);
/* If the incoming command queue length reach the high water mark, send
provisional response out */
if (pTransacMng->MsgList.bQueueIsFull ||
(pTransacMng->MsgList.CmdInProcessList.count >=
pTransacMng->MsgList.wHighWaterMark))
{
SendProvisonalResponse(pMgcpCmd->dwTransacId, RSP_TRANSACTION_QUEUED,
pTransacMng->iSocket_fd, pMgcpCmd->dwSrcIpAddr,
pMgcpCmd->wSrcPort);
pTransCmd->bProvisionalRspOut = TRUE;
pTransacMng->MsgList.bQueueIsFull = TRUE;
}
/* Construct a new stack message and send to EndpointCtrl */
/* Transaction ID */
pNewMgcpCmd->dwTransacId = pMgcpCmd->dwTransacId;
/* Endpoint name */
pNewMgcpCmd->EndpointName.pcLocalName = pMgcpCmd->EndpointName.pcLocalName;
pMgcpCmd->EndpointName.pcLocalName = NULL; // 防止指针悬空
pNewMgcpCmd->EndpointName.pcDomainName = pMgcpCmd->EndpointName.pcDomainName;
pMgcpCmd->EndpointName.pcDomainName = NULL; // 防止指针悬空
/* Source address and port of this command*/
pNewMgcpCmd->dwSrcIpAddr = pMgcpCmd->dwSrcIpAddr;
pNewMgcpCmd->wSrcPort = pMgcpCmd->wSrcPort;
/* Command type and data */
pNewMgcpCmd->eType = pMgcpCmd->eType;
pNewMgcpCmd->u.pEpcfCmd = pMgcpCmd->u.pEpcfCmd;
pMgcpCmd->u.pEpcfCmd = NULL; // 防止指针悬空
/* Construct the stack message to EndpointCtrl */
memset(&Msg, 0, sizeof(MGCP_STACK_MSG));
Msg.eMsgCode = M_INCOMING_CMD;
Msg.pMsgData = pNewMgcpCmd;
/* Must use none block like mode to send message because of mutex useage */
SendMsgToEndpointCtrl((H_MGCP_ENDPOINT_CONTROL)
pTransacMng->pStack->pEndpointCtl, &Msg);
}
}
/******************************************************************************
* Function : ProcessTransacIncomingMgcpRsp
*
* Description : Process the transaction incoming mgcp response, if it is
* a response ack, find the response waiting this ack and
* process it; if it is a old one and need ack, resend the
* ack response; if it is a new, find the outgoing command
* associating this response and process, after process,
* send it to EndpointCtrl for further process.
*
* Input parameters : H_MGCP_TRANSAC_MANAGER - TransactionManager handle
* pMgcpRsp - pointer to Mgcp incoming response to be processed
*
* Output parameters :
*
* Return value : None
*
* Comments :
*
* History :
* 2005/09/05 : Creation
*
* Date : Sep 05 2005, Frank Zhang
******************************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?