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

📄 rvmegacotermmgr.c

📁 h.248协议源码
💻 C
📖 第 1 页 / 共 3 页
字号:
									   RvMegacoServiceChangeDescriptor * sc,RvBool keepEntity,
									   RvMegacoServiceChangeMethod method) 
{	
	RvMegacoCommand command;
	RvMegacoContextId contextId;
	RvMegacoTransaction transaction;
	RvMegacoAction action;
	RvMegacoTerminationId	tId;
	RvBool rval = rvFalse;

	rvMegacoServiceChangeDescriptorSetMethod(sc, method);
	rvMegacoServiceChangeDescriptorSetVersion(sc, rvMegacoVersion);

	rvMegacoTerminationIdConstruct(&tId, term->terminationId);
	rvMegacoServiceChangeCommandConstruct(&command, &tId, sc);
	
	rvMegacoContextIdConstructSpecial(&contextId, RV_MEGACOCONTEXTID_NULL);

	/* Construct action */
	rvMegacoActionConstruct(&action, &contextId);

	/* Add command to action */
	rvMegacoActionAddCommand(&action, &command);

	/* Construct transaction */
	rvMegacoTransactionConstruct(&transaction);

	/* Add action to transaction */
	rvMegacoTransactionAddAction(&transaction, &action);
	
	if (mgr->mgcEntityValid) {
		/* If is still the same address, then there is no need to 
		   rebuild the entity */
		if(!keepEntity)
			rvMegacoEntityDestruct(&mgr->mgcEntity);
	}

	if (keepEntity || rvMegacoEntityConstructRemote(&mgr->mgcEntity,remoteAddr, rvTrue, mgr->localEntity) !=NULL)
		{
		mgr->mgcEntityValid = rvTrue;

		rvMegacoServiceChangeDescriptorCopy(&mgr->sc, sc );

		/* Send transaction */
#ifndef RV_MEGACOTERMMGR_TESTSTACKON
		rvMegacoEntitySendRequest(&mgr->mgcEntity, &transaction, procServiceChangeReply, mgr);
#else
		rvMegacoTestStackSendRequest(mgr,&transaction);
#endif

		mgr->state = RV_MEGACOTERMMGRSTATE_REGISTERING;
		rval = rvTrue;
		}

	/* Destroy objects */
	rvMegacoTerminationIdDestruct(&tId);
	rvMegacoTransactionDestruct(&transaction);
	rvMegacoActionDestruct(&action);
	rvMegacoContextIdDestruct(&contextId);
	rvMegacoServiceChangeCommandDestruct(&command);

	return(rval);
}

void rvMegacoTermMgrSendServiceChangeUp(RvMegacoTermMgr * mgr,RvMegacoTerm * term,RvMegacoServiceChangeDescriptor * sc) 
{
	RvBool rval = rvFalse;
	RvBool keepEntity = rvFalse;
	RvMegacoServiceChangeMethod method;
	RvListIter(RvMegacoEntityAddress) tempIter;

	/* Make sure that termination is active */
	rvMegacoTermEnable(term);
	
	while (rval == rvFalse)
	{
	if (mgr->state == RV_MEGACOTERMMGRSTATE_DISCONNECTED)       /* If the state of the TermMgr is DISCONNECTED: */
		{
		tempIter =  rvPtrListBegin(&mgr->mgcAddrList);/* Connect to first entry in the table (the primary MGC for this MG)*/
		if (rvMegacoEntityAddressEqual(rvListIterData(tempIter), rvMegacoEntityGetAddress(&mgr->mgcEntity) ))
			{	/*	Unless, the last entity that we were connected to is the first entry in the table */
			tempIter = rvPtrListIterNext(tempIter);		/* Go to the second entry in the table. */
			if (tempIter == rvPtrListEnd(&mgr->mgcAddrList))	/* if there's only one entry */
				tempIter =  rvPtrListBegin(&mgr->mgcAddrList); /* go back to the begining  - so we don't wait around */
			}
		mgr->mgcAddrListIter = tempIter;
		mgr->state = RV_MEGACOTERMMGRSTATE_REGISTERING;
		}
	/*		Otherwise, attempt to connect to the first entry in the table (the primary MGC for this MG) */
	/* then, set the state to REGISTERING and continue to cycle through the entries in the table */
	/* If the state is REGISTERING, then just continue to cycle through the entries in the table */

		/* If we're at the end of the list, sleep before trying from the begining of the list */
		if (mgr->mgcAddrListIter == rvPtrListEnd(&mgr->mgcAddrList))
			{
			rvThreadSleep(1000);
			mgr->mgcAddrListIter = rvPtrListBegin(&mgr->mgcAddrList);
			}

		/* We should not be at the end of the list...*/
		if (mgr->mgcAddrListIter != rvPtrListEnd(&mgr->mgcAddrList))
			{	
			if (rvMegacoEntityAddressEqual(&mgr->lastConnectedAddress,rvListIterData(mgr->mgcAddrListIter)))
				{
				rvMdmServiceChangeSetReason(sc, RV_MDMSERVICECHANGEREASON_MGCFAILURE);
				method = RV_MEGACOSERVICECHANGEMETHOD_DISCONNECTED;
				keepEntity = rvTrue;
				}
			else
				{
			
				/* When we're not sending the SC to the primary MGC, set the method to FAILOVER */
				if (mgr->mgcAddrListIter != rvPtrListBegin(&mgr->mgcAddrList))
					{
					rvMdmServiceChangeSetReason(sc, RV_MDMSERVICECHANGEREASON_MGCFAILURE);
					method = RV_MEGACOSERVICECHANGEMETHOD_FAILOVER;
					}
				else
					{
					rvMdmServiceChangeSetReason(sc, RV_MDMSERVICECHANGEREASON_COLDBOOT);
					method = RV_MEGACOSERVICECHANGEMETHOD_RESTART;
					}
				}
			rval = sendServiceChangeToAddress(mgr,term, rvListIterData(mgr->mgcAddrListIter), sc,keepEntity,method);
			mgr->mgcAddrListIter = rvPtrListIterNext(mgr->mgcAddrListIter);
			}
	}
}


/* Reconnect to the current MGC */
void rvMegacoTermMgrReconnect(RvMegacoTermMgr * mgr)
{
	rvMutexLock(&mgr->lock);
	mgr->state = RV_MEGACOTERMMGRSTATE_REGISTERING;
	sendServiceChangeToAddress(mgr,mgr->rootTermination,rvMegacoEntityGetAddress(&mgr->mgcEntity), &mgr->sc,rvTrue,RV_MEGACOSERVICECHANGEMETHOD_RESTART);
	rvMutexUnlock(&mgr->lock);
}


/* Take the MG out of service */
static void sendServiceChangeDown(RvMegacoTermMgr * mgr,RvMegacoTerm * term,
								  RvMegacoServiceChangeDescriptor * sc,
								  RvMegacoReplyCb callbackFunc ) 
{
	RvMegacoCommand command;
	RvMegacoContextId contextId;
	RvMegacoTransaction transaction;
	RvMegacoAction action;
	RvMegacoTerminationId	tId;

	rvMegacoServiceChangeDescriptorSetMethod(sc, RV_MEGACOSERVICECHANGEMETHOD_FORCED);

	rvMegacoTerminationIdConstruct(&tId, term->terminationId);
	rvMegacoServiceChangeCommandConstruct(&command, &tId, sc);
	
	rvMegacoContextIdConstructSpecial(&contextId, RV_MEGACOCONTEXTID_NULL);

	/* Construct action */
	rvMegacoActionConstruct(&action, &contextId);

	/* Add command to action */
	rvMegacoActionAddCommand(&action, &command);

	/* Construct transaction */
	rvMegacoTransactionConstruct(&transaction);

	/* Add action to transaction */
	rvMegacoTransactionAddAction(&transaction, &action);
	
	rvMegacoServiceChangeDescriptorCopy(&mgr->sc, sc );

		/* Send transaction */
	rvMegacoEntitySendRequest(&mgr->mgcEntity, &transaction, callbackFunc, mgr);
	
	/* Destroy objects */
	rvMegacoTerminationIdDestruct(&tId);
	rvMegacoTransactionDestruct(&transaction);
	rvMegacoActionDestruct(&action);
	rvMegacoContextIdDestruct(&contextId);
	rvMegacoServiceChangeCommandDestruct(&command);
}

/* Send a service change down message for other than the root termination */
static void sendTerminationServiceChangeDown(RvMegacoTermMgr * mgr,RvMegacoTerm * term,RvMegacoServiceChangeDescriptor * sc) 
{
	sendServiceChangeDown(mgr,term, sc,NULL ) ;
}

static void freeTerm(RvMegacoTerm * term,RvAlloc * a) {
	rvMegacoTermDestruct(term);
	rvAllocDeallocate(a,sizeof(RvMegacoTerm),term);
}

static RvBool MegacoUnregisterTerm(RvMdmXTermMgr * x,RvMdmXTerm * xTerm,RvMegacoServiceChangeDescriptor * sc) {
	RvMegacoTermMgr * mgr = (RvMegacoTermMgr*)x;
	RvMegacoTerm * term = (RvMegacoTerm*)xTerm;
	RvMegacoContext * activeContext = NULL;
	
	if(!rvMegacoTermIsInNullCtxt(term))
		activeContext = rvMegacoTermGetContext(term);

	/* Stop signals, delete media */
	rvMegacoTermProcessCommandStart(term);
	rvMegacoTermDisable(term);
	rvMegacoTermProcessCommandEnd(term);

	/* If termination found in active context,remove */
	/* Note: at this point the application resources are released already 
	  so rvMegacoTermLeaveContext() is not needed */
	if(activeContext!=NULL) {
		rvMutexLock(&activeContext->mutex);

		rvMegacoTopologyRemoveTerm(&activeContext->topology,term,activeContext->alloc);
		rvMutexUnlock(&activeContext->mutex);
	}

	/* Send the service change */
	if(!rvMegacoTermIsEphemeral(term) && mgr->state == RV_MEGACOTERMMGRSTATE_REGISTERED ) {
		sendTerminationServiceChangeDown(mgr,term,sc);
	}

	if(rvMegacoTermIsPhysical(term) ) {
		rvMegacoTopologyRemoveTerm(&mgr->nullContext.topology,term,mgr->alloc);
		freeTerm(term,mgr->alloc);
	}
	else if(rvMegacoTermIsEphemeral(term)) {
		/* For ephemeral terminations,call the user callback */
		/* There is some 'risk' that the user already released the asociated
		   resources... */
		rvMdmTermMgrDeleteEphTerm_(mgr->mdmTermMgr,rvMegacoTermGetMdmTerm(term));
		rvMegacoTopologyRemoveTerm(&mgr->ephContext.topology,term,mgr->ephContext.alloc);
		freeTerm(term,mgr->alloc);
	}
	else if(term==mgr->rootTermination) {
		rvMegacoTermDestruct(term);
	}
	else
		return rvFalse;

	return rvTrue;	
}

/* Remove a termination from the ephemeral context */
void  rvMegacoTermMgrRemoveFromEphContext(RvMegacoTermMgr * mgr,struct RvMegacoTerm_ * term) {
	rvMutexLock(&mgr->ephContext.mutex);
	rvMegacoTopologyRemoveTerm(&mgr->ephContext.topology,term,mgr->ephContext.alloc);
	rvMutexUnlock(&mgr->ephContext.mutex);
}


typedef struct {
	RvMegacoServiceChangeDescriptor * sc;
	RvMegacoTermMgr * mgr;
} RvMegacoTermMgrUnregisterInfo;

static RvBool unregisterEachTerm(RvMdmTerm* term,void* data) {
	RvMegacoTermMgrUnregisterInfo* info = (RvMegacoTermMgrUnregisterInfo*)data;

	MegacoUnregisterTerm(info->mgr,term->xTerm,info->sc);
	return rvTrue;
}

static void MegacoClearTerm(RvMdmXTermMgr * x,RvMegacoServiceChangeDescriptor * sc) {
	RvMegacoTermMgr * mgr = (RvMegacoTermMgr*)x;
	RvMegacoTermMgrUnregisterInfo info;
	
	/* For each physical termination */
	/*
	t = &(mgr->nullContext.topology);
	for(i=0;i<rvMegacoTopologyGetNumTerm(t);i++) {
		MegacoUnregisterTerm(mgr,rvMegacoTopologyGetTermByIndex(t,i),sc);
	}
	*/
	info.sc = sc;
	info.mgr = mgr;
	rvMegacoContextForEachTerm(&mgr->nullContext,unregisterEachTerm,&info);

	/* For each ephemeral termination */
	/*
	t = &(mgr->ephContext.topology);
	for(i=0;i<rvMegacoTopologyGetNumTerm(t);i++) {
		MegacoUnregisterTerm(mgr,rvMegacoTopologyGetTermByIndex(t,i),sc);
	}
	MegacoUnregisterTerm(mgr,mgr->rootTermination,sc);
	*/
	rvMegacoContextForEachTerm(&mgr->ephContext,unregisterEachTerm,&info);
}

static RvMdmTerm* MegacoFindTerm(RvMdmXTermMgr * x,const char* id) {
	RvMegacoTermMgr * mgr = (RvMegacoTermMgr*)x;
	RvMegacoTerm * term = findInAllContexts(mgr,id);
	return term!=NULL ? rvMegacoTermGetMdmTerm(term) : NULL;
}

typedef struct RvMegacoIdleTermInfo_ {
	RvMegacoTerm* term;
	const char * pattern;
} RvMegacoIdleTermInfo;

static RvBool findIdleTerm(void *node, void *data) {
	RvMegacoTerm* term = (RvMegacoTerm*)node;
	RvMegacoIdleTermInfo* info = (RvMegacoIdleTermInfo*)data;
	if( rvMegacoTermIsInNullCtxt(term) && rvMegacoTermMatchWildcardEx(term,info->pattern,'$') ) {
		info->term = term;
		return rvTrue;
	}
	return rvFalse;
}

static RvMdmTerm* MegacoGetIdleTerm(RvMdmXTermMgr * x,const char* id_) {
	RvMegacoIdleTermInfo info = { NULL,NULL };
	const char * id = "$";
	if(strlen(id_))
		id = id_;
	info.pattern = id;
	rvMegacoTermMgrForEachInNullContext(x,findIdleTerm,&info);
	return info.term!=NULL ? rvMegacoTermGetMdmTerm(info.term) : NULL;
}

static RvMdmTerm* MegacoRegisterPhysTerm(RvMdmXTermMgr * x,RvMdmTermClass * c,
								   const char* id,RvMdmTermDefaultProperties* termProperties,
								   RvMegacoServiceChangeDescriptor * sc) {
	RvMegacoTermMgr * mgr = (RvMegacoTermMgr*)x;
	RvMegacoTerm * term = rvMegacoContextAddNewTerm(&mgr->nullContext,id);
	RvMdmTerm * mdmTerm = rvMegacoTermGetMdmTerm(term);

	rvMegacoTermSetType(term,RV_MDMTERMTYPE_PHYSICAL);
	rvMegacoTermInNullCtxt(term);

	/* Set default properties */
	rvMegacoTermPhysInitDefState(term);
	rvMegacoTermSetDefaultState(term,termProperties);

	/* Construct the mdmTerm */
	rvMdmTermConstruct_(mdmTerm,c,rvMegacoPhysTermMdmXClbks,term);

/*	if(mgr->state == RV_MEGACOTERMMGRSTATE_REGISTERED || mgr->state == RV_MEGACOTERMMGRSTATE_REGISTERING)*/
	if(mgr->state == RV_MEGACOTERMMGRSTATE_REGISTERED )
		rvMegacoTermMgrSendTermServiceChangeUp(mgr,term,sc);

	return mdmTerm;	
}

static RvMdmTerm* MegacoRegisterEphTerm(RvMdmXTermMgr * x,RvMdmTermClass * c,
								  const char* id,RvMdmTermDefaultProperties* termProperties) {
	RvMegacoTermMgr * mgr = (RvMegacoTermMgr*)x;
	RvMegacoTerm * term = rvMegacoContextAddNewTerm(&mgr->ephContext,id);
	RvMdmTerm * mdmTerm = rvMegacoTermGetMdmTerm(term);

	rvMegacoTermSetType(term,RV_MDMTERMTYPE_EPHEMERAL);
	rvMegacoTermInNullCtxt(term);

	/* Set default properties */
	rvMegacoTermSetDefaultState(term,termProperties);
	
	/* Construct the mdmTerm */
	rvMdmTermConstruct_(mdmTerm,c,rvMegacoEphTermMdmXClbks,term);
	return mdmTerm;	
}

/* The root termination is already constructed, id is fixed ("root") */
static RvMdmTerm* MegacoRegisterRootTerm(RvMdmXTermMgr * x,RvMdmTermClass * c,RvMdmTermDefaultProperties* termProperties) {
	RvMegacoTermMgr * mgr = (RvMegacoTermMgr*)x;
	RvMdmTerm * mdmTerm = rvMegacoTermGetMdmTerm(mgr->rootTermination);
	RvMegacoParameterValue value;
	char num[16];

	/* Reset state (maybe is not first time that is registred */
	rvMegacoTermResetDynamicFields(mgr->rootTermination);

	/* Construct the mdmTerm */
	rvMdmTermDestruct_(mdmTerm);
	rvMdmTermConstruct_(mdmTerm,c,rvMegacoRootTermMdmXClbks,mgr->rootTermination);

	/* Set default properties */
	rvMegacoTermSetDefaultState(mgr->rootTermination,termProperties);

	/* The class must support the root package */
	if(!rvMdmTermIsPkgSupported_(mdmTerm,"root"))
		rvMdmTermClassAddSupportedPkg(mdmTerm->termClass,"root",1);

	/* Set the root package properties */
	sprintf(num,"%u",rvMegacoTermMgrGetMaxContexts(mgr));
	rvMegacoParameterValueConstructA(&value,num,mgr->alloc);
	rvMegacoTermUpdateDefaultProperty(mgr->rootTermination,"root","maxNumberOfContexts",&value);
	rvMegacoParameterValueDestruct(&value);

	sprintf(num,"%u",rvMegacoTermMgrGetMaxTermPerContext(mgr));
	rvMegacoParameterValueConstructA(&value,num,mgr->alloc);
	rvMegacoTermUpdateDefaultProperty(mgr->rootTermination,"root","maxTerminationsPerContext",&value);
	rvMegacoParameterValueDestruct(&value);
	
	/* Construct the mdmTerm */
	rvMdmTermDestruct_(mdmTerm);
	rvMdmTermConstruct_(mdmTerm,c,rvMegacoRootTermMdmXClbks,mgr->rootTermination);
	return mdmTerm;	
}

⌨️ 快捷键说明

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