📄 rvmegacotopology.c
字号:
}
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 + -