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

📄 rvmegacotopology.c

📁 h.248协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	return rvTrue;
}

static void disconnectMedias(RvMegacoTerm * t1,RvMegacoMediaStream * s1,
						  RvMegacoTerm * t2,RvMegacoMediaStream * s2,
						  RvMegacoLink * link) {
	RvMdmError error;
	RvMdmTermMgr * mgr = t1->context->termMgr->mdmTermMgr;

	/* A matching media stream exists and the link state is not isolated */
	if(s2!=NULL ) { 
		rvMdmErrorConstruct_(&error);
		rvMdmTermMgrDisconnectMediaStreams_(mgr,rvMegacoTermGetMdmTerm(t1),s1,
											rvMegacoTermGetMdmTerm(t2),s2,
											&error);
	}
}

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

	if(s2!=NULL) { /* A matching media stream exists */
		RvMdmTermMgr * mgr = t1->context->termMgr->mdmTermMgr;
		rvMdmTermMgrDisconnectMediaStreams_(mgr,rvMegacoTermGetMdmTerm(t1),s1,
											rvMegacoTermGetMdmTerm(t2),s2,
											error);
		/* Reconnect using the new mode */
		return connect2Medias(t1,s1,t2,s2,link,error);	
	}
	return rvTrue;
}




/* Disconnect the media stream connection between a given stream in a given termination
   and all associated streams */
/* TODO: What should be the status of a disconnected stream (the other side?) */
/* TODO : Rewrite with foreach ? */
void rvMegacoTopologyDisconnectTermMedia(RvMegacoTopology * x,RvMegacoTerm* term,RvMegacoMediaStream * stream) {
	RvGraphLinkIter l;
	RvGraphNodeIter i = rvGraphFindNode(x,term);

	for(l=rvGraphNodeOutLinksBegin(i);l!=rvGraphNodeOutLinksEnd(i);l=rvGraphLinkIterNext(l)){
		/* Disconnect the stream from the other node */
		RvMegacoLink * link = (RvMegacoLink*)rvGraphLinkIterGetData(l);
		RvMegacoTerm* t2 = (RvMegacoTerm*)rvGraphLinkIterGetNode(l);
		RvMegacoMediaStream * s2 = rvMegacoTermGetMediaStream(t2,rvMegacoMediaStreamGetId(stream));
		if(link->direction!=RV_MDMSTREAMDIRECTION_ISOLATE)
			disconnectMedias(term,stream,t2,s2,link);			
	}
	for(l=rvGraphNodeInLinksBegin(i);l!=rvGraphNodeInLinksEnd(i);l=rvGraphLinkIterNext(l)){
		/* Disconnect the stream from the other node */
		RvMegacoLink * link = (RvMegacoLink*)rvGraphLinkIterGetData(l);
		RvMegacoTerm* t2 = (RvMegacoTerm*)rvGraphLinkIterGetNode(l);
		RvMegacoMediaStream * s2 = rvMegacoTermGetMediaStream(t2,rvMegacoMediaStreamGetId(stream));
		if(link->direction!=RV_MDMSTREAMDIRECTION_ISOLATE)
			disconnectMedias(term,stream,t2,s2,link);			
	}
}

/*
		for all (out) links with status update 
		  update all matching media connection		
		  update link
*/
static RvBool updateConnections(RvMegacoTopology * x,RvGraphNodeIter i,RvMegacoMediaStream * s1,RvMdmError* error) {
	RvGraphLinkIter l;
	RvMegacoTerm * t2; 
	RvMegacoTerm * t1 = (RvMegacoTerm*)rvGraphNodeIterGetNode(i); 
	RvMegacoMediaStream * s2;
	RvMegacoLink * link;
	RvBool retval = rvTrue;

	for(l=rvGraphNodeOutLinksBegin(i);l!=rvGraphNodeOutLinksEnd(i);l=rvGraphLinkIterNext(l)) {
		link = (RvMegacoLink*)rvGraphLinkIterGetData(l);
		t2 = (RvMegacoTerm*)rvGraphLinkIterGetNode(l);
		s2 = rvMegacoTermGetMediaStream(t2,rvMegacoMediaStreamGetId(s1));
		/* First connect any new media,then update existing media if needed */  
		if(s2!=NULL && (rvMegacoMediaStreamIsStatusNew(s1) || rvMegacoMediaStreamIsStatusNew(s2)) ) {
			retval = connectMedias(t1,s1,t2,s2,link,error);
		}
		else if(rvMegacoLinkToUpdate(link)==rvTrue) {
			if(getOldDirection(link)==RV_MDMSTREAMDIRECTION_ISOLATE)
				retval = connectMedias(t1,s1,t2,s2,link,error);
			else if(rvMegacoLinkGetDirection(link)==RV_MDMSTREAMDIRECTION_ISOLATE)
				disconnectMedias(t1,s1,t2,s2,link);
			else
				retval = modifyMediaConnect(t1,s1,t2,s2,link,error);
		}
		if(retval==rvFalse)
			break;

		/* Mark link as updated and media stream status as connected */
		rvMegacoLinkUpdated(link);
	}

	return retval;
}


/* Connect the media streams for all the terminations with new or
   updated topology  */
/* For every termination:
	For every media
	  If media status == NEW 
		 connect to all connected terminations (both sides) with matching media
		 update media status
	  else
		for all (out) links with status update 
		  update all matching media connection		
		  update link
*/

RvBool rvMegacoTopologyUpdateMediaConnections(RvMegacoTopology * x,RvMdmError* error) {
	RvGraphNodeIter i;
	RvMegacoMediaStream * stream;
	RvMegacoTerm * term;
	unsigned int k;
	RvBool retval = rvTrue;

	/* Update topology for all nodes */
	for(i=rvGraphBegin(x);i!=rvGraphEnd(x) && retval==rvTrue;i=rvGraphNodeIterNext(i)) {
		term = (RvMegacoTerm*)rvGraphNodeIterGetNode(i);
		for(k=0;k<rvMegacoTermGetNumOfStreams(term) && retval==rvTrue;k++) {
			stream = rvMegacoTermGetMediaStreamElem(term,k);
			retval = updateConnections(x,i,stream,error);
			rvMegacoMediaStreamSetStatusConnected(stream);
		}
	}
	return retval;
}

typedef struct {
	RvGraph *graph;
	RvMegacoTerm * term;
} RvMegacoNewTermInfo;

static RvBool duplicateLinkFrom(void *head, void *tail, void *link, void *data) {
	RvMegacoLink * link_ = link;
	RvMegacoNewTermInfo * info = (RvMegacoNewTermInfo*)data;	
	rvGraphAddLink(info->graph,info->term,tail,link);
	link_->refCnt++;
	return rvFalse;
}
static RvBool duplicateLinkTo(void *head, void *tail, void *link, void *data) {
	RvMegacoLink * link_ = link;
	RvMegacoNewTermInfo * info = (RvMegacoNewTermInfo*)data;	
	rvGraphAddLink(info->graph,head,info->term,link);	
	link_->refCnt++;
	return rvFalse;
}

void rvMegacoTopologyDuplicate(RvMegacoTopology * x,RvMegacoTerm * orig,RvMegacoTerm * copy) {
	RvMegacoNewTermInfo info;

	info.graph = x;
	info.term = copy;
	rvGraphForEachLinkFromNode(x,orig,duplicateLinkFrom,&info);
	rvGraphForEachLinkToNode(x,orig,duplicateLinkTo,&info);
	rvMegacoTermSetSerialNumber(copy,rvMegacoTermGetSerialNumber(orig));
}
/*
typedef struct {
	unsigned int count;
	unsigned int target;
	RvMegacoTerm * term;
} RvMegacoFindLinkNumberInfo;

static RvBool findLinkNumber(void *head, void *tail, void *link, void *data) {
	RvMegacoFindLinkNumberInfo * info = (RvMegacoFindLinkNumberInfo *)data;
	if(info->count==info->target) {
		info->term = (RvMegacoTerm*)tail;
		return rvTrue;
	}
	info->count = info->count+1;
	return rvFalse;
}
*/
unsigned int rvMegacoTopologyGetNumTerm(RvMegacoTopology * x) {
	RvGraphNodeIter i;
	unsigned int k = 0;

	/* Update topology for all nodes */
	for(i=rvGraphBegin(x);
		i!=rvGraphEnd(x); i=rvGraphNodeIterNext(i)) {
		k++;
	}
	return k;
}

RvMegacoTerm * rvMegacoTopologyGetTermByIndex(RvMegacoTopology * x,unsigned int index) {
	RvGraphNodeIter i;
	RvMegacoTerm * term;
	unsigned int k = 0;

	/* Update topology for all nodes */
	for(i=rvGraphBegin(x);
		i!=rvGraphEnd(x); i=rvGraphNodeIterNext(i)) {
		term = (RvMegacoTerm*)rvGraphNodeIterGetNode(i);
		if(k==index)
			return term;
		k++;		
	}
	return NULL;
}

/*********************************************************/
/* Functions to connect a new termination to the context */
/*********************************************************/

/* Create connection for a new termination */
/*
TODO: Implement. By now is hard to do because the links are unidirectional ?
static RvBool connectNewTermMedia(RvMegacoTopology * x,RvGraphNodeIter iNewTerm,RvMdmError* error) {
	RvMegacoMediaStream * stream;
	RvMegacoTerm * term;
	RvGraphNodeIter i;
	unsigned int k;
	RvBool retval=rvTrue;

	// Update topology for the new node 
	term = (RvMegacoTerm*)rvGraphNodeIterGetNode(iNewTerm);

	// Link are unidirectional, from lower element in the graph to higher element //
	for(i=rvGraphBegin(x);i!=iNewTerm && retval==rvTrue; i=rvGraphNodeIterNext(i)) {
		for(k=0;k<rvMegacoTermGetNumOfStreams(term) && retval==rvTrue;k++) {
			stream = rvMegacoTermGetMediaStreamElem(term,k);
			// Mark the media as "new" , can be reinserted after "Move" failed //
			rvMegacoMediaStreamIsStatusNew(stream);
			retval = updateConnections(x,iNewTerm,stream,error);
			rvMegacoMediaStreamSetStatusConnected(stream);
		}
	}
	return retval;
}
*/

/* Update topology for a new termination */
static RvBool updateNewTermTopology(RvMegacoTopology * x,RvMegacoTerm* chosenTerm,
								const RvMegacoTopologyDescriptor * topology,RvGraphNodeIter iNewTerm) {

	size_t k;
	const RvMegacoTerminationId *termId1,*termId2;
	const char* id1, * id2;
	RvGraphNodeIter i,i1,i2;
	RvDirection direction;
	RvMegacoTerm * term = (RvMegacoTerm*)rvGraphNodeIterGetNode(iNewTerm);

	/* Go over the topology and look for a triple matching this termination */
	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);

		/* Check if any termination matched the new term */
		if(!rvStrIcmp(rvMegacoTermGetId(term),id1) || 
			(term==chosenTerm && rvMegacoTerminationIdIsChoose(termId1)) )  {
			i1 = iNewTerm;			
			/* Find the other termination */
			if(rvMegacoTerminationIdIsNormal(termId2) )
				i2 =  rvMegacoTopologyGetTermIter(x,id2);
			else if( rvMegacoTerminationIdIsChoose(termId2) && chosenTerm!=NULL ) 
				i2 =  rvGraphFindNode(x,chosenTerm);

		}
		else if(!rvStrIcmp(rvMegacoTermGetId(term),id2) || 
			(term==chosenTerm && rvMegacoTerminationIdIsChoose(termId2) ))  {
			i2 = iNewTerm;
			/* Find the other termination */
			if(rvMegacoTerminationIdIsNormal(termId1) )
				i1 =  rvMegacoTopologyGetTermIter(x,id1);
			else if( rvMegacoTerminationIdIsChoose(termId1) && chosenTerm!=NULL ) 
				i1 =  rvGraphFindNode(x,chosenTerm);


		}
		else  /* No match */
			continue; 
			
		if(i1 && i2) {
			rvMegacoTopologyUpdateLink(x,i1,i2,direction);
			continue;
		}

		/* The remaining case: the other one is wildcarded */
		/* Link are unidirectional, from lower element in the graph to higher element */
		for(i=rvGraphBegin(x);i!=iNewTerm; i=rvGraphNodeIterNext(i)) {
			rvMegacoTopologyUpdateLink(x,i,iNewTerm,direction);
		}

	};
	return rvTrue;	
}

RvBool rvMegacoTopologyConnectNewTerm(RvMegacoTopology * x,RvMegacoTerm * term,RvMegacoTerm * chosenTerm,
									  const RvMegacoTopologyDescriptor* topology,
									  RvMegacoCommandReply * commReply,RvAlloc* a) {
	RvGraphNodeIter i = rvGraphFindNode(x,term);
	RvMdmError error;
	
	rvMdmErrorConstruct_(&error);

	if(!rvMegacoTermMgrUtilIsCmdRspValid(commReply))
		return rvFalse;

	/* Update the topology */
	if(topology)
		updateNewTermTopology(x,chosenTerm,topology,i);
	
	/* Connect to other terminations */
	if( rvMegacoTopologyUpdateMediaConnections(x,&error)!= rvTrue ) {
		rvMegacoTermMgrUtilAddError2(commReply,&error,RV_MEGACOERROR_NOTAVAIL_RSRC,
									 "Insufficient resources",a);		
		return rvFalse;
	}
	return rvTrue;
}

⌨️ 快捷键说明

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