📄 rvmegacotermsignal.c
字号:
}
}
/* Signal invalid or failed in the termination */
rvMegacoTermSendErrorMsg(x,&error,RV_MEGACOERROR_NOTSPT_SIGNAL,
"Media Gateway unequipped to generate requested Signals",commReply);
return rvFalse;
}
/*
1. Stop active signals and signalLists except if a new signal with
keepAlive is present. Generate completion if required.
For each signal:
2. Validate the signal
3. Get the signal type,duration (Note: Is 0 used for default duration? )
4. Start the signal. If fails,report error
5. If type==timeout, start timer
6. For signal lists,process sequentially
*/
static void processNewSignals(RvMegacoTerm * x,const RvMegacoSignalsDescriptor * signalsDescr,
RvMegacoCommandReply * commReply) {
unsigned int i;
const RvMegacoSignal * signal;
RvMilliseconds timeout;
RvMegacoSignalType type;
/* 1. Stop active signals and signalLists except if a new signal with
keepAlive is present. Generate completion if required.*/
stopActiveSignals(x,signalsDescr,RV_MEGACOSIGNAL_NEWSIGDESCR,commReply);
for(i=0;i<rvMegacoSignalsDescriptorGetNumSignals(signalsDescr);i++) {
signal = rvMegacoSignalsDescriptorGetSignal(signalsDescr,i);
/* Ignore keepActive signals */
if(rvMegacoSignalGetKeepActiveFlag(signal))
continue;
/* Start the signal */
/* If an error is received,stop processing */
if(!startSignal(x,signal,&type,&timeout,commReply))
break;
/* Add the signal to the active signals list */
if( type!=RV_MEGACOSIGNAL_BRIEF )
addCurSignal(x,signal,timeout);
}
return;
}
/*------------------------------------------------------------*/
/* Signal lists */
/*------------------------------------------------------------*/
rvDefineList(RvMegacoCurSignalList)
rvDefineListAllocBack(RvMegacoCurSignalList)
typedef RvListIter(RvMegacoCurSignalList) RvMegacoCurSigListIter;
void RvMegacoCurSignalListConstructCopy(RvMegacoCurSignalList* d,const RvMegacoCurSignalList* s,RvAlloc* a) {
return;
}
RvBool rvMegacoCurSignalListEqual(const RvMegacoCurSignalList* x,const RvMegacoCurSignalList* y) {
return rvMegacoSignalListGetId(&x->list)==rvMegacoSignalListGetId(&y->list);
}
void rvMegacoCurSignalListDestruct(RvMegacoCurSignalList* x) {
rvMegacoTermTimerCancel(x->timer);
rvMegacoSignalListDestruct(&x->list);
}
static void rvMegacoCurSignalListConstruct(RvMegacoCurSignalList* x,RvMegacoTerm* term,
const RvMegacoSignalList* list) {
x->term = term;
x->curElem = 0;
x->stat = RV_MEGACOCURSIGLIST_NEW;
rvMegacoSignalListConstructCopy(&x->list,list,rvListGetAllocator(&term->curSignals));
}
static RvBool processSignalList(RvMegacoCurSigListIter* i,RvMegacoCommandReply * commReply);
/* Callback function for signal lists */
static void processSigListTimeout(RvTimer* timer,void* data) {
RvMegacoTermTimer* megacoTimer = (RvMegacoTermTimer*)data;
RvMegacoCurSigListIter iter = (RvMegacoCurSigListIter)megacoTimer->data;
processSignalList(&iter,NULL);
}
static void removeSignalList(RvMegacoTerm* x,RvMegacoCurSigListIter* i) {
*i = rvListErase(RvMegacoCurSignalList)(&x->curSignalLists,*i);
}
/* Sequentialy process the signal list, starting from current element.
Stop when the signal is not brief */
/* Set iterator to next valid value */
static RvBool processSignalList(RvMegacoCurSigListIter* i,RvMegacoCommandReply * commReply) {
RvMegacoCurSignalList* curList = rvListIterData(*i);
RvMegacoTerm* x = curList->term;
RvMegacoSignalList* list = &curList->list;
size_t j;
curList->stat = RV_MEGACOCURSIGLIST_DONE;
for(j=curList->curElem;j<rvMegacoSignalListGetSize(list);j++) {
RvMilliseconds timeout;
RvMegacoSignalType type;
const RvMegacoSignal* signal = rvMegacoSignalListGetElem(list,j);
/* Start the signal */
/* If an error is received,stop processing */
if(!startSignal(x,signal,&type,&timeout,commReply))
return rvFalse;
/* Increment the current element */
curList->curElem++;
/* Restore timer value to NULL */
curList->timer = NULL;
/* Keep processing as long as signals are brief */
if( type==RV_MEGACOSIGNAL_BRIEF )
continue;
/* Start the timer for this signal, type is TIMEOUT */
if( timeout ) {
curList->timer = rvMegacoTermTimerCreate(x->alloc,timeout,
processSigListTimeout,i,&x->mutex);
}
break;
}
/* The list end was reached */
if(j==rvMegacoSignalListGetSize(list)) {
removeSignalList(x,i);
}
else
*i = rvListIterNext(*i);
return rvTrue;
}
/* Stop the currently playing signal in the list */
/* Returns the next iterator after removing this one */
static RvBool stopCurSignalList(RvMegacoTerm* x,RvMegacoCurSigListIter* i,RvMegacoSignalNotificationReasons reason,
RvMdmError* error) {
RvBool retval;
RvMegacoCurSignalList* curList = rvListIterData(*i);
RvMegacoSignalList* list = &curList->list;
const RvMegacoSignal* signal = rvMegacoSignalListGetElem(list,curList->curElem);
retval = stopMdmSignal(x,signal,error);
generateCompleteEvent(x,signal,rvMegacoSignalListGetId(list),reason);
*i = rvListErase(RvMegacoCurSignalList)(&x->curSignalLists,*i);
return retval;
}
static void addSignalList(RvMegacoTerm * x,const RvMegacoSignalList *signalList) {
RvMegacoCurSignalList * cur;
cur = rvListAllocBack(RvMegacoCurSignalList)(&x->curSignalLists);
rvMegacoCurSignalListConstruct(cur,x,signalList);
}
/* calling this with signalsDescr==NULL will effectively remove all signal lists */
/* Otherwise will remove all except the keepActive and activate the new ones */
static void processNewSignalLists(RvMegacoTerm * x,const RvMegacoSignalsDescriptor * signalsDescr,
RvMegacoSignalNotificationReasons reason,
RvMegacoCommandReply * commReply) {
RvMegacoCurSigListIter i;
const RvMegacoSignalList * signalList;
RvMegacoCurSignalList* cur;
size_t j, newLists = 0;
unsigned int cnt=0,oldSize = rvListSize(&x->curSignalLists);
if(signalsDescr!=NULL)
newLists = rvMegacoSignalsDescriptorGetNumSignalLists(signalsDescr);
/* Loop over active signal lists, new signal lists */
/* If there are matching id's the old list stays alive */
/* Otherwise the new list is add to the list */
for(i=rvListBegin(&x->curSignalLists);cnt<oldSize;i=rvListIterNext(i),cnt++) {
cur = rvListIterData(i);
for(j=0;j<newLists;j++) {
signalList = rvMegacoSignalsDescriptorGetSignalList(signalsDescr,j);
if(rvMegacoSignalListGetId(&cur->list)==rvMegacoSignalListGetId(signalList) )
cur->stat = RV_MEGACOCURSIGLIST_KEEP;
else
addSignalList(x,signalList);
}
}
/* Stop and remove list with status DONE */
for(i=rvListBegin(&x->curSignalLists);i!=rvListEnd(&x->curSignalLists);) {
cur = rvListIterData(i);
if(cur->stat==RV_MEGACOCURSIGLIST_DONE) {
RvMdmError error;
rvMdmErrorConstruct_(&error);
/* Set iterator to Next */
if(!stopCurSignalList(x,&i,reason,&error))
return;
}
/* First NEW list */
else if(cur->stat==RV_MEGACOCURSIGLIST_NEW)
break;
else
i=rvListIterNext(i);
}
/* Start list with status NEW */
for(;i!=rvListEnd(&x->curSignalLists);) {
cur = rvListIterData(i);
if(cur->stat==RV_MEGACOCURSIGLIST_NEW) {
if(!processSignalList(&i,commReply))
return;
}
}
return;
}
/*------------------------------------------------------------*/
void rvMegacoTermProcessSignals(RvMegacoTerm * x,const RvMegacoSignalsDescriptor * signalsDescr,
RvMegacoCommandReply * commReply) {
if(!rvMegacoSignalsDescriptorIsSet(signalsDescr))
return;
if(rvMegacoTermMgrUtilIsCmdRspValid(commReply))
processNewSignals(x,signalsDescr,commReply);
if(rvMegacoTermMgrUtilIsCmdRspValid(commReply))
processNewSignalLists(x,signalsDescr,RV_MEGACOSIGNAL_NEWSIGDESCR,commReply);
}
/* Use to stop all signals when a requested event is detected or some other
case like term going down */
void rvMegacoTermEventStopSignals(RvMegacoTerm * x) {
stopActiveSignals(x,NULL,RV_MEGACOSIGNAL_GOTEVENT,NULL);
processNewSignalLists(x,NULL,RV_MEGACOSIGNAL_GOTEVENT,NULL);
}
/* If the interrupted signal was timeout or on-off, the completion reason is
always 'other'. Otherwise (for BRIEF) can be completed or other. */
RvMegacoSignalNotificationReasons getStopReason(RvMegacoSignalType type,RvBool normal) {
if(type==RV_MEGACOSIGNAL_ONOFF || type==RV_MEGACOSIGNAL_TIMEOUT)
return RV_MEGACOSIGNAL_OTHERREASON;
else if(normal==rvTrue)
return RV_MEGACOSIGNAL_COMPLETED;
return RV_MEGACOSIGNAL_OTHERREASON;
}
/* Implements the RvMdmXTermSignalStoppedCB callback */
void rvMegacoTermSignalStopped(RvMdmXTerm* xTerm,const char * id,const char * pkg,RvMdmMediaStream* media,RvBool normal) {
RvMegacoTerm * x = (RvMegacoTerm*)xTerm;
RvMegacoSignal target;
RvMegacoPackageItem name;
RvMegacoCurSignalIter i=0;
RvMegacoCurSigListIter j=0;
rvMegacoPackageItemConstruct(&name,pkg,id);
rvMegacoSignalConstructA(&target,&name,x->alloc);
/* Assume that the stopped signal can be in the current signals
or an active signal of the current signal list or both */
for(i=rvListBegin(&x->curSignals);i!=rvListEnd(&x->curSignals);) {
RvMegacoCurSignal * curSignal = rvListIterData(i);
if(signalMatch(&curSignal->signal,&target)) {
generateCompleteEvent(x,&curSignal->signal,0,
getStopReason(rvMegacoSignalGetType(&curSignal->signal),normal));
removeSignal(x,&i);
}
else
i=rvListIterNext(i);
}
for(j = rvListBegin(&x->curSignalLists);j!=rvListEnd(&x->curSignalLists);) {
RvMegacoCurSignalList* cur = rvListIterData(j);
const RvMegacoSignal *signal = rvMegacoSignalListGetElem(&cur->list,cur->curElem);
if(signalMatch(signal,&target)) {
generateCompleteEvent(x,signal,rvMegacoSignalListGetId(&cur->list),
getStopReason(rvMegacoSignalGetType(signal),normal));
removeSignalList(x,&j);
}
else
j=rvListIterNext(j);
}
/* Destruct local objects */
rvMegacoPackageItemDestruct(&name);
rvMegacoSignalDestruct(&target);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -