📄 rvmegacotermsignal.c
字号:
/******************************************************************************
Filename : rvmegacotermsignal.c
Description: Signal-processing MEGACO Termination Functions
******************************************************************************
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 "rvmegacoobjects.h"
#include "rvmegacotermsignal.h"
#include "rvmegacoterm.h"
#include "rvmegacoerrors.h"
static void rvMegacoCurSignalDestruct(RvMegacoCurSignal* x);
typedef RvListRevIter(RvMegacoCurSignal) RvMegacoCurSignalIter;
static void buildMdmSignal(RvMegacoTerm * x,RvMdmSignal * mdmSignal,const RvMegacoSignal * signal) {
const RvMegacoPackageItem * pkgItem;
RvMdmMediaStream * userStream;
pkgItem = rvMegacoSignalGetName(signal);
userStream = rvMegacoTermGetMediaStream(x,rvMegacoSignalGetStreamId(signal));
rvMdmSignalConstruct_(mdmSignal,rvMegacoPackageItemGetItem(pkgItem),
rvMegacoPackageItemGetPackage(pkgItem),
rvMegacoSignalGetParameterList(signal),
userStream);
}
/* Set iterator to next after removing this one */
static void removeSignal(RvMegacoTerm* x,RvMegacoCurSignalIter* i) {
/* Delete signal from list */
*i = rvListErase(RvMegacoCurSignal)(&x->curSignals,*i);
}
static RvBool stopMdmSignal(RvMegacoTerm* x,const RvMegacoSignal* signal,RvMdmError* error) {
RvMdmSignal mdmSignal;
buildMdmSignal(x,&mdmSignal,signal);
return rvMdmTermStopSignal_(&x->mdmTerm,&mdmSignal,error);
}
/*
RV_MEGACOSIGNAL_COMPLETED = 1,
RV_MEGACOSIGNAL_GOTEVENT = 2,
RV_MEGACOSIGNAL_NEWSIGDESCR = 4,
RV_MEGACOSIGNAL_OTHERREASON = 8
*/
static char* completeEventReason[] = {"TO","EV","SD","NC"};
static char* getReasonStr(RvMegacoSignalNotificationReasons reason) {
switch(reason) {
case RV_MEGACOSIGNAL_COMPLETED : return completeEventReason[0];
case RV_MEGACOSIGNAL_GOTEVENT : return completeEventReason[1];
case RV_MEGACOSIGNAL_NEWSIGDESCR : return completeEventReason[2];
case RV_MEGACOSIGNAL_OTHERREASON :
default :
return completeEventReason[3];
}
}
static void generateCompleteEvent(RvMegacoTerm* x,const RvMegacoSignal* signal,int listId,
RvMegacoSignalNotificationReasons reason) {
RvMdmMediaStream * userStream;
RvMegacoParameterList args;
RvMegacoParameterValue value;
RvMegacoPackageItem name;
const RvMegacoPackageItem * sigName;
RvString sigArg;
RvMegacoSignalNotificationReasons reqReason = rvMegacoSignalGetNotifyReasons(signal);
char list[32];
if( !(reqReason & reason) )
return;
/* Generate completion event */
rvStringConstruct(&sigArg,"",x->alloc);
rvMegacoParameterListConstructA(&args,x->alloc);
userStream = rvMegacoTermGetMediaStream(x,rvMegacoSignalGetStreamId(signal));
/* Set signal id */
sigName = rvMegacoSignalGetName(signal);
if(listId!=0) {
rvStringConcatenate(&sigArg,rvMegacoPackageItemGetPackage(sigName));
rvStringConcatenate(&sigArg,"/");
sprintf(list,"%d",listId);
rvStringConcatenate(&sigArg,list);
rvStringConcatenate(&sigArg,"{");
}
rvStringConcatenate(&sigArg,rvMegacoPackageItemGetPackage(sigName));
rvStringConcatenate(&sigArg,"/");
rvStringConcatenate(&sigArg,rvMegacoPackageItemGetItem(sigName));
if(listId!=0)
rvStringConcatenate(&sigArg,"}");
rvMegacoPackageItemConstructA(&name,"g","SigId",x->alloc);
rvMegacoParameterValueConstructA(&value,rvStringGetData(&sigArg),x->alloc);
rvMegacoParameterListSet(&args,&name,&value);
rvMegacoPackageItemDestruct(&name);
rvMegacoParameterValueDestruct(&value);
rvStringDestruct(&sigArg);
/* Set reasons */
rvMegacoPackageItemConstructA(&name,"g","Meth",x->alloc);
rvMegacoParameterValueConstructA(&value,getReasonStr(reason),x->alloc);
rvMegacoParameterListSet(&args,&name,&value);
rvMegacoParameterValueDestruct(&value);
rvMegacoPackageItemDestruct(&name);
/* Send event */
rvMdmTermProcessEvent(rvMegacoTermGetMdmTerm(x),"g","sc",userStream,&args);
/* Free local objects */
rvMegacoParameterListDestruct(&args);
}
/* Return the next iterator after removing this one */
static RvBool stopCurSignal(RvMegacoTerm* x,RvMegacoCurSignalIter* i,
RvMegacoSignalNotificationReasons reason,RvMdmError* error) {
RvBool retval;
RvMegacoCurSignal* curSignal = rvListIterData(*i);
retval = stopMdmSignal(x,&curSignal->signal,error);
generateCompleteEvent(x,&curSignal->signal,0,reason);
removeSignal(x,i);
return retval;
}
/* Callback function for signals */
static void processSignalTimeout(RvTimer* t,void * data) {
RvMegacoTermTimer* megacoTimer = (RvMegacoTermTimer*)data;
RvMegacoCurSignalIter i = (RvMegacoCurSignalIter)megacoTimer->data;
RvMegacoCurSignal* curSignal = rvListIterData(i);
RvMdmError error;
stopCurSignal(curSignal->term,&i,RV_MEGACOSIGNAL_COMPLETED,&error);
}
static void rvMegacoCurSignalConstruct(RvMegacoCurSignal* x,
RvMegacoTerm* term,const RvMegacoSignal* signal) {
x->term = term;
rvMegacoSignalConstructCopy(&x->signal,signal,rvListGetAllocator(&term->curSignals));
x->timer = NULL;
}
static void rvMegacoCurSignalDestruct(RvMegacoCurSignal* x) {
rvMegacoSignalDestruct(&x->signal);
rvMegacoTermTimerCancel(x->timer);
}
/* This will be an empty function to allow unconstructed objects to be inserted */
void RvMegacoCurSignalConstructCopy(RvMegacoCurSignal* d,const RvMegacoCurSignal* s,RvAlloc* a) {
return;
}
static RvBool signalMatch(const RvMegacoSignal* s1,const RvMegacoSignal* s2) {
const RvMegacoPackageItem* n1 = rvMegacoSignalGetName(s1);
const RvMegacoPackageItem* n2 = rvMegacoSignalGetName(s2);
/* Check if both name and media id match */
return ( rvMegacoPackageItemEqual(n1,n2) &&
rvMegacoSignalGetStreamId(s1)==rvMegacoSignalGetStreamId(s2) );
}
RvBool RvMegacoCurSignalEqual(const RvMegacoCurSignal* x,const RvMegacoCurSignal* y) {
return signalMatch(&x->signal,&y->signal);
}
rvDefineList(RvMegacoCurSignal)
rvDefineListAllocBack(RvMegacoCurSignal)
static void addCurSignal(RvMegacoTerm* x,const RvMegacoSignal* signal,RvMilliseconds timeout) {
RvMegacoCurSignal * cur;
cur = rvListAllocBack(RvMegacoCurSignal)(&x->curSignals);
rvMegacoCurSignalConstruct(cur,x,signal);
if(timeout) { /* Start timer */
cur->timer = rvMegacoTermTimerCreate(x->alloc,timeout,processSignalTimeout,
(void*)rvListRevBegin(&x->curSignals),&x->mutex);
}
}
static RvBool isKeepAlivePresent(const RvMegacoSignalsDescriptor* signalsDescr,const RvMegacoSignal* oldSignal) {
unsigned int i;
if(signalsDescr==NULL)
return rvFalse;
/* Go over all signals in new descriptor looking for a matching keepAlive*/
for(i=0;i<rvMegacoSignalsDescriptorGetNumSignals(signalsDescr);i++) {
const RvMegacoSignal* signal = rvMegacoSignalsDescriptorGetSignal(signalsDescr,i);
/* In most cases they will be no keepAlive */
if(rvMegacoSignalGetKeepActiveFlag(signal)) {
/* Check if signal == target */
if(signalMatch(signal,oldSignal))
return rvTrue;
}
}
return rvFalse;
}
static void stopActiveSignals(RvMegacoTerm * x,
const RvMegacoSignalsDescriptor * signalsDescr,
RvMegacoSignalNotificationReasons reason,
RvMegacoCommandReply * commReply) {
RvMdmError error;
RvMegacoCurSignal* curSignal;
RvMegacoCurSignalIter i;
for(i=rvListBegin(&x->curSignals);i!=rvListEnd(&x->curSignals);) {
curSignal = rvListIterData(i);
if( !isKeepAlivePresent(signalsDescr,&curSignal->signal) ) {
rvMdmErrorConstruct_(&error);
/* stopCurSignal will set next iterator */
if( !stopCurSignal(x,&i,reason,&error) ) {
/* TODO - Overwrite the error msg if not set */
rvMegacoTermSendErrorMsg(x,&error,0,"",commReply);
}
}
else
i=rvListIterNext(i);
}
return;
}
static RvMegacoSignalType getType(const RvMegacoSignal* s,const RvMdmSignalInfo* i,RvMilliseconds* timeout) {
RvMegacoSignalType type;
if( rvMegacoSignalGetType(s)==RV_MEGACOSIGNAL_DEFAULTTYPE )
type = i->type ;
else
type = rvMegacoSignalGetType(s);
/* Add timeout type signals to list of currently playing signals*/
if(type==RV_MEGACOSIGNAL_TIMEOUT) {
if(rvMegacoSignalGetDuration(s)==0)
*timeout = i->duration;
else
*timeout = rvMegacoSignalGetDuration(s)*10;
}
else
*timeout=0;
return type;
}
static RvBool startSignal(RvMegacoTerm* x,const RvMegacoSignal* signal,
RvMegacoSignalType* type,RvMilliseconds* timeout,RvMegacoCommandReply * commReply) {
const RvMegacoPackageItem* name;
const RvMdmSignalInfo* info = NULL;
RvMdmError error;
RvBool reportCompletion;
RvMdmSignal mdmSignal;
RvMdmTermMgr * mdmMgr = x->context->termMgr->mdmTermMgr;
rvMdmErrorConstruct_(&error);
/* Validate the signal */
name = rvMegacoSignalGetName(signal);
if( rvMdmTermIsPkgSupported_(rvMegacoTermGetMdmTerm(x),rvMegacoPackageItemGetPackage(name)) ) {
info = rvMdmTermMgrGetSignalInfo_(mdmMgr,&name->package,&name->item,&error);
if(info!=NULL) {
/* Start the signal */
buildMdmSignal(x,&mdmSignal,signal);
*type = getType(signal,info,timeout);
if(*type==RV_MEGACOSIGNAL_BRIEF) {
reportCompletion = rvMegacoSignalGetNotifyReasons(signal)!=0;
if(rvMdmTermPlaySignal_(&x->mdmTerm,&mdmSignal,reportCompletion,&error) ) {
return rvTrue;
}
}
else {
if(rvMdmTermStartSignal_(&x->mdmTerm,&mdmSignal,&error) ) {
return rvTrue;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -