📄 endpointctrl.c
字号:
/******************************************************************************
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 + -