protocalapi.c

来自「mgcp协议源代码和测试程序,还有一个编译器」· C语言 代码 · 共 1,971 行 · 第 1/5 页

C
1,971
字号
/******************************************************************************
  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               :  
*
*
*      Date of creation          :  08/03/2005
*
*
*      History                   :
*      2005/08/03 Frank ZHANG    : - Creation
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

#include "posix.h"
#include "mgcpdef.h"
#include "stackcb.h"

#include "endpointctrl.h"
#include "transacmng.h"

#include "protocalapi.h"

/* MGCP version name */
#define MGCP_VERSION      "1.0"

/* Task numbers of the stack */
#define TOTAL_TASK_NUM    3

/******************************************************************************
 * Function          : MgcpStackCreate
 *
 * Description       : Create the control block of the protocal stack and 
 *                     initialize it.
 *
 * Input parameters  : pCbkNotfyApp - Callback function of the stack
 *                     pCbkGetConnParams - Callback function of get the
 *                                         connection parameters.
 *
 * Output parameters : ppStack - Handle of the stack
 *
 * Return value      : Return OK if the stack is created successfylly, otherwise
 *                     return FAIL.
 *
 * Comments          : 
 *
 * History           :
 *  2005/12/15       : Creation
 *
 * Date              : Dec 15 2005, Frank Zhang
 ******************************************************************************/
LONG MgcpStackCreate(H_STACK *ppStack, CBK_MGCP_STACK pCbkNotfyApp,
                     CBK_GET_CONNEC_PARAMS pCbkGetConnParams)
{
	MGCP_STACK *pStack = (MGCP_STACK*)calloc(1, sizeof(MGCP_STACK));

	Assert(ppStack);
	Assert(pCbkNotfyApp);
	Assert(pStack);

	/* Firstly chekc Call back function */
	if (pCbkNotfyApp == NULL || pCbkGetConnParams == NULL)
	{
		return FAIL;
	}

	pStack->pCbkNotfyApp = pCbkNotfyApp;
	pStack->pCbkGetConnParams = pCbkGetConnParams;

	/* MGCP version */
	StrClone(&pStack->pcMgcpVersion, MGCP_VERSION);

	/* Init thread barrier */
	if (pthread_barrier_init(&pStack->pThreadBarrier, NULL, TOTAL_TASK_NUM) != 0)
	{
		MgcpStackDestroy((H_STACK)pStack);
		return FAIL;
	}

	/* Create EndpointCtrl CB */
	if (EndpointControlCreate((H_MGCP_ENDPOINT_CONTROL*)(&pStack->pEndpointCtl),
							  pStack) != OK)
	{
		MgcpStackDestroy((H_STACK)pStack);
		return FAIL;
	}
  
	/* Create TransactionMng CB */
	if (TransationManagerCreate((H_MGCP_TRANSAC_MANAGER*)(&pStack->pTransacMng),
								pStack) != OK)
	{
		MgcpStackDestroy((H_STACK)pStack);
		return FAIL;
	}

	*ppStack = (H_STACK)pStack;

	/* Stack state */
	pStack->eStackState = STACK_STATE_CREATED;

	return OK;
}
/******************************************************************************
 * Function          : MgcpStackStart
 *
 * Description       : Start the protocal stack.
 *
 * Input parameters  : pStack - Handle of the stack
 *
 * Output parameters :
 *
 * Return value      : Return OK if the stack is started successfylly, otherwise
 *                     return FAIL.
 *
 * Comments          : 
 *
 * History           :
 *  2005/12/15       : Creation
 *
 * Date              : Dec 15 2005, Frank Zhang
 ******************************************************************************/
LONG MgcpStackStart(H_STACK pStack)
{
	MGCP_STACK *pTmpStack = (MGCP_STACK*)pStack;

	if (pTmpStack && pTmpStack->eStackState == STACK_STATE_CREATED)
	{
		pTmpStack->eStackState = STACK_STATE_RUNNING;
		if (EndpointControlStart((H_MGCP_ENDPOINT_CONTROL)
								 (pTmpStack->pEndpointCtl)) != OK)
		{
			return FAIL;
		}
		if (TransationManagerStart((H_MGCP_TRANSAC_MANAGER)
								   (pTmpStack->pTransacMng)) != OK)
		{
			return FAIL;
		}		
	}
	else
	{
		return FAIL;
	}

	return OK;
}
/******************************************************************************
 * Function          : MgcpStackDestroy
 *
 * Description       : Destroy the protocal stack.
 *
 * Input parameters  : pStack - Handle of the stack
 *
 * Output parameters :
 *
 * Return value      : NONE
 *
 * Comments          : NOTE: The order to termiante the threads and when to
 *                           reclaim the resource must be cauciously arranged!
 *
 * History           :
 *  2005/12/15       : Creation
 *
 * Date              : Dec 15 2005, Frank Zhang
 ******************************************************************************/
void MgcpStackDestroy(H_STACK pStack)
{
#if 0
	MGCP_STACK *pTmpStack = (MGCP_STACK*)pStack;

	MGCP_ENDPOINT_CONTROL *pEndpointCtrl;

	MGCP_TRANSACTION_MANAGER *pTranMng;

	H_MGCP_ENDPOINT pEndpoint;

	Assert(pStack);

	pEndpointCtrl = (MGCP_ENDPOINT_CONTROL*)pTmpStack->pEndpointCtl;
	Assert(pEndpointCtrl);
	pTranMng = (MGCP_TRANSACTION_MANAGER*)pTmpStack->pTransacMng;
	Assert(pTranMng);

	/**************************************************************
	Firstly muse terminate the tasks according to below order !
	**************************************************************/
	/* @Step 1: Fistly must set the stack state Terminating */
	pTmpStack->eStackState = STACK_STATE_TERMINATING;

	/* @Step 2: Detach the EndpointCtrl thread */
	pthread_join(pEndpointCtrl->EndpointCtrlThread, NULL);

	/* @Step 3: Delete tick timer of EndpntCtrl */
	TimerDelete(pEndpointCtrl->TickTimer.TimerID);

	/* @Step 4: Detach the TransacMng TX thread */
	pthread_join(pTranMng->MsgTxThread, NULL);

	/* @Step 5: Delete tick timer of TransacMng */
	TimerDelete(pTranMng->TickTimer.TimerID);

	/* @Step 6: Close the socket */
	close(pTranMng->iSocket_fd);

	/* @Step 7: Detach the TransacMng RX thread, before this join, the socket 
	 must closed, because this thread is maybe blocked at receive operation of
	 socket, the close action will canceal the blocking */
	pthread_join(pTranMng->MsgRxThread, NULL);

	/**************************************************************
	Free the system resources
	**************************************************************/
	/* Close message queue */
	mq_close(pEndpointCtrl->MsgQueue);
	mq_close(pTranMng->MsgQueue);

	/* Destroy mutex */
	pthread_mutex_destroy(&pEndpointCtrl->pEndpoinCtrltMutex);
	pthread_mutex_destroy(&pTranMng->pTranMngMutex);

	/* Destroy barrier */
	pthread_barrier_destroy(&pTmpStack->pThreadBarrier);

	/* Free the memories of TransacMng */
	/* Free the domain name */
	free(pTranMng->pcDomainName);

	/* Free the mgcp message list */
	ClearMgcpMessageList(&pTranMng->MsgList);

	/* Free the control block */
	free(pTranMng);

	/* Free the memories of EndpntCrl */
	/* Clear the endpoint list */
	SListReset(&pEndpointCtrl->EndpointList);
	while((pEndpoint = SListGetCurData(&pEndpointCtrl->EndpointList)) != NULL)
	{
		ClearMgcpEndpoint(pEndpoint);
		free(pEndpoint);
		SListDelCurNode(&pEndpointCtrl->EndpointList);
	}

	/* Clear endpoint tree */
	ClearEndpointTree(&pEndpointCtrl->EndpointTree);

	/* Free the CB */
	free(pEndpointCtrl);

	/* Free the memories of Stack */
	free(pTmpStack->pcMgcpVersion);
	free(pTmpStack->pcProfileName);  
	free(pTmpStack);
#endif

#if 10
	MGCP_STACK *pTmpStack = (MGCP_STACK*)pStack;

	MGCP_ENDPOINT_CONTROL *pEndpointCtrl;

	MGCP_TRANSACTION_MANAGER *pTranMng;

	H_MGCP_ENDPOINT pEndpoint;

	Assert(pStack);
	pEndpointCtrl = (MGCP_ENDPOINT_CONTROL*)pTmpStack->pEndpointCtl;
	Assert(pEndpointCtrl);
	pTranMng = (MGCP_TRANSACTION_MANAGER*)pTmpStack->pTransacMng;
	Assert(pTranMng);

	/**************************************************************
	Firstly muse terminate the tasks according to below order !
	**************************************************************/
	/* Shut the socket to be sending only */
	shutdown(pTranMng->iSocket_fd, SHUT_RD);

	/* Set the stack state to beTerminating */
	pTmpStack->eStackState = STACK_STATE_TERMINATING;

	/* Sleep 1 seconde for all the tasks to have time to free the messages
	 in their message queue to avoid memory leak */
	sleep(1);

	/* Set the stack state to be DESTROY for the tasks to exit their loop */
	pTmpStack->eStackState = STACK_STATE_DESTROY;

	/* Detach the TransacMng TX thread */
	pthread_join(pTranMng->MsgTxThread, NULL);

	/* Delete tick timer of TransacMng */
	timer_delete(pTranMng->TickTimer.TimerID);

	/* Detach the EndpointCtrl thread */
	pthread_join(pEndpointCtrl->EndpointCtrlThread, NULL);

	/* Delete tick timer of EndpntCtrl */
	timer_delete(pEndpointCtrl->TickTimer.TimerID);

	/* Close the socket */
	close(pTranMng->iSocket_fd);

	/* Detach the TransacMng RX thread, before this join, the socket 
	 must closed, because this thread is maybe blocked at receive operation of
	 socket, the close action will canceal the blocking */
	pthread_join(pTranMng->MsgRxThread, NULL);

	/**************************************************************
	Free the system resources
	**************************************************************/
	/* Close message queue */
	mq_close(pEndpointCtrl->MsgQueue);
	mq_close(pTranMng->MsgQueue);

	/* Destroy mutex */
	pthread_mutex_destroy(&pEndpointCtrl->pEndpoinCtrltMutex);
	pthread_mutex_destroy(&pTranMng->pTranMngMutex);

	/* Destroy barrier */
	pthread_barrier_destroy(&pTmpStack->pThreadBarrier);

	/* Free the memories of TransacMng */
	/* Free the domain name */
	free(pTranMng->pcDomainName);

	/* Free the mgcp message list */
	ClearMgcpMessageList(&pTranMng->MsgList);

	/* Free the control block */
	free(pTranMng);

	/* Free the memories of EndpntCrl */
	/* Clear the endpoint list */
	SListReset(&pEndpointCtrl->EndpointList);
	while((pEndpoint = SListGetCurData(&pEndpointCtrl->EndpointList)) != NULL)
	{
		ClearMgcpEndpoint(pEndpoint);
		free(pEndpoint);
		SListDelCurNode(&pEndpointCtrl->EndpointList);
	}

	/* Clear endpoint tree */
	ClearEndpointTree(&pEndpointCtrl->EndpointTree);

	/* Free the CB */
	free(pEndpointCtrl);

	/* Free the memories of Stack */
	free(pTmpStack->pcMgcpVersion);
	free(pTmpStack->pcProfileName);  
	free(pTmpStack);
 #endif
}
/******************************************************************************
 * Function          : MgcpStackSetNetwork
 *
 * Description       : Set the network of the stack
 *
 * Input parameters  : pStack - Handle of the stack
 *                     dwLocalIPAddr - IP address
 *                     wPort - MGCP port
 *
 * Output parameters : 
 *
 * Return value      : Return OK if the stack is configured successfylly,
 *                     otherwise return FAIL.
 *
 * Comments          : 
 *
 * History           :
 *  2005/12/16       : Creation

⌨️ 快捷键说明

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