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

📄 rvmegacotopology.c

📁 h.248协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
Filename   : rvmegacotopology.c
Description: Methods for MEGACO Context Topology - 
			 Graph holding terminations and links between them
******************************************************************************
                Copyright (c) 1999 RADVision Inc.
************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision LTD.
No part of this publication may be reproduced in any form whatsoever 
without written prior approval by RADVision LTD..

RADVision LTD. reserves the right to revise this publication and make 
changes without obligation to notify any person of such revisions or 
changes.
******************************************************************************
$Revision:$
$Date:11.15.00$
$Author: D.Elbert$
******************************************************************************/

/******************************************************************************
	Link class, used for the context graph
******************************************************************************/
#include "rvmegacotopology.h"
#include "rvmegacoterm.h"
#include "rvmegacoobjects.h"
#include "rvmegacoerrors.h"


void rvMegacoLinkConstruct(RvMegacoLink * link) {
	rvMegacoLinkConstructEx(link,RV_MDMSTREAMDIRECTION_BOTHWAYS);
}

void rvMegacoLinkConstructEx(RvMegacoLink * link,RvMdmStreamDirection direction) {
	link->direction = direction;
	/*link->oldDirection = direction;*/
	link->oldDirection = RV_MDMSTREAMDIRECTION_ISOLATE;
/*	link->state = RV_MEGACOLINKSTATE_TOCONNECT;*/
	link->refCnt = 1;
}

void  rvMegacoLinkDestruct(RvMegacoLink * link) {
	link->refCnt--;
/*	link->state = 0;*/
}


void  rvMegacoLinkSetDirection(RvMegacoLink * link,RvMdmStreamDirection direction) {
	link->oldDirection = link->direction;
	link->direction = direction;
}

RvMdmStreamDirection rvMegacoLinkGetDirection(RvMegacoLink * link) {
	return link->direction;
}

static RvMdmStreamDirection correctDirection(RvMdmStreamDirection direction,RvBool inOrder) {
	if(inOrder==rvTrue)
		return direction;

	/* Reverse source2target,target2source */
	if(direction==RV_MDMSTREAMDIRECTION_SOURCE2TARGET)
		return RV_MDMSTREAMDIRECTION_TARGET2SOURCE;

	if(direction==RV_MDMSTREAMDIRECTION_TARGET2SOURCE)
		return RV_MDMSTREAMDIRECTION_SOURCE2TARGET;

	return direction;
}

static RvMdmStreamDirection getOldDirection(RvMegacoLink * link) {
	return link->oldDirection;
}

RvBool rvMegacoLinkToUpdate(RvMegacoLink * link) {
	return (link->oldDirection!=link->direction);
}

void rvMegacoLinkUpdated(RvMegacoLink * link) {
	link->oldDirection=link->direction;
}

RvMdmStreamDirection rvMegacoLinkGetTrueDirection(RvMegacoLink * x,RvMegacoTerm * source, RvMegacoTerm * target) {
	RvBool inOrder;
	if(rvMegacoTermGetSerialNumber(source) < rvMegacoTermGetSerialNumber(target))
		inOrder = rvTrue;
	else 
		inOrder = rvFalse;
	return correctDirection(rvMegacoLinkGetDirection(x),inOrder);
}


/******************************************************************************
	Topology class
******************************************************************************/

static void renumberNodes(RvMegacoTopology * x) {
	/* Iterate through all nodes and number them from 0 to n */	
	RvGraphNodeIter i;
	RvMegacoTerm * term;
	unsigned int j =0;

	/* Update topology for all nodes */
	for(i=rvGraphBegin(x);i!=rvGraphEnd(x); i=rvGraphNodeIterNext(i)) {
		term = (RvMegacoTerm*)rvGraphNodeIterGetNode(i);
		rvMegacoTermSetSerialNumber(term,j++);
	}
}

/* Generate incremental serial number for the graph nodes */
static RvUint32 getNewSerialNumber(RvMegacoTopology * x) {
	RvMegacoTerm * term;
	if(!rvGraphGetNumNodes(x)) /* No nodes in graph */
		return 0;
	term = (RvMegacoTerm*)rvGraphNodeIterGetNode(rvGraphTail(x));
	if(rvMegacoTermGetSerialNumber(term)==0xFFFFFFFE)
		renumberNodes(x);
	return rvMegacoTermGetSerialNumber(term) + 1;
}

static RvBool matchAlways(void * node,void * data) {
	return rvTrue;
}

static RvMegacoLink * getLinkFromNodeIter(RvMegacoTopology * x,RvGraphNodeIter source,RvGraphNodeIter target,RvBool * inOrder) {
	void * head, * tail;
	RvMegacoTerm* t1 = (RvMegacoTerm*)rvGraphNodeIterGetNode(source);
	RvMegacoTerm* t2 = (RvMegacoTerm*)rvGraphNodeIterGetNode(target);
	if(rvMegacoTermGetSerialNumber(t1) < rvMegacoTermGetSerialNumber(t2) ) {	   
		head = source;
		tail = target;
		*inOrder = rvTrue;
	}
	else {
		head = target;
		tail = source;
		*inOrder = rvFalse;
	}
	return rvGraphFindLinkFromNodeIter(x,head,tail,matchAlways,0);
}
/*
static RvMegacoLink * getLink(RvMegacoTopology * x,RvMegacoTerm * source,RvMegacoTerm * target,RvBool * inOrder) {
	return getLinkFromNodeIter(x,rvGraphFindNode(x,source),rvGraphFindNode(x,target),inOrder);
}
*/
/* Links are always created in the rigth order,no need to check for order */
void rvMegacoTopologyCreateLink(RvMegacoTopology * x,RvMegacoTerm * source, RvMegacoTerm * target,RvAlloc * alloc) {
	RvMegacoLink * link = (RvMegacoLink *)rvAllocAllocate(alloc,sizeof(RvMegacoLink));
	rvMegacoLinkConstruct(link);
	rvGraphAddLink(x,source,target,link);
	return;
}

static RvBool deallocLink(void *head, void *tail, void *link_, void *data) {
	RvAlloc * alloc = (RvAlloc*)data;
	RvMegacoLink * link = (RvMegacoLink *)link_;
	rvMegacoLinkDestruct(link);
	/* The link data is used in two link, free only if the reference
	   count is zero */
	if(!link->refCnt)
		rvAllocDeallocate(alloc,sizeof(RvMegacoLink),link);
	return rvTrue;
}

/* Note: Remove has been split in Disconnect & Remove */
void rvMegacoTopologyRemoveTerm(RvMegacoTopology * x,RvMegacoTerm * term,RvAlloc * linkAlloc) {
	/*
	unsigned int k;
	RvMegacoMediaStream* stream;

	for(k=0;k<rvMegacoTermGetNumOfStreams(term);k++) {
		stream = rvMegacoTermGetMediaStreamElem(term,k);
		rvMegacoTopologyDisconnectTermMedia(x,term,stream);
	}
	*/
	rvGraphRemoveNodeExt(x,term,deallocLink,linkAlloc);
}

void rvMegacoTopologyDisconnectTerm(RvMegacoTopology * x,RvMegacoTerm * term,RvAlloc * linkAlloc) {
	unsigned int k;
	RvMegacoMediaStream* stream;

	for(k=0;k<rvMegacoTermGetNumOfStreams(term);k++) {
		stream = rvMegacoTermGetMediaStreamElem(term,k);
		rvMegacoTopologyDisconnectTermMedia(x,term,stream);
		/* Can be reconnected in another context */
		rvMegacoMediaStreamSetStatusNew(stream);
	}
}

void rvMegacoTopologyAddTerm(RvMegacoTopology * x,RvMegacoTerm * term,RvAlloc * linkAlloc) {
	RvGraphNodeIter i;
	void * target;

	rvMegacoTermSetSerialNumber(term,getNewSerialNumber(x));
	rvGraphAddNode(x,term);	
	target = rvGraphNodeIterGetNode(rvGraphTail(x));

	/* connect last node to all others if the context is not null or ephemeral */
	/* In that case the allocator will be set to null */
	if( linkAlloc ) {
		for(i=rvGraphBegin(x); i!=rvGraphTail(x); i=rvGraphNodeIterNext(i))
			rvMegacoTopologyCreateLink(x,rvGraphNodeIterGetNode(i),target,linkAlloc);		
	}
	return;
}


static RvBool matchTermId(void *node, void *data) {
	return rvMegacoTermMatchId((RvMegacoTerm*)node,(const char*)data);
}

static RvGraphNodeIter rvMegacoTopologyGetTermIter(RvMegacoTopology * x,const char * id) {
	return rvGraphFindNodeIterCmp(x,matchTermId,(void*)id); 
}

RvMegacoTerm * rvMegacoTopologyGetTerm(RvMegacoTopology * x,const char * id) {
	return rvGraphFindNodeCmp(x,matchTermId,(void*)id); 
}

RvBool rvMegacoTopologyIsTermPresent(RvMegacoTopology * x,RvMegacoTerm * ptr) {
	return rvGraphFindNode(x,ptr)!=rvGraphEnd(x);
}


static void rvMegacoTopologyUpdateLink(RvMegacoTopology * x,RvGraphNodeIter source,RvGraphNodeIter target,RvDirection direction) {

	if(source!=rvGraphEnd(x) && target!=rvGraphEnd(x) ) {
		RvBool inOrder;
		RvMegacoLink * link = getLinkFromNodeIter(x,source,target,&inOrder);	
		switch(direction) {
			case RV_DIRECTION_BOTHWAYS: 
				rvMegacoLinkSetDirection(link,RV_MDMSTREAMDIRECTION_BOTHWAYS); break;
			case RV_DIRECTION_ISOLATE:  
				rvMegacoLinkSetDirection(link,RV_MDMSTREAMDIRECTION_ISOLATE); break;
			case RV_DIRECTION_ONEWAY:   
				rvMegacoLinkSetDirection(link,correctDirection(RV_MDMSTREAMDIRECTION_SOURCE2TARGET,inOrder));
				break;
		}
	}
}

/* Get topology from descriptor and update */
RvBool rvMegacoTopologyUpdate(RvMegacoTopology * x,RvMegacoTerm* chosenTerm,
							  const RvMegacoTopologyDescriptor * topology) {

	size_t k;
	const RvMegacoTerminationId *termId1,*termId2;
	const char* id1, * id2;
	RvGraphNodeIter i1,i2,i,j;
	RvDirection direction;

	/* Go over the topology and update */
	for(k=0;k<rvMegacoTopologyDescriptorGetNumTriples(topology);k++) {
		/* Get termination id */
		termId1 = rvMegacoTopologyDescriptorGetFirstTerminationId(topology,k);
		termId2 = rvMegacoTopologyDescriptorGetSecondTerminationId(topology,k);
		id1 = rvMegacoTerminationIdGetId(termId1);
		id2 = rvMegacoTerminationIdGetId(termId2);
		i1 = i2 = 0;

		/* Get topology */
		direction = rvMegacoTopologyDescriptorGetDirection(topology,k);

		if(rvMegacoTerminationIdIsNormal(termId1) )
			i1 = rvMegacoTopologyGetTermIter(x,id1);
		else if( rvMegacoTerminationIdIsChoose(termId1) && chosenTerm!=NULL ) 
			i1 = rvGraphFindNode(x,chosenTerm);

			
		if(rvMegacoTerminationIdIsNormal(termId2) )
			i2 = rvMegacoTopologyGetTermIter(x,id2);
		else if( rvMegacoTerminationIdIsChoose(termId2) && chosenTerm!=NULL ) 
			i2 = rvGraphFindNode(x,chosenTerm);
			
		if(i1 && i2) {
			rvMegacoTopologyUpdateLink(x,i1,i2,direction);
			continue;
		}

		/* The remaining case: at least one is wildcarded */
		/* Link are unidirectional, from lower element in the graph to higher element */
		for(i=rvGraphBegin(x);i!=rvGraphEnd(x); i=rvGraphNodeIterNext(i)) {
			/* If this is not wildcard, ignore all cases but the specific */
			if(i1 && i1!=i) 
				continue;
			for(j=rvGraphNodeIterNext(i);j!=rvGraphEnd(x); j=rvGraphNodeIterNext(j)) {
				/* If this is not wildcard, ignore all cases but the specific */
				if(i2 && i2!=j)
					continue;
				rvMegacoTopologyUpdateLink(x,i,j,direction);
			}
		}

	};
	return rvTrue;	
}

/*
If direction is ISOLATE, the streams don't get connected
*/
RvBool connect2Medias(RvMegacoTerm* t1,RvMegacoMediaStream* s1,
					  RvMegacoTerm* t2,RvMegacoMediaStream* s2,
					  RvMegacoLink* link,RvMdmError* error) {
	RvMdmTermMgr* mgr = t1->context->termMgr->mdmTermMgr;
	RvMdmStreamDirection direction = rvMegacoLinkGetTrueDirection(link,t1,t2);
	/* If GetTrueDirection==Target2Source,invert both term & media stream... */
	if(direction==RV_MDMSTREAMDIRECTION_TARGET2SOURCE) {
		return rvMdmTermMgrConnectMediaStreams_(mgr,rvMegacoTermGetMdmTerm(t2),s2,
												rvMegacoTermGetMdmTerm(t1),s1,
												RV_MDMSTREAMDIRECTION_SOURCE2TARGET,error);
	}
	else if(direction!=RV_MDMSTREAMDIRECTION_ISOLATE){
		return rvMdmTermMgrConnectMediaStreams_(mgr,rvMegacoTermGetMdmTerm(t1),s1,
												rvMegacoTermGetMdmTerm(t2),s2,
												rvMegacoLinkGetDirection(link),error);
	}
	return rvTrue;
}

static RvBool connectMedias(RvMegacoTerm * t1,RvMegacoMediaStream * s1,
						  RvMegacoTerm * t2,RvMegacoMediaStream * s2,
						  RvMegacoLink * link,RvMdmError* error) {

	if(s2!=NULL) { /* A matching media stream exists */
		return connect2Medias(t1,s1,t2,s2,link,error);

⌨️ 快捷键说明

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