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 + -
显示快捷键?