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

📄 rvmegacotermsignal.c

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

	/* 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 + -