📄 transacmng.c
字号:
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); ((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); 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); SendMgcpRspOut(pTransacMng, pTransRsp->pRspOut, FALSE); } /* Check if the command has been responsed with piggybacking commands */ else if (SListFind(&pTransacMng->MsgList.RspSentPiggybackList, &pMgcpCmd->dwTransacId, FindMgcpRspOutByTranID) != NULL) { /* Re-Send the response */ pTransRsp = SListGetCurData(&pTransacMng->MsgList.RspSentPiggybackList); 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); 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); 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 ******************************************************************************/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_MIN && 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); /* 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); /* 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -