📄 rvmegacoterm.c
字号:
/******************************************************************************
Filename : rvmegacoterm.c
Description: Methods for MEGACO Termination (part of Termination Manager)
******************************************************************************
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$
******************************************************************************/
#include "rvstr.h"
#include "rvalgo.h"
#include "rvwildcard.h"
#include "rvmegacoerrors.h"
#include "rvmegacoterm.h"
#include "rvmegacocontext.h"
#include "rvmdm.h"
#include "rvmegacotermmgrutil.h"
#include "rvmegacotermevent.h"
#define RvMegacoMediaStreamConstructCopy rvMegacoMediaStreamConstructCopy
#define RvMegacoMediaStreamDestruct rvMegacoMediaStreamDestruct
#define RvMegacoMediaStreamEqual rvMegacoMediaStreamEqual
rvDefineVector(RvMegacoMediaStream)
typedef RvVectorIter(RvMegacoMediaStream) RvMegacoMediaStreamVectorIter;
typedef RvVector(RvMegacoStreamDescriptor) RvMegacoStreamDescriptorVector;
/* Static functions */
static void clearMedia(RvMegacoTerm * x,RvMegacoCommandReply * commReply);
static void constructDynamicFields(RvMegacoTerm * x);
static void destructDynamicFields(RvMegacoTerm * x);
/* Internal */
RvBool rvMegacoTermMatchId(RvMegacoTerm * x,const char * id) {
return (rvStrIcmp(rvStringGetData(&x->terminationId),id) == 0);
}
RvBool rvMegacoTermMatchWildcard(RvMegacoTerm * x,const char * pattern) {
RvWildcard w;
rvWildcardConstruct(&w,pattern,rvFalse);
return rvWildcardMatch(&w,rvStringGetData(&x->terminationId));
}
RvBool rvMegacoTermMatchWildcardEx(RvMegacoTerm * x,const char * pattern,char allChars) {
RvWildcard w;
rvWildcardConstructEx(&w,pattern,rvFalse,allChars);
return rvWildcardMatch(&w,rvStringGetData(&x->terminationId));
}
static RvMegacoMediaStream * addMediaStream(RvMegacoTerm * x,const RvMegacoStreamDescriptor * streamDescr) {
RvMegacoStreamDescriptor * termStreamDescr;
RvMegacoMediaStream * mediaStream = rvVectorAllocBack(RvMegacoMediaStream)(&x->streamList);
/* Add the streamDescriptor to the termination MediaDescriptor */
rvMegacoMediaDescriptorAddStream(&x->mediaDescr,streamDescr);
/* Get the new stream descriptor and pass it to the new stream */
termStreamDescr = (RvMegacoStreamDescriptor *)rvMegacoMediaDescriptorGetStream(&x->mediaDescr,
rvMegacoMediaDescriptorGetNumStreams(&x->mediaDescr)-1);
rvMegacoMediaStreamConstructA(mediaStream,termStreamDescr,x->alloc);
return mediaStream;
}
/* Must release both the RvMegacoMediaStream from the vector and the
RvMegacoStreamDescriptor from inside the RvMegacoMediaDescriptor */
static void releaseMediaStream(RvMegacoTerm * x,RvMegacoMediaStream * mediaStream,RvMegacoMediaStreamVectorIter i) {
RvMegacoStreamDescriptor * streamDescr = rvMegacoMediaStreamGetStreamDescriptor(mediaStream);
RvVector(RvMegacoStreamDescriptor)* streams = &x->mediaDescr.streams;
RvVectorIter(RvMegacoStreamDescriptor) j;
/* Remove the media stream */
rvVectorErase(RvMegacoMediaStream)(&x->streamList,i);
/* Remove the streamDescriptor from the termination MediaDescriptor */
/* Look for the element in the list matching the pointer */
for(j=rvVectorBegin(streams);j!=rvVectorEnd(streams);j=rvVectorIterNext(j)) {
if(streamDescr==rvVectorIterData(j)) {
rvVectorErase(RvMegacoStreamDescriptor)(streams,j);
break;
}
}
return;
}
/*************************************************************************************/
/* inList - the original,unchanged list */
/* outList - the list that goes to the application and is changed */
static RvBool updateTerminationState(RvMegacoTerm * x,const RvMegacoTerminationStateDescriptor * cmdState,RvMegacoCommandReply * commReply) {
RvMdmError error;
/* Get the media descriptor from the response */
RvMegacoMediaDescriptor * rspMedia = (RvMegacoMediaDescriptor *)rvMegacoCommandReplyGetMedia(commReply);
rvMdmErrorConstruct_(&error);
if(!rvMegacoTermMgrUtilIsCmdRspValid(commReply))
return rvFalse;
if(rvMegacoTerminationStateDescriptorIsSet(cmdState)) {
RvMegacoTerminationStateDescriptor * termState;
const RvMegacoTerminationStateDescriptor * rspState;
const RvMegacoParameterList * inList;
RvMegacoParameterList * outList;
/* Save the new state descriptor */
termState = (RvMegacoTerminationStateDescriptor *)rvMegacoMediaDescriptorGetTerminationState(&x->mediaDescr);
rvMegacoTerminationStateDescriptorCopy(termState,cmdState);
/*Process the lock step parameter*/
rvMegacoTermSetLockStep(x,rvMegacoTerminationStateDescriptorIsLockstepMode(termState));
/* Update the termination state in accord with the service state */
if(rvMegacoTerminationStateDescriptorGetServiceState(termState)==RV_MEGACOSERVICESTATE_OUTOFSERVICE)
rvMegacoTermDisable(x);
else if(rvMegacoTerminationStateDescriptorGetServiceState(termState)==RV_MEGACOSERVICESTATE_INSERVICE)
rvMegacoTermEnable(x);
/* Extract the parameter list from the command state,termination state */
inList = rvMegacoTerminationStateDescriptorGetParameterList(cmdState);
outList = (RvMegacoParameterList *)rvMegacoTerminationStateDescriptorGetParameterList(termState);
/* Update the application, application should change the list of parameters if required */
if(rvMdmTermUpdateState_(rvMegacoTermGetMdmTerm(x),outList,&error)!=rvTrue) {
return rvMegacoTermMgrUtilAddError2(commReply,&error,RV_MEGACOERROR_UNKNWN_PARAM,
"Error in Termination State",x->alloc);
}
/* Add to response if required */
rspState = rvMegacoMediaDescriptorGetTerminationState(rspMedia);
rvMegacoTermMgrUtilParamListFillDif(inList,outList,
(RvMegacoParameterList *)rvMegacoTerminationStateDescriptorGetParameterList(rspState));
}
return rvTrue;
}
static RvBool matchMediaId(RvMegacoMediaStream *m, void * id) {
RvUint32 id_ = *(RvUint32*)id;
return rvMegacoMediaStreamMatchId(m,id_);
}
rvDeclareFindIf(RvVectorIter,RvMegacoMediaStream)
rvDefineFindIf(RvVectorIter,RvMegacoMediaStream)
RvMegacoMediaStreamVectorIter getMediaStream(RvMegacoTerm * x,RvUint32 streamId) {
RvMegacoMediaStreamVectorIter i = rvFindIf(RvVectorIter,RvMegacoMediaStream)(rvVectorBegin(&x->streamList),rvVectorEnd(&x->streamList),
matchMediaId,&streamId);
if(i != rvVectorEnd(&x->streamList))
return i;
else
return NULL;
}
RvMegacoMediaStream * rvMegacoTermGetMediaStream(RvMegacoTerm * x,RvUint32 streamId) {
RvMegacoMediaStreamVectorIter i;
if((i=getMediaStream(x,streamId))==0)
return NULL;
return rvVectorIterData(i);
}
/*
7.1.6 Stream Descriptor
A stream is deleted by setting empty Local and Remote descriptors for
the stream with ReserveGroup and ReserveValue in LocalControl set to
"false" on all terminations in the context that previously supported
that stream.
*/
static RvBool isDeleteStream(const RvMegacoStreamDescriptor * streamDescr) {
RvBool emptyLocal = rvFalse,emptyRemote = rvFalse;
if( rvMegacoStreamDescriptorIsLocalDescriptorSet(streamDescr) &&
rvMegacoStreamDescriptorGetNumLocalDescriptors(streamDescr)== 0 )
emptyLocal = rvTrue;
if( rvMegacoStreamDescriptorIsRemoteDescriptorSet(streamDescr) &&
rvMegacoStreamDescriptorGetNumRemoteDescriptors(streamDescr)== 0 )
emptyRemote = rvTrue;
if( emptyLocal && emptyRemote
&&
(rvMegacoStreamDescriptorGetReserveValueMode(streamDescr)==rvFalse)
&&
(rvMegacoStreamDescriptorGetReserveGroupMode(streamDescr)==rvFalse ))
return rvTrue;
return rvFalse;
}
void rvMegacoTermProcessMedia(RvMegacoTerm * x,const RvMegacoMediaDescriptor * mediaDescr,
RvMegacoCommandReply * commReply) {
unsigned int i,id;
const RvMegacoStreamDescriptor * streamDescr;
RvMegacoMediaStream * mediaStream = NULL;
RvBool isDelete;
RvMegacoMediaStreamVectorIter iter;
/* Update the termination state */
if(!updateTerminationState(x,rvMegacoMediaDescriptorGetTerminationState(mediaDescr),commReply))
return;
/* Process the media */
for(i=0;i<rvMegacoMediaDescriptorGetNumStreams(mediaDescr);i++) {
/* Check the error status before processing a new descriptor */
if(!rvMegacoTermMgrUtilIsCmdRspValid(commReply))
return;
/* Get stream descriptor from command */
streamDescr = rvMegacoMediaDescriptorGetStream(mediaDescr,i);
id = rvMegacoStreamDescriptorGetId(streamDescr);
/* Look in the termination for the media stream with given id */
iter = getMediaStream(x,id);
if(iter)
mediaStream = rvVectorIterData(iter);
isDelete = isDeleteStream(streamDescr);
/* Add a new media stream */
if(mediaStream==NULL) { /* New media stream */
if(!isDelete ) {
mediaStream = addMediaStream(x,streamDescr);
rvMegacoMediaStreamCreateMdmMedia(mediaStream,x,streamDescr,commReply);
}
else { /* Trying to delete a non existing media */
rvMegacoTermMgrUtilAddError(commReply,RV_MEGACOERROR_INTERNAL,
"Stream Id not found",x->alloc);
}
}
else {
if(isDelete) {
rvMegacoTopologyDisconnectTermMedia(&x->context->topology,x,mediaStream);
rvMegacoMediaStreamReleaseMdmMedia(mediaStream,x,commReply);
releaseMediaStream(x,mediaStream,iter);
}
else
rvMegacoMediaStreamUpdateMdmMedia(mediaStream,x,streamDescr,commReply);
}
}
}
static void clearMedia(RvMegacoTerm * x,RvMegacoCommandReply * commReply) {
RvMegacoMediaStream * mediaStream;
RvVectorIter(RvMegacoMediaStream) i;
if(!rvMegacoTermMgrUtilIsCmdRspValid(commReply))
return;
for(i=rvVectorBegin(&x->streamList);i!=rvVectorEnd(&x->streamList);i=rvVectorIterNext(i)) {
mediaStream = rvVectorIterData(i);
rvMegacoMediaStreamReleaseMdmMedia(mediaStream,x,commReply);
}
rvVectorClear(RvMegacoMediaStream)(&x->streamList);
}
RvMegacoTermMgr* rvMegacoTermGetTermMgr(RvMegacoTerm * x) {
RvMegacoContext* context = rvMegacoTermGetContext(x);
return (context->termMgr);
}
void rvMegacoTermSetContext(RvMegacoTerm * x,RvMegacoContext* context) {
x->oldContext = x->context;
x->context = context;
}
void rvMegacoTermEnterContext(RvMegacoTerm * x,RvMegacoContext* c) {
rvMegacoTermSetContext(x,c);
rvMdmTermAddToContext_(rvMegacoTermGetMdmTerm(x),c);
}
/* isDelete==rvTrue means that the termination is subtracted and not moved */
void rvMegacoTermLeaveContext(RvMegacoTerm * x,RvMegacoCommandReply * commReply_,
RvBool isDelete,RvBool getStats) {
RvMegacoStatisticsDescriptor * stats;
RvMegacoCommandReply dummyReply,*commReply=commReply_;
RvMegacoTerminationId id;
/* If there is no command reply, construct a dummy one to avoid crashing */
if(commReply==NULL) {
rvMegacoTerminationIdConstructA(&id,rvMegacoTermGetId(x),x->alloc);
rvMegacoCommandReplyConstructExA(&dummyReply,RV_MEGACOCOMMANDTYPE_AUDITVAL,
&id,x->alloc);
commReply=&dummyReply;
}
/* Get stats */
/* Note: stats may be there from audit, may even not be produced */
if(isDelete) {
/* Clear all media */
/* Media is not deleted when the context is moved to another
context */
clearMedia(x,commReply);
/* This can be used by te application to track the time spent in the context*/
rvMdmTermRemoveFromContext_(rvMegacoTermGetMdmTerm(x),x->context);
if(getStats) {
stats = (RvMegacoStatisticsDescriptor *)rvMegacoCommandReplyGetStatistics(commReply);
rvMdmTermGetStats_(&x->mdmTerm,stats);
}
rvMdmTermResetStats_(&x->mdmTerm);
}
else
rvMdmTermMoveFromContext_(rvMegacoTermGetMdmTerm(x),x->context);
/* set context as old context */
x->oldContext = x->context;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -