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: //接收来显状态
无
ENDPT_410_casTaskMain
最新推荐文章于 2014-11-05 13:30:40 发布