ENDPT_410_casTaskMain

while(1)
	bosSleep( CAS_TASK_RATE )	//延时10 ms
	
	//读取命令队列
while(memCircBufRead(casCtlCmdQ,(char*)&command,sizeof(CASCMD))==BUF_STATUS_OK 	)
	//执行命令处理,收集命令信息,CASIO内容比较多,放在下面单独介绍
	casIO(&casState.service[command.devhdl].localmem, &command);
	
	//如果是同步模式,则需要释放信号量
	if ( command.mode == CAS_CMD_MODE_SYNC )
		bosSemGive(&casSynCmdSem);

for( chan = 0; chan < casState.numChannels; chan++ )	//遍历所有通道
	//如果在初始化CAS服务时,该通道的类型无效,则不继续处理
	if (casState.service[chan].localmem.channelinfo.castype == CAS_TYPE_INACTIVE)
		continue;
	
	//CAS通道控制开启时才处理
	if( casState.service[chan].localmem.status & CAS_ENABLED )
		//如果在CAS控制对象中通道类型为FXO(其实就是FXS口,正好相反)
		if (casState.service[chan].localmem.channelinfo.castype == CAS_TYPE_FXO)
			//获取CAS驱动对象
			casDriver = casState.service[chan].localmem.channelinfo.casDriver;
			//获取摘挂机历史记录长度,当前6816功能宏没开,返回1
			casHistLength = xdrvCasNumHookSamples( casDriver );
		else
			//不是FXS口类型的通道,历史记录长度为1
			casHistLength = 1;
		
		for ( i=0; i < casHistLength; i++ )
			//CAS控制器主函数,设置SLIC模式,获取摘挂机状态,控制灯位(当
//前6816没有使用,使用的是系统GPIO),并针对事件进行处理(包
//括脉冲、FLASH键、R键检测,摘挂机事件上报全部在这里)
			casBlk( &casState.service[chan] );
if( ! ( localp->status & CAS_ENABLED ))			//校验通道开启
return;

					//设置SLIC驱动状态,并获取摘挂机信息,下面单独写
casbits_rx = casUpdate( &localp->channelinfo );	//调用外部驱动
				
					// casbits为调用casBlk 函数返回的摘挂机状态
// localp->channelinfo 为当前通道信息
//callbackp回调之前设置为NULL
//CAS事件处理,下面单独写
					casProcess( casbits_rx, &localp->channelinfo, srvp->callbackp );
	
	//交替振铃算法状态机,需要开启CAS_CTL_CFG_STAGGER_RING_SUPPORT功能宏
	//目前6816没有开启该功能宏,该功能暂不关心
	StaggerBlk();
	
---------------------------------------------------------------------------------------------------------------------------
casIO
switch ( cmdp->cmd )
// CAS服务是否使能
case CAS_ENABLE:
	if ( cmdp->op1 == VRG_TRUE )	//上层指示要开启
		//如果之前没有开启,则复位一些信息,并记为开启
		if ( (localp->status & CAS_ENABLED) != CAS_ENABLED )
			casInitJitterBuf( &localp->channelinfo );
			localp->status = 0;
			localp->status |= CAS_ENABLED;
		else if (localp->status & CAS_ENABLED)	//上层指示关闭
			localp->status &= ~CAS_ENABLED;
			casFlushJitterBuf( &localp->channelinfo );

//上层设置CAS状态改变
case CAS_STATECTL:
	if (localp->status & CAS_ENABLED)		//CAS服务开启后才能设置状态
		bosCritSectEnter( &localp->critSect );
		//提取旧状态位
		state = (CAS_CTL_FXO_INTERFACE_STATE) (((localp->channelinfo.state) &
 								CAS_STATEBITS_MASK) >> CAS_STATEBITS_SHIFT);
		//提取新状态位
		nextState = (CAS_CTL_FXO_INTERFACE_STATE)
((((CASPROFILE *)cmdp->op2.ref)->casstm.state[0].stateinfo &
 CAS_STATEBITS_MASK) >> CAS_STATEBITS_SHIFT);
		
		//当将FXS口设备,从ADDRESSING或ACTIVE切为IDLE状时时,忽略这种切换
        if ( (localp->channelinfo.castype == CAS_TYPE_FXO) 
        	&& (state == CAS_CTL_FXO_ADDRESSING || state == CAS_CTL_FXO_ACTIVE) 
            && (nextState == CAS_CTL_FXO_IDLE))
			free(cmdp->op2.ref);
			bosCritSectLeave( &localp->critSect );
return(CAS_CTL_SUCCESS);
		
		//存储处理信息,供之后函数调用
		if (localp->channelinfo.profilep != NULL)
			free(localp->channelinfo.profilep);
		localp->channelinfo.profilep = cmdp->op2.ref;
		
		//复位状态机触发值
		localp->channelinfo.counter = CAS_CTL_CFG_TASK_RATE_MS;
		//如果老状态与新状态不同
		if ( (localp->channelinfo.state & CAS_STATEBITS_MASK) !=
     		( ((CASPROFILE *)cmdp->op2.ref)->casstm.state[0].stateinfo &
 CAS_STATEBITS_MASK) )
//更新信息
			localp->channelinfo.substate = 0;
			localp->channelinfo.currentCount = 0;
			if( (localp->channelinfo.state & CAS_STATEBITS_MASK) == FXOBITS_IDLE )
				localp->channelinfo.deglitchCount=
CAS_CTL_DEFAULT_FXO_DEGLITCH_MSEC;
		//设置下一状态0
localp->channelinfo.state = ((localp->channelinfo.state
                                        & (CAS_STATEBITS_MASK + CAS_ABCD_MASK))
                                        | CAS_NEXTSTATE_0);
		bosCritSectLeave( &localp->critSect );

//初始CAS配置
case CAS_CONFIG:
	//通道类形及通道号,注意这里FXO口类型对应上面是FXO口,相反
	localp->channelinfo.castype = cmdp->op1;
	localp->channelinfo.channelnum = cmdp->op2.val;
	//设置初始状态
    localp->channelinfo.state = 
            ((cmdp->op1 == CAS_TYPE_FXS) ? FXSBITS_RELEASED : FXOBITS_IDLE);
	localp->channelinfo.substate = FXO_STARTUP_IDLE;
	localp->channelinfo.statechange = VRG_FALSE;

//配置FXO类型通道
case CAS_CONFIG_FXO:
	//存储FXO口参数
	fxoParms = (CAS_CTL_FXO_PARMS*)cmdp->op2.ref;
	localp->channelinfo.fxoParms = *fxoParms;
	free(cmdp->op2.ref);

//退出CAS服务
case CAS_EXIT:
	bosCritSectDestroy( &localp->critSect );

//获取CAS通道信息
case CAS_GET_LINESTATUS:
	CASSTATUS *statusp = cmdp->op2.ref;
statusp->state = localp->channelinfo.state;
    statusp->currentCAS = localp->channelinfo.currentCAS;
    statusp->currentCount = localp->channelinfo.currentCount;
    statusp->deglitchCount = localp->channelinfo.deglitchCount;
    statusp->substate = localp->channelinfo.substate;

//设置SLIC相关命令
case CAS_SLIC_CMD:
	casProcessSlicCommands(cmdp);
		switch( cmdp->reqid )
		//设置升压环路电流使能
		case CAS_REQ_SLIC_BOOTED_LOOP_CURRENT:
			xdrvSlicSetBoostedLoopCurrent( slicDrv, (int)cmdp->op2.val );
		
		//设置铃流配置
		case CAS_REQ_SLIC_SET_RING_PARMS:
			xdrvSlicSetRingParms( slicDrv, (int)parms->arguments[0],
								(int)parms->arguments[1], (int)parms->arguments[2],
								(int)parms->arguments[3], (int)parms->arguments[4] );
		
		//设置极性反转
		case CAS_REQ_SLIC_PHASE_REVERSAL_CONTROL:
			xdrvSlicPhaseReversalControl( slicDrv, (int)cmdp->op2.val );
		
		//设置电源使用电池还是市内交流电,跟下面代码好像没用
		case CAS_REQ_SLIC_SET_POWER_SOURCE:
			xdrvSlicSetPowerSource( slicDrv, (int)cmdp->op2.val );
		
//FXO相关命令
case CAS_DAA_CMD:
	//没有去看,大概包括设置控制模式、获取摘挂机状态
	casProcessDaaCommands(cmdp);

//APM模块相关命令
case CAS_APM_CMD:
	//没有去看,大概包含设置APM相关振铃参数,请求脉冲信号
	casProcessApmCommands(cmdp);

---------------------------------------------------------------------------------------------------------------------------
casUpdate
	casUpdateFXS( channelinfop );	//FXO口芯片相关
		//获取接口状态及事件比特位
		interfaceState = (CAS_CTL_FXS_INTERFACE_STATE)
      	((channelinfop->state & CAS_STATEBITS_MASK) >> CAS_STATEBITS_SHIFT);
		casbits = (VRG_UINT16)(channelinfop->state & CASBITS_MASK);
		
		//获FXO口芯片驱动对象
		daaDriver = (XDRV_DAA*)channelinfop->casDriver;
		
		if ( channelinfop->statechange )	//如果有状态改变
			channelinfop->statechange = VRG_FALSE;	//清除标记
			
			switch ( interfaceState )
			case CAS_CTL_FXS_SEIZED:
				//控制FXO芯片摘机
				xdrvDaaModeControl( daaDriver, XDRV_DAA_MODE_OFFHOOK );
			
			case CAS_CTL_FXS_CLIDRX:
				//控制FXO芯片到挂机并检测来显状态
				xdrvDaaModeControl( daaDriver, XDRV_DAA_MODE_ONHOOK_DATA );
			
			case CAS_CTL_FXS_RELEASED:
			default:
				//控制FXO芯片到挂机状态
				xdrvDaaModeControl( daaDriver, XDRV_DAA_MODE_ONHOOK );
		
		//执行FXO驱动自身事件处理回调
		xdrvDaaProcessEvents( daaDriver );
		
		if( xdrvDaaIsOffhook( daaDriver ) )	//检测到FXO口摘机
			loopCurrent = xdrvDaaGetLoopCurrent( daaDriver );	//检测当前环路状态
			
			switch ( loopCurrent )
			case XDRV_DAA_LOOP_CLOSED:	//环路闭合
				return CASBITS_LCF;		//返回LCF信号位
			case XDRV_DAA_LOOP_CLOSED_REVERSE:	//环路反向闭合
				return CASBITS_RLCF;		//返回RLCF信号位
			case XDRV_DAA_LOOP_OPEN:
			default:
				return CASBITS_LCFO;		//返回LCFO信号位
		else if ( xdrvDaaIsRingActive ( daaDriver ) )		//检测到FXO口振铃
			return( CASBITS_RINGING );		//返回RINGING信号位
		else
			return CASBITS_LCFO;			//返回LCFO信号位
		
casUpdateFXO( channelinfop );	//FXS口芯片相关
	//获取上层设置的CAS状态位
	interfaceState = (VRG_UINT16)((channelinfop->state & CAS_STATEBITS_MASK) >>
CAS_STATEBITS_SHIFT);
	
	//获取上层设置的CAS对应状态位的附属信息
	casbits = (VRG_UINT16)(channelinfop->state & CASBITS_MASK);
	
	casDriver = channelinfop->casDriver;	//获取CAS驱动
						
	//如果上层设置改变标记才执行
	if (channelinfop->statechange)
		switch (interfaceState)
		// SLIC服务是否使能,如果为LCF,则设置SLIC开启环路馈电,否则设置
//SLIC关闭环路馈电
		case CAS_CTL_FXO_SERVICEDENIED:
			if ( casbits == CASBITS_LCF )
				casSetSlicState( channelinfop, XDRV_SLIC_MODE_LCF );
				else
					casSetSlicState( channelinfop, XDRV_SLIC_MODE_LCFO );
								
			//设置SLIC到正常待命令状态
			case CAS_CTL_FXO_IDLE:
				casSetSlicState( channelinfop, XDRV_SLIC_MODE_STANDBY );
								
			//设置上层为振铃状态,如果为LCF,则设置SLIC到挂机传送状态,如果为RLCF,
//则设置SLIC到反向挂机传送状态,否则设置SLIC为振铃状态
			case CAS_CTL_FXO_ALERTING:
			case CAS_CTL_FXO_JAPAN_ALERTING:
			case CAS_CTL_FXO_JAPAN_ALERTING_CLID:
			case CAS_CTL_FXO_JAPAN_ALERTING_CLID_OFFHOOK:
				if ( casbits == CASBITS_LCF )
					casSetSlicState( channelinfop,XDRV_SLIC_MODE_OHT );
else if ( casbits == CASBITS_RLCF )
casSetSlicState( channelinfop, XDRV_SLIC_MODE_OHTR );
else
casSetSlicState( channelinfop, XDRV_SLIC_MODE_RING );
								
			//其它状态,则根据是否LCF,则设置SLIC正向馈电,还是反向馈电
			default:
				if ( casbits == CASBITS_LCF )
					casSetSlicState( channelinfop, XDRV_SLIC_MODE_LCF );
				else
					casSetSlicState( channelinfop, XDRV_SLIC_MODE_RLCF );
			
			channelinfop->statechange = VRG_FALSE;//复位标记
							
		//SLIC自身事件处理回调,当前函数为空
		xdrvSlicProcessEvents( casDriver->slicDriver );
							
		//从SLIC寄存器中读取摘挂机状态,并调用SLIC自身点灯程序(目前6816点灯程
//序无内容,因为灯位是板子的GPIO实现),返回环路断开或环路闭合
		If ( xdrvCasGetHookState( casDriver ) == XDRV_CAS_ONHOOK )
			return( CASBITS_LO );
		else
			return( CASBITS_LC );

-------------------------------------------------------------------------------------------------------------------------------
casProcess

//CAS任务主循环每次延时时间为10 ms,即CAS任务每10ms调度一次
blockrate = CAS_CTL_CFG_TASK_RATE_MS;	

//如果当前计数小于8秒(这里是为了在状态长时间不变时,如电话挂机空闲,必免监控
//函数被频繁调用,在状态改变时,如从挂机转为摘机状态,currentCount会被重新设置为
//一个比较小的值)
//并且没有忽略摘挂机检测
//并且是FXS口类型
//并且没有关闭服务
if (( channelp->currentCount < CAS_STANBDY_THRESH ) &&
 ( channelp->ignoreHookState == CAS_IGNOREHOOKSTATE_OFF ) &&
       !((channelp->castype == CAS_TYPE_FXO) &&
         (( channelp->state & CAS_STATEBITS_MASK ) 
          == FXOBITS_SERVICEDENIED )))
	channelp->currentCount += blockrate;		//累加当前时间
	
	//注释描述说是为了解决L9500芯片从摘机到挂机转换时小问题,在SLIC设置为IDLE
	//模式时,deglitchCount设置为200ms,当时间超出200ms时,casMonitor函数中设置
	//SLIC模式才生效
	if(channelp->deglitchCount > blockrate)
		channelp->deglitchCount -= blockrate;
	else
		channelp->deglitchCount = 0;
	
	//监控处理周期为20ms毫秒,并且当前状态和上次一样时
	if (( channelp->currentCount >= CAS_MONITOR_RATE ) && ( channelp->currentCAS ==
 casbits ))
		//处理CAS事件,其中摘挂机上取就在这里,函数后面单独介绍
		casMonitor( channelp, callbackp );

//如果是FXS口,
//并且摘挂机状态改变
//并且没有忽略摘挂机检测
//并且没有关闭服务
if ((channelp->castype == CAS_TYPE_FXO) &&
       ( channelp->currentCAS != casbits ) &&
       ( channelp->ignoreHookState == CAS_IGNOREHOOKSTATE_OFF ) &&
       ( ( channelp->state & CAS_STATEBITS_MASK ) 
          != FXOBITS_SERVICEDENIED ))
	channelp->newCount += blockrate;	//记载新的状态变量使用时间
	//如果状态改变的时候超过防抖动时间,则认为是合法的状态改变,而不是因为电路
	//干扰引发的误改变
	if (channelp->newCount >= CAS_CTL_DEFAULT_FXO_DEBOUNCE_MSEC)
		//改变当前计数值,是为了激活上面的状态监控又重新实时调度
		//记录最新状态
		channelp->currentCount = CAS_CTL_DEFAULT_FXO_DEBOUNCE_MSEC;
		channelp->currentCAS = casbits;
		
		//处理CAS事件,其中摘挂机上取就在这里,函数后面单独介绍
		casMonitor( channelp, callbackp );
		channelp->newCount = 0;
//如果是FXO口设备,并且状态改变
else if ( (channelp->castype == CAS_TYPE_FXS) && (channelp->currentCAS != casbits) )
	//同FXS口处理类似
	if (channelp->newCountFxs >= FXS_DEBOUNCE)
		channelp->currentCount = FXS_DEBOUNCE;
		channelp->currentCAS = casbits;
		casMonitor( channelp, callbackp );
		channelp->newCountFxs = 0;
//否是其它条件下(如状态一直没有改变等),复位去抖动相关变量
else
	channelp->newCount = 0;
	channelp->newCountFxs = 0;

//获取该通道的PROFILE,
profilep = channelp->profilep;

if (profilep != NULL)		//如果上层CAS设置命令含有相关附属信息则执行
	channelp->counter -= blockrate;	//CAS任务扣除延时时间点
	if (channelp->counter <= 0)
		if ((channelp->state & CAS_ENDING_STATE) == CAS_ENDING_STATE)//如果状态完成
			if( profilep != NULL )
free(profilep);
			channelp->profilep = NULL;
			
			//如果之前是短振铃事件,则上报短振铃完成
			if ( ( channelp->state & CASEVENT_BRIEF_RING ) == CASEVENT_BRIEF_RING )
				casGenEvent( callbackp, CAS_CTL_BRIEF_RING_COMPLETE_EVENT, 0, 0 );
		else	//必非最终状态完成
			//获取下一个状态索引
			statenum = (VRG_UINT16)((channelp->state & CAS_NEXTBITS_MASK) >>
 CAS_NEXTBITS_SHIFT);	
			
			//如果有环回标记,则下一状态索引从afterloop中取,目前还没看到哪里设置
			//这个标记
			if (channelp->state & CAS_LOOP_FLAG)
				profilep->casstm.loopcount--;
				if (profilep->casstm.loopcount == 0)
					statenum = profilep->casstm.afterloop;
			
			channelp->statechange = VRG_TRUE;	//标记需要状态改变
			
			//获取下一个状态的触发时间
			channelp->counter = profilep->casstm.state[statenum].duration;
			
			state = profilep->casstm.state[statenum].stateinfo;	//获取新的状态值
			
			//如果非RINGING、LCFO、SERVICEDENIED则记载先前状态
			if ((( channelp->state & CASBITS_MASK ) != CASBITS_RINGING ) &&
                (( channelp->state & CASBITS_MASK ) != CASBITS_LCFO )    && 
                (( channelp->state & CAS_STATEBITS_MASK ) != FXOBITS_SERVICEDENIED ))
				channelp->previousActiveState = channelp->state;
			
			channelp->state = state;		//改变CAS状态
			
			if (channelp->state & CAS_EVENT_MASK)	//如果有事件
				//获取事件
				stateEvent = (VRG_UINT16)((channelp->state & CAS_EVENT_MASK) >>
 CAS_EVENT_SHIFT);
				//放入事件队列,让DISP任务处理
				casGenEvent( callbackp, CAS_CTL_STATECTL_EVENT, stateEvent, 
														channelp->channelnum );

------------------------------------------------------------------------------------------------------------------------
casMonitor
	casMonitorFXO( channelinfop, callbackp );	//临控FXS类型通道
		//获取当前CAS状态,当前摘挂机状态,当前时间计数
		state = (CAS_CTL_FXO_INTERFACE_STATE) (((channelinfop->state) &
CAS_STATEBITS_MASK) >> CAS_STATEBITS_SHIFT);
		casbits = (channelinfop->currentCAS) & CAS_ABCD_MASK;
		currentCount = channelinfop->currentCount;
		
		switch (state)
		//日式,挂机状态下振铃加来显状态
		case CAS_CTL_FXO_JAPAN_ALERTING_CLID:
			if ((casbits & CASBITS_LC) == CASBITS_LC)	//摘机
				if ( currentCount >= channelinfop->fxoParms.minConnect )	//到达摘机下限
					//状态改为JAPAN_ALERTING_CLID_OFFHOOK状态
					//并上报摘机事件
					casChangeControlState( channelinfop, callbackp,
					( FXOBITS_JAPAN_ALERTING_CLID_OFFHOOK | CASEVENT_OFFHOOK | 
																CASBITS_RLCF ));
		
		//日式,摘机状态下振铃加来显状态
		case CAS_CTL_FXO_JAPAN_ALERTING_CLID_OFFHOOK:
			if ((casbits & CASBITS_LC) == CASBITS_LC)
			{
}
else	//挂机
	//到达挂机下限,状态改为JAPAN_ALERTING_CLID状态,并上报挂机
	if ( currentCount >= channelinfop->fxoParms.minDisconnect )
		casChangeControlState( channelinfop, callbackp,
				( FXOBITS_JAPAN_ALERTING_CLID | CASEVENT_ONHOOK |
 		CASBITS_RLCF ));
		
		//CAS服务未使用,什么都不做
		case CAS_CTL_FXO_SERVICEDENIED:
		{
}

//挂机态
case CAS_CTL_FXO_IDLE:
	if ((casbits & CASBITS_LC) == CASBITS_LC)	//摘机
		if (channelinfop->earlyOffState)		//标记早期摘机
			//上报早期摘机事件
			casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
				CAS_CTL_EVENT_EARLY_OFFHOOK, channelinfop->channelnum );
		//到达抗尖峰缓冲时间则更新SLIC状态
		if(channelinfop->deglitchCount == 0)
			casSetSlicState( channelinfop, XDRV_SLIC_MODE_LCF );
		//重置标记
		channelinfop->earlyOffState = 0;
		channelinfop->earlyOnState = 1;
		
		if (channelinfop->delayOffState)	//标记延时摘机
			//上报延时摘机
			casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
				CAS_CTL_EVENT_DELAY_OFFHOOK, channelinfop->channelnum );
		//重置标记
		channelinfop->delayOffState = 0;
		channelinfop->delayOnState = 1;
		
		//到达最小摘机时间
		if ( currentCount >= channelinfop->fxoParms.minConnect )
			//改为ADDRESSING状态,上报摘机事件
			casChangeControlState( channelinfop, callbackp,
				FXOBITS_ADDRESSING | CASEVENT_OFFHOOK | CASBITS_LCF );
		//到达生成一个脉冲的WINK时间
		else if ( currentCount >= channelinfop->fxoParms.minWink )
			channelinfop->substate = FXO_IDLE_WINK;	//标记到达WINK时间
		else
			channelinfop->substate = 0;	//复位
	else	//挂机
		//如果有早期挂机标记
		if (channelinfop->earlyOnState)
			//上报早期挂机事件
			casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
				CAS_CTL_EVENT_EARLY_ONHOOK, channelinfop->channelnum );
			//到达抗尖峰缓冲时间则更新SLIC状态
			if(channelinfop->deglitchCount == 0)
				casSetSlicState( channelinfop, XDRV_SLIC_MODE_STANDBY );
			//复位标记
			channelinfop->earlyOffState = 0;
			channelinfop->earlyOnState = 1;
		
		//如果有延时挂机标记
		if (channelinfop->delayOffState)
			//上报延时挂机事件
			casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
				CAS_CTL_EVENT_DELAY_ONHOOK, channelinfop->channelnum );
			//复位标记
			channelinfop-> delayOnState = 0;
			channelinfop-> delayOffState = 1;
		
		//如果前面标记有一个肪冲WINK
		if (channelinfop->substate == FXO_IDLE_WINK)
			//并且到达了最小WINK时间
			if ( currentCount >= channelinfop->fxoParms.minPostWink )
				//上报一个WINK事件
				casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
					CAS_CTL_EVENT_WINK, channelinfop->channelnum );
				channelinfop->substate = 0;
		//在CAS初始化时,substate 被置为FXO_STARTUP_IDLE状态,这里仅仅
		//需要需要状态设置为正常可用的IDLE,并设置LCF环路馈电。这个仅在
		//CAS初始化时执行这一次
		else if (channelinfop->substate == FXO_STARTUP_IDLE)
			casChangeControlState( channelinfop, callbackp,
						FXOBITS_IDLE | CASEVENT_NOEVT | CASBITS_LCF );
			channelinfop->substate = 0;

//振铃状态
case CAS_CTL_FXO_ALERTING:
case CAS_CTL_FXO_JAPAN_ALERTING:
	if ((casbits & CASBITS_LC) == CASBITS_LC)	//摘机
		//到达正常振铃时间
		if (channelinfop->currentCount >= CAS_CTL_CFG_RING_TRIP_REMOVE)
			//切到ACTIVE状态,上报摘机事件,并设置之前的LCF或RLCF
			casChangeControlState( channelinfop, callbackp,
				( FXOBITS_ACTIVE | CASEVENT_OFFHOOK |
 ( channelinfop->previousActiveState & CASBITS_MASK ) ) );
		
		//之前已经处于摘机态(CAS_CTL_FXO_ACTIVE是从被叫振铃后摘机切换
//,CAS_CTL_FXO_ADDRESSING是从主叫摘机切换)
		case CAS_CTL_FXO_ACTIVE:
		case CAS_CTL_FXO_ADDRESSING:
			if ((casbits & CASBITS_LC) == CASBITS_LC)	//摘机
				//有早期摘机标记,则上报早期摘机事件	
				if ((channelinfop->earlyOffState) && (currentCount >=
channelinfop->fxoParms.earlyActiveHookInterval))
	casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
		CAS_CTL_EVENT_EARLY_OFFHOOK, channelinfop->channelnum );
				channelinfop->earlyOffState = 0;
				channelinfop->earlyOnState = 1;
				
				//有延时摘机标记,则上报延时摘机事件
				if ((channelinfop->delayOffState) && (currentCount >= 
				channelinfop->fxoParms.delayActiveHookInterval))
					casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
						CAS_CTL_EVENT_DELAY_OFFHOOK, channelinfop->channelnum );
					channelinfop->delayOffState = 0;
					channelinfop->delayOnState = 1;
				
				//如果之前到达FLASH下限,并且现在又到达FLASH范围内,则上报FLASH
				if (channelinfop->substate == FXO_FLASH_STARTED)
					if (currentCount >= FXO_POSTFLASH)
						casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
						CAS_CTL_EVENT_FLASH, channelinfop->channelnum );
					channelinfop->substate = 0;
				
				//如果之前到达R键下限,并且现在又到达R键范围内,则上报FLASH
				if (channelinfop->substate == FXO_R_STARTED)
					if (currentCount >= FXO_POSTRKey)
						casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
							CAS_CTL_EVENT_FLASH, channelinfop->channelnum );
						channelinfop->substate = 0;
				
				//如果到达一个脉冲按键时间,则上报当前按键,这里右移1位
				//是因为按键收集是2个substate为1次脉冲,如substate为6,则
				//当前按键为3
				if (currentCount >= channelinfop->fxoParms.pulseMaxMake)
					if ((channelinfop->substate) && 
(channelinfop->substate != FXO_FLASH_STARTED) &&
(channelinfop->substate != FXO_R_STARTED))
						casGenEvent( callbackp, CAS_CTL_PULSEDIAL_EVENT,
							(VRG_UINT16)(channelinfop->substate >> 1), 
							channelinfop->channelnum );
						channelinfop->substate = 0;
				//否则可能是一个脉冲数字
				else
					if (currentCount >= channelinfop->fxoParms.pulseMinMake)
						if (channelinfop->substate & 1)
							channelinfop->substate++;
			else	//挂机
				//早期挂机检测,则上报早期挂机事件
				if ((channelinfop->earlyOnState) && (currentCount >= 
									channelinfop->fxoParms.earlyActiveHookInterval))
					casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
						CAS_CTL_EVENT_EARLY_ONHOOK, channelinfop->channelnum );
					channelinfop->earlyOnState = 0;
					channelinfop->earlyOffState = 1;
				
				//延时挂机检测,则上报延时挂机事件
				if ((channelinfop->delayOnState) && (currentCount >= 
								channelinfop->fxoParms.delayActiveHookInterval))
					casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
						CAS_CTL_EVENT_DELAY_ONHOOK, channelinfop->channelnum );
					channelinfop->delayOnState = 0;
					channelinfop->delayOffState = 1;
				//如果当前时间已经大于最大的肪冲BREAK时间,则这不是一个正常的
				//脉冲电压,忽略之前的肪冲数字统计
				if (currentCount >= channelinfop->fxoParms.pulseMaxBreak)
					channelinfop->substate = 0;
				else
					//如果当前时间大于最小的脉冲BREAK,则可能是一个肪冲按键,进
					//行数字统计,两次substate累加为1个数字
					if (currentCount >= channelinfop->fxoParms.pulseMinBreak)
						if (!(channelinfop->substate & 1))
							channelinfop->substate++;
				
				//如果当前时间大于最小挂机时间,则上报挂机事件
				if ( currentCount >= channelinfop->fxoParms.minDisconnect )
					casChangeControlState( channelinfop, callbackp,
						FXOBITS_IDLE | CASEVENT_ONHOOK | CASBITS_LCF );
					channelinfop->substate = 0;
				else
					//检测是否满足合法的R键范围,满足则记开始位
					if (currentCount >= channelinfop->fxoParms.maxRKey)
						channelinfop->substate = 0;
					else if (currentCount >= channelinfop->fxoParms.minRKey)
						channelinfop->substate = FXO_R_STARTED;
					
					//检测是否满足合法的FLASH键范围,满足则记开始位
					if (currentCount >= channelinfop->fxoParms.maxHookFlash)
						channelinfop->substate = 0;
					else if (currentCount >= channelinfop->fxoParms.minHookFlash)
						channelinfop->substate = FXO_FLASH_STARTED;
	
	casMonitorFXS( channelinfop, callbackp );	//临控FXO类型通道
		//获取接口状态、信号比特位、当前次数
		state = (CAS_CTL_FXS_INTERFACE_STATE) (((channelinfop->state) & 
		CAS_STATEBITS_MASK) >> CAS_STATEBITS_SHIFT);
		casbits = (channelinfop->currentCAS) & CAS_ABCD_MASK;
		currentCount = channelinfop->currentCount;
		
		switch (state)
		case CAS_CTL_FXS_RELEASED:		//挂机状态
			if ( casbits == CASBITS_RINGING )	//如果检测到振铃
				//达到一定振铃时长
				if ( currentCount >= FXS_RINGON && channelinfop->substate != 1 )
					channelinfop->substate = 1;	//设置子状态
					
					//发送CAS事件,检测到振铃
					casGenEvent( callbackp, CAS_CTL_DETECT_EVENT, 
					CAS_CTL_EVENT_RINGON, channelinfop->channelnum );
				else if (channelinfop->substate == 1)	//在振铃ON子状态
					if (currentCount >=  FXS_RINGOFF)	//达到停振时长
						//发送CAS事件,检测到停振
						casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
						CAS_CTL_EVENT_RINGOFF, channelinfop->channelnum );
						
						//设置FXO口到检测来显状态
						xdrvDaaModeControl( (XDRV_DAA *)channelinfop->casDriver,
						XDRV_DAA_MODE_ONHOOK_DATA);
						
						channelinfop->substate = 2;	//更新子状态
				else if (channelinfop->substate == 2)	//在检测来显子状态
					if (currentCount >= FXS_CLIDRXEND)	//达到来显接收完成时长
						//设置FXO口到挂机状态
						xdrvDaaModeControl( (XDRV_DAA *)channelinfop->casDriver,
						XDRV_DAA_MODE_ONHOOK);
						
						channelinfop->substate = 3;	//更新子状态
				else if (channelinfop->substate == 3)	//在来显结束子状态
					if (currentCount >=  FXS_RINGEND)	//达来振铃结束时长
						//发送CAS事件,振铃结束
						casGenEvent( callbackp, CAS_CTL_DETECT_EVENT,
						CAS_CTL_EVENT_RINGEND, channelinfop->channelnum );
						
						channelinfop->substate = 0;	//更新子状态
		
		case CAS_CTL_FXS_SEIZED:	//摘机状态
			无
		
		case CAS_CTL_FXS_CLIDRX:	//接收来显状态
			无

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值