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

📄 endpointctrl.c

📁 mgcp协议源代码和测试程序,还有一个编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************
  Copyright(C) 2005,2006 Frank ZHANG

  All Rights Reserved.
    
  This program is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 2 of the License, or (at your option)
  any later version.

  This program is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  more details.
    
  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  Place, Suite 330, Boston, MA 02111-1307 USA.
 
 ******************************************************************************
*      Authors                   :  Frank ZHANG (openmgcp@gmail.com)
*      Description               :  EndpointCtrl module
*
*
*      Date of creation          :  09/07/2005
*
*
*      History                   :
*      2005/09/07 Frank ZHANG    : - Creation
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "typedef.h"
#include "debg.h"
#include "list.h"
#include "misc.h"

#include "posix.h"
#include "protocalapi.h"
#include "stackcb.h"
#include "endpointctrl.h"

extern LONG SendMsgToTransationManager(MGCP_TRANSACTION_MANAGER*, MGCP_STACK_MSG*);

/*****************************************************************************
  RFC3435 section 2.3.3: Event action combinability table
  
   --------------------------------------------------------------
  |       | Notif | Swap | Accum | AccDi | KeSiA | EmbNo | Ignor |
  |--------------------------------------------------------------|
  | Notif |   N   |   Y  |   N   |   N   |   Y   |   Y*  |   N   |
  | Swap  |   -   |   N  |   Y   |   N   |   N   |   N   |   Y   |
  | Accum |   -   |   -  |   N   |   N   |   Y   |   Y   |   N   |
  | AccDi |   -   |   -  |   -   |   N   |   Y   |   N   |   N   |
  | KeSiA |   -   |   -  |   -   |   -   |   N   |   Y   |   Y   |
  | EmbNo |   -   |   -  |   -   |   -   |   -   |   N   |   N   |
  | Ignor |   -   |   -  |   -   |   -   |   -   |   -   |   N   |
   --------------------------------------------------------------
  Note (*):  The "Embedded Notification Request" can only be combined with
    "Notify", if the gateway is allowed to issue more than one Notify command
    per Notification request (see RFC3435 Section 4.4.1).
******************************************************************************/

#define FBD 0     /* Forbidden */
#define PMT 1     /* Permit */

static const BYTE EventActionTable[][7] =
{  
 /* NOTIFY  SWAP  ACCUMU ACCU_DIG KEEP  EMBED  IGNORE */
    {FBD,   PMT,   FBD,   FBD,    PMT,   PMT,   FBD},     /* ACTION_NOTIFY    */
    {PMT,   FBD,   PMT,   FBD,    FBD,   FBD,   PMT},     /* ACTION_SWAP      */
    {FBD,   PMT,   FBD,   FBD,    PMT,   PMT,   FBD},     /* ACTION_ACCUMU    */
    {FBD,   FBD,   FBD,   FBD,    PMT,   FBD,   FBD},     /* ACTION_ACCU_DIG  */
    {PMT,   PMT,   PMT,   PMT,    PMT,   PMT,   PMT},     /* ACTION_KEEP      */
    {PMT,   FBD,   PMT,   FBD,    PMT,   FBD,   FBD},     /* ACTION_EMBED_REQ */
    {FBD,   PMT,   FBD,   FBD,    PMT,   FBD,   FBD}      /* ACTION_IGNORE    */    
};
/******************************************************************************
 * Function          : ConvertIpAddress
 *
 * Description       : Convert the Dot-decimal format Ip address into DWORD
 *                     
 * Input parameters  : pcSrcAddress - Dot-decimal format Ip address string
 *
 * Output parameters : pDesIpAddress - DWORD format Ip address
 *
 * Return value      : Return OK if convert successfully, otherwise return FAIL.
 *
 * Comments          : 
 *
 * History           :
 *  2005/09/07       : Creation
 *
 * Date              : Sep 07 2005, Frank Zhang
 ******************************************************************************/
LONG ConvertIpAddress(DWORD *pDesIpAddress, char *pcSrcAddress)
{  
	DWORD IPV4[4] = {0};

	if (pDesIpAddress == NULL || pcSrcAddress == NULL)
	{
		return FAIL;
	}
	
	if (sscanf(pcSrcAddress,"%ld.%ld.%ld.%ld", &IPV4[0], &IPV4[1], &IPV4[2], &IPV4[3]) == 4)
	{
		*pDesIpAddress = (IPV4[0]<<0x18) + (IPV4[1]<<0x10) + (IPV4[2]<<0x8) + IPV4[3];
		return OK;
	}
	else if (sscanf(pcSrcAddress,"[%ld.%ld.%ld.%ld]", &IPV4[0], &IPV4[1], &IPV4[2], &IPV4[3]) == 4)
	{
		*pDesIpAddress = (IPV4[0]<<0x18) + (IPV4[1]<<0x10) + (IPV4[2]<<0x8) + IPV4[3];
		return OK;
	}
	else
	{
		return FAIL;
	}
}
/******************************************************************************
 * Function          : CalculateRTOInitValue
 *
 * Description       : Calculate the initial value of RTO
 *                     
 * Input parameters  : pEndpoint - Endpoint handle 
 *
 * Output parameters : 
 *
 * Return value      : The value of RTO
 *
 * Comments          : 
 *
 * History           :
 *  2005/09/07       : Creation
 *
 * Date              : Sep 07 2005, Frank Zhang
 ******************************************************************************/
#define RTO_MAX 4000       /* Max RTO value, 4s */
DWORD CalculateRTOInitValue(H_MGCP_ENDPOINT pEndpoint)
{
	LONG TempRTO = 0;
	
	if (pEndpoint == NULL)
	{
		return 0;
	}
	
	TempRTO = ((LONG)rand() % pEndpoint->lAverAckDelay)
					+ pEndpoint->lAverAckDelay + 2*pEndpoint->lAverDeviation;
	Assert(TempRTO > 0);

	return (DWORD)((TempRTO < RTO_MAX) ? TempRTO : RTO_MAX);
}
/******************************************************************************
 * Function          : EndpointUpdataRTO
 *
 * Description       : Update the RTO of the endpoint after receive the response
 *                     to outgoing command.
 *                     
 * Input parameters  : pEndpoint - Endpoint handle 
 *                     dwTimeDelay - RTT value after sending out command and
 *                                   receiving the response
 *
 * Output parameters : 
 *
 * Return value      : None
 *
 * Comments          : 
 *
 * History           :
 *  2005/09/07       : Creation
 *
 * Date              : Sep 07 2005, Frank Zhang
 ******************************************************************************/
void EndpointUpdataRTO(H_MGCP_ENDPOINT pEndpoint, DWORD dwTimeDelay)
{
	LONG iError = 0;
	
	if (pEndpoint == NULL)
	{
		return;
	}
	iError = (LONG)dwTimeDelay - pEndpoint->lAverAckDelay;
	pEndpoint->lAverAckDelay += iError >> 3;
	iError = iError < 0 ? -iError : iError;
	pEndpoint->lAverDeviation += (iError - pEndpoint->lAverDeviation) >> 2;
}
/******************************************************************************
 * Function          : ParseEventRange
 *
 * Description       : Parse the event range string to be MGCP event range type
 *                     
 * Input parameters  : pcEventName - Event range name 
 *                     ePackageType - Package type of the event range
 *
 * Output parameters : pEventRange - The parsed MGCP event range, if fail to
 *                                 parse the event range, the result is cleared 
 *
 * Return value      : OK - Event range is parsed successfully.
 *                     FAIL - Fail to parse the event range.
 *
 * Comments          : 
 *
 * History           :
 *  2005/09/07       : Creation
 *
 * Date              : Sep 07 2005, Frank Zhang
 ******************************************************************************/
LONG ParseEventRange(char *pcEventRangeName, MGCP_EVENT_RANGE *pMgcpEventRange,
					 E_MGCP_PACKAGE ePackage)
{
	MGCP_PKG_EVENT Event;
	int i = 0;
	char *pCur = NULL;    /* Current position in the EventRangeName */

	char RangeStartValue;
	char RangeEndValue; 
	char TmpEventName[2];

	Assert(pcEventRangeName);
	Assert(pMgcpEventRange);

	memset(&Event, 0, sizeof(MGCP_PKG_EVENT));
	
	/* Fill event range name */
	StrClone(&pMgcpEventRange->pcEventName, pcEventRangeName);

  while (*pcEventRangeName != '\0')
  {
    if ((pCur = strchr(pcEventRangeName, '-')) != NULL)
    {
      /* Parser the event string before "-" */
      for (i = 0; i < pCur-pcEventRangeName; i++)
      {
        memset(TmpEventName, 0, sizeof(TmpEventName));
        TmpEventName[0] = pcEventRangeName[i];

        if (FindMgcpPkgEventByName(&Event, TmpEventName, ePackage) != OK)
        {
          free(pMgcpEventRange->pcEventName);
          SListFreeAll(&pMgcpEventRange->EventList);
          return FAIL;
        }
        else
        {
          E_MGCP_EVENT *pEvent = (E_MGCP_EVENT*)calloc(1, sizeof(E_MGCP_EVENT));
          Assert(pEvent);
          *pEvent = Event.eEventID;
          SListAppend(&pMgcpEventRange->EventList, pEvent);
        }
      }

      /* Parser the event range, such as "A-D", notice the range start value is
         one more than the value of the char before the '-', and the range end
         value is one less than the value of the char after the '-' */
      RangeStartValue = (char)(*(pCur-1)+1);
      RangeEndValue = (char)(*(pCur+1)-1);

      for (; RangeStartValue <= RangeEndValue; RangeStartValue++)
      {
        memset(TmpEventName, 0, sizeof(TmpEventName));

        /* Event name should be 1 more than the start */
        TmpEventName[0] = RangeStartValue;

        if (FindMgcpPkgEventByName(&Event, TmpEventName, ePackage) != OK)
        {
          free(pMgcpEventRange->pcEventName);
          SListFreeAll(&pMgcpEventRange->EventList);
          return FAIL;
        }
        else
        {
          E_MGCP_EVENT *pEvent = (E_MGCP_EVENT*)calloc(1, sizeof(E_MGCP_EVENT));
          Assert(pEvent);
          *pEvent = Event.eEventID;
          SListAppend(&pMgcpEventRange->EventList, pEvent);
        }
      }

      /* Advance the header to pointer to the postion past the '-' */
      pcEventRangeName = pCur+1;
    }
    else
    {
      /* No '-' is found in the string, parser the string */
      while (*pcEventRangeName != '\0')
      {
        memset(TmpEventName, 0, sizeof(TmpEventName));
        TmpEventName[0] = *pcEventRangeName;
    
        if (FindMgcpPkgEventByName(&Event, TmpEventName, ePackage) != OK)
        {
          free(pMgcpEventRange->pcEventName);
          SListFreeAll(&pMgcpEventRange->EventList);
          return FAIL;
        }
        else
        {
          E_MGCP_EVENT *pEvent = (E_MGCP_EVENT*)calloc(1, sizeof(E_MGCP_EVENT));
          Assert(pEvent);
          *pEvent = Event.eEventID;
          SListAppend(&pMgcpEventRange->EventList, pEvent);
          pcEventRangeName++;
        }
      }
    }
  }

  return OK;
}
/******************************************************************************
 * Function          : EndpointNotifyApplicationLinkState
 *
 * Description       : Notify the application the current linkage state of the
 *                     endpoint
 * 
 * Input parameters  : pEndpoint - Endpoint handle 
 *                     Linkstate - Linkage state of the endpoint
 *
 * Output parameters : 
 *
 * Return value      : None
 *
 * Comments          : 
 *
 * History           :
 *  2005/09/07       : Creation
 *
 * Date              : Sep 07 2005, Frank Zhang
 ******************************************************************************/
void EndpointNotifyApplicationLinkState(H_MGCP_ENDPOINT pEndpoint,
                                        MGCP_CBK_LINK_STATE Linkstate)
{ 
  MGCP_CBK_MSG CbkMsg;
  WORD wRspCode;

  Assert(pEndpoint);
  
  /* Notify application linkage state */
  memset(&CbkMsg, 0, sizeof(MGCP_CBK_MSG)); 
  CbkMsg.eType = MGCP_CBK_MSG_RESTART_STATE;
  CbkMsg.u.CbkRestartState = Linkstate;
  
  Assert(STACK_HANDLE(pEndpoint)->pCbkNotfyApp);  
  (STACK_HANDLE(pEndpoint))->pCbkNotfyApp((H_ENDPOINT)pEndpoint, &CbkMsg, &wRspCode);
}
/******************************************************************************
 * Function          : ClearEndpointLocalName
 *
 * Description       : Clear endpoint name
 *                     
 * Input parameters  : pName - Pointer to endpoint name 
 *
 * Output parameters : 
 *
 * Return value      : None
 *
 * Comments          : 
 *
 * History           :
 *  2005/09/12       : Creation
 *
 * Date              : Sep 12 2005, Frank Zhang
 ******************************************************************************/
void ClearEndpointLocalName(ENDPOINT_LOCAL_NAME *pName)
{
  if (pName != NULL)
  {
    while (pName->wHierarchicalNum-- > 0)
      free(pName->SubNames[pName->wHierarchicalNum]);
  }
}
/******************************************************************************
 * Function          : CheckValidityOfEndpointName
 *
 * Description       : Check validity of endpoint name according to RFC3435
 *                     
 * Input parameters  : pName - Pointer to endpoint name 
 *
 * Output parameters : 
 *
 * Return value      : Return OK if endpoint name is valid, otherwise return

⌨️ 快捷键说明

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