state = GetEndptState( lineId ); //获取线路对象
if( cnxId != -1 ) //如果当前信号作用于资源对象上
cnx = GetCnxState( cnxId ); //获取资源对象
if (signal == EPSIG_SB_DISCONNECT ) //设置VHD断开控制
//遍历当前线路所有资源对象
for( i=0; i<VRG_ENDPT_CFG_MAX_CNX_PER_ENDPT; i++ )
if (state->cnx[i]->cnxId == cnxId) //查找哪定的资源对象
if (value)
//设置断开标记
cnx->bSBDisconnect = VRG_TRUE;
//更新当前资源VHD与线路VHD及其它资源VHD连接。该函数在
//《ENDPT_410_ProcessVrgEndptCreateConnection.doc》中有注释说明
//,这里不再说明。
UpdateSBMasks( cnx, cnx->mode );
else
//设置连接标记
cnx->bSBDisconnect = VRG_FALSE;
UpdateSBMasks( cnx, cnx->mode );
return (EPSTATUS_SUCCESS);
if (signal == EPSIG_LINE_MODE_CONTROL ) //设置收发等模式按线路进行处理
//遍历当前线路所有资源对象
for( i=0; i<VRG_ENDPT_CFG_MAX_CNX_PER_ENDPT; i++ )
if (state->cnx[i]->cnxId == cnxId)
//标记针对该资源对象设置收发等模式是否按线路级进行处理
if (value)
cnx->cnxModeControlsLineVhd = VRG_TRUE;
else
cnx->cnxModeControlsLineVhd = VRG_FALSE;
return (EPSTATUS_SUCCESS);
//生成一个进展的DTMF按键音。有些扩展对象没有DTMF音功能(如DECT对象),则
//需要人为放DTMF按键音
if (signal == EPSIG_INGRESS_DTMF)
//遍历当前线路所有资源对象
for( i=0; i<VRG_ENDPT_CFG_MAX_CNX_PER_ENDPT; i++ )
if (state->cnx[i]->cnxId == cnxId)
if ( value < HAPI_PTE_DTMFDMAXDGT )
//通知监控模块,当前资源对象处于激活状态
hbUpdatePatientState( state->cnxSignalHBId, HBSTATE_ACTIVE );
//生成进展DTMF音
Provision( state->endptArchive, EPPROV_DtmfDbLevel, &dbLevel );
Provision( state->endptArchive, EPPROV_DtmfPulseTime, &pulseTime );
Provision( state->endptArchive, EPPROV_DTMFSkew, &skew );
hdspDigitOn( state->lineVhdHdl, state->lineId, value, dbLevel, skew,
pulseTime, INGRESS_TONE );
return (EPSTATUS_SUCCESS);
//遍历当前线路所有资源对象
for( i=0; i<VRG_ENDPT_CFG_MAX_CNX_PER_ENDPT; i++ )
if (state->cnx[i]->cnxId == cnxId)
cnx->activeSignal = value; //记载当前资源对象上是否有放信号音
if( value ) //在当前资源对象上放音
//根据信号类型查找声音映射
const EPZTONEMAP *toneMap = epToneMap;
while(( toneMap->event != EPSIG_NULL ) && ( toneMap->event != signal ))
toneMap++;
//查找对应声音属性文件,如果没有找到则使用默认值
if ( EPSTATUS_SUCCESS == Provision( state->endptArchive,
toneMap->provItem, &vrgTone ))
translateTone(&vrgTone, &hdspTonePattern, VRG_FALSE);
pHdspTonePattern = &hdspTonePattern;
else
pHdspTonePattern = NULL;
//通知监控模块,当前资源对象处于激活状态
hbUpdatePatientState( state->cnxSignalHBId, HBSTATE_ACTIVE );
//设置RTP收发模式,用于发向网络侧。该函数在
//《ENDPT_410_ProcessVrgEndptCreateConnection.doc》中有注释说明,这
//里不再说明。
SetRtpMode( state->cnx[i], state->cnx[i]->mode );
//生成进展指定声音
hdspToneOn( state->cnx[i]->vhdhdl, state->lineId, toneMap->tone, 0, 0,
pHdspTonePattern, INGRESS_TONE, VRG_FALSE, endptConfig.country );
else //停止当前资源对象上的声音
//通知监控模块,当前资源对象处于激活状态
hbUpdatePatientState( state->cnxSignalHBId, HBSTATE_ACTIVE );
hdspToneOff( state->cnx[i]->vhdhdl, INGRESS_TONE ); //停止声音
//设置RTP模式该函数在
//《ENDPT_410_ProcessVrgEndptCreateConnection.doc》中有注释说明,这
//里不再说明。
SetRtpMode( state->cnx[i], state->cnx[i]->mode );
//通知监控模块,当前资源对象处于未激活状态
hbUpdatePatientState( state->cnxSignalHBId, HBSTATE_INACTIVE );
//下面的信号处理仅和线路对象有关,上面的信号处理和资源对象有关
switch ( signal )
case EPSIG_SAS_CAS: //需要发送SAS CAS
case EPSIG_SAS_CAS1: //需要发送SAS CAS
case EPSIG_SAS_CAS2: //需要发送SAS CAS
case EPSIG_SAS_CAS3: //需要发送SAS CAS
case EPSIG_SAS_CAS4: //需要发送SAS CAS
case EPSIG_CALLWT: //仅需要发送SAS,即不需要发送来显
case EPSIG_CALLW1: //仅需要发送SAS,即不需要发送来显
case EPSIG_CALLW2: //仅需要发送SAS,即不需要发送来显
case EPSIG_CALLW3: //仅需要发送SAS,即不需要发送来显
case EPSIG_CALLW4: //仅需要发送SAS,即不需要发送来显
if ( value != 0 ) //开启呼叫等待
//获取发送SAS、CAS音延时时间,如果没取到,则callWtgDelay值为0,表示取默
//认值
Provision( state->endptArchive, EPPROV_CallWtgDelay, &callWtgDelay )
callWtgDelay *= 1000;
//获取信号类型对应的声音映射
while(( toneMap->event != EPSIG_NULL ) &&( toneMap->event != signal ))
toneMap++;
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//将来显状态机切为摘机来显类型,准备就绪
classStmReset( &state->classState, CLASSSTM_TYPE_OFFHOOK_CLID );
//查找是否有用户自定义的SAS声音属性文件,没找到则使用默认值
if (( toneMap->provItem != - 1) && ( EPSTATUS_SUCCESS ==
Provision( state->endptArchive, toneMap->provItem, &vrgTone )))
translateTone(&vrgTone, &hdspTonePattern, VRG_TRUE);
state->classState.callWtgInfo.bUseSasProvProfile = VRG_TRUE;
else
state->classState.callWtgInfo.bUseSasProvProfile = VRG_FALSE;
//设置SAS自定义声音属性文件
//设置发送CAS、CAS延时时间
//设置声音类型
//设置FSK参数
//设置DTMF参数
state->classState.callWtgInfo.sasCustomProfile = hdspTonePattern;
state->classState.callWtgInfo.delay = (VRG_UINT16) callWtgDelay;
state->classState.callWtgInfo.profile = toneMap->tone;
Provision(state->endptArchive, EPPROV_CIDFskParms, &fskParmsPlaceHolder[lineId]);
state->classState.fskParmp = &fskParmsPlaceHolder[lineId];
Provision(state->endptArchive,EPPROV_CIDDtmfParms,
&dtmfParmsPlaceHolder[lineId]);
state->classState.dtmfParmp = &dtmfParmsPlaceHolder[lineId];
if ( EPSIG_IS_SAS_CAS( signal ) ) //如果当前信号需要发送SAS及CAS
state->offhookciding = VRG_TRUE; //标记需要上报来显结束事件
//设置一个3秒的定时器,用于异常情况下,将来显状态机恢复到初始状态
//并上报来显完成事件
init_timer(&state->ClassStateTimer);
state->ClassStateTimer.expires = jiffies + 3*HZ;
state->ClassStateTimer.data = state->lineId;
state->ClassStateTimer.function = ResetStmState;
//驱动来显状态机,切换到stateClass2PendingCallid状态
state->classState.callWtgInfo.bUseCasProvProfile = VRG_FALSE;
classStmEventProcess( &state->classState, CLASSSTM_CLID_SAS_CAS,
state->lineId );
else //只需要发送SAS
//驱动来显状态机,切换到stateClass2PendingDelayDone状态,并延时放
//SAS音
state->classState.callWtgInfo.bUseCasProvProfile = VRG_FALSE;
classStmEventProcess( &state->classState, CLASSSTM_CLID_SAS_ONLY,
state->lineId );
else //关闭呼叫等待
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//驱动来显状态机到空闲状态,并停止来显音
classStmEventProcess( &state->classState, CLASSSTM_CLID_SAS_CAS_OFF,
state->lineId );
//如果是SAS、CAS共存的信号,并且当前触发短暂来显信号,则去激活状态
if ( EPSIG_IS_SAS_CAS( signal ) )
if ( state->activeBriefSignal == EPSIG_CALLID )
hbUpdatePatientState( state->signalCallerIdHBId, HBSTATE_INACTIVE );
//通知监控模块,当前线路信号处于去激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//放各种进展声音
case EPSIG_BUSY: //忙音
case EPSIG_CONF: //证实音
case EPSIG_MSGW: //消息等待指示音
case EPSIG_OHWARN: //摘机警示音
case EPSIG_REORDER: //重置音
case EPSIG_DIAL: //拨号音
case EPSIG_RINGBACK: //回铃音
case EPSIG_STUTTER: //急促拨号音
case EPSIG_INTRUSION: //入侵警示音
case EPSIG_CALLCARD: //呼叫卡服务器音
case EPSIG_NETBUSY: //网络业务繁忙警示音
case EPSIG_NETBUSY1: //网络业务繁忙警示音1
case EPSIG_RINGBACK_CUST1: //自定义回铃音
case EPSIG_SPECIAL_DIAL: //特殊拨号音
case EPSIG_SPECIAL_DIAL_TONE: //特殊拨号音
case EPSIG_DISCONNECT: //连接中断警示音
case EPSIG_PAYPHONE_REC: //特定信息指示音
case EPSIG_WARNING: //警示音
if( value ) //需要播放
//查找事件对应声音属性
while(( toneMap->event != EPSIG_NULL ) && toneMap->event != signal )
toneMap++;
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//获取当前声音属性文件,如果没找到则使用默认值
if (( toneMap->provItem != - 1 ) &&
( EPSTATUS_SUCCESS == Provision( state->endptArchive, toneMap->provItem,
&vrgTone )))
translateTone(&vrgTone, &hdspTonePattern, VRG_FALSE);
pHdspTonePattern = &hdspTonePattern;
else
pHdspTonePattern = NULL;
//设置延时发送时间,0表示使用默认值
if ( duration == -1 )
toneDelay = 0;
else
toneDelay = duration;
//DSP放音
hdspToneOn( state->lineVhdHdl, state->lineId, toneMap->tone,
(VRG_UINT16)toneDelay, 0, pHdspTonePattern, EGRESS_TONE, VRG_FALSE,
endptConfig.country );
//如果当前为证实音,则保存为当前短暂信号
if ( signal == EPSIG_CONF )
briefSignal = signal;
//如果当前为特殊播号音,则触发回音消除状态机
if (signal == EPSIG_DIAL || signal == EPSIG_SPECIAL_DIAL ||signal ==
EPSIG_SPECIAL_DIAL_TONE)
EcanProcessStm( state, ECANEVT_DIALTONE_ON );
else //停止放音
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//DSP停止放音
hdspToneOff( state->lineVhdHdl, EGRESS_TONE );
//如果当前为特殊播号音,则触发回音消除状态机
if (signal == EPSIG_DIAL || signal == EPSIG_SPECIAL_DIAL ||signal ==
EPSIG_SPECIAL_DIAL_TONE)
EcanProcessStm( state, ECANEVT_DIALTONE_OFF );
//通知监控模块,当前线路信号处于去激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//暂不关心这几个信号事件,没有实际功能代码,就是上层用户下发一个信号,然后在返回
//给上层用户,告诉上层用户你下发一个信号???
case EPSIG_LOOP_CLOSE:
case EPSIG_LOOP_OPEN:
case EPSIG_NO_BATTERY:
case EPSIG_NORMAL_POLARITY:
case EPSIG_REDUCED_BATTERY:
case EPSIG_REVERSE_POLARITY:
case EPSIG_INIT_RING:
case EPSIG_ENABLE_METERING:
if ( value )
state->signalRep = repetition;
(*endptConfig.notify)( state->endptArchive, -1, signal, NULL, 0, -1 );
case EPSIG_METERING_BURST: //控制DSP产生一个脉冲信号
if( value )
EPPULSESIGFREQUENCY frequency = PULSE_SIGNAL_FREQ_16KHZ; //设置默认频率
//获取脉冲频率
Provision( state->endptArchive, EPPROV_MeteringFrequency, &frequency );
meterPulse.pulseLineHdl = state->endptNum; //线路
meterPulse.pulseDuration = duration; //脉冲持续时间
meterPulse.pulsePeriod = period; //脉冲周期
meterPulse.pulseCount = repetition; //脉冲次数
meterPulse.pulseAmplitude = 1; //脉冲振幅
meterPulse.pulseFrequency = frequency; //脉冲频率
//设置到DSP
hdspSendCmdData( ((state->dspNum << 8) | HAPIRESMAN),
HAPI_RM_CFG_PULSE_SIGNAL_CMD, HSCMDEXTDATA_SYNC, sizeof( meterPulse ),
&meterPulse );
//这些无功能代码,暂不关心
case EPSIG_STEADY_FULL_BATTERY:
case EPSIG_STEADY_LOOP_CLOSE:
case EPSIG_STEADY_LOOP_OPEN:
case EPSIG_STEADY_NO_BATTERY:
case EPSIG_STEADY_NORMAL_POLARITY:
case EPSIG_STEADY_REDUCED_BATTERY:
case EPSIG_STEADY_REVERSED_POLARITY:
VRG_LOG_INFO(( VRG_LOG_MOD_EPT, " vrgEndptSignal: Steady signal" ));
//向本地侧或网络侧发一个DTMF音
case EPSIG_DTMF0:
case EPSIG_DTMF1:
case EPSIG_DTMF2:
case EPSIG_DTMF3:
case EPSIG_DTMF4:
case EPSIG_DTMF5:
case EPSIG_DTMF6:
case EPSIG_DTMF7:
case EPSIG_DTMF8:
case EPSIG_DTMF9:
case EPSIG_DTMFS:
case EPSIG_DTMFH:
case EPSIG_DTMFA:
case EPSIG_DTMFB:
case EPSIG_DTMFC:
case EPSIG_DTMFD:
if( value ) //放音
//获取信号映射声音属性
const EPZSIG2PTEDIGITMAP *dtmfMap = epSig2PteDigitMap;
while(( dtmfMap->signal != EPSIG_NULL ) && ( dtmfMap->signal != signal ))
dtmfMap++;
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//获取发送DTMF声音大小
//获取发送DTMF按下时间
//获取发送DTMF相位角
Provision( state->endptArchive, EPPROV_DtmfDbLevel, &dbLevel );
Provision( state->endptArchive, EPPROV_DtmfPulseTime, &pulseTime );
Provision( state->endptArchive, EPPROV_DTMFSkew, &skew );
//生成不同方向的DTMF按键
if(repetition == 1)
hdspDigitOn( state->lineVhdHdl, state->lineId, dtmfMap->digit, dbLevel, skew, 200, INGRESS_TONE );
else
hdspDigitOn( state->lineVhdHdl, state->lineId, dtmfMap->digit, dbLevel, skew
, pulseTime, EGRESS_TONE );
briefSignal = signal;
else //停止声音
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
hdspDigitOff( state->lineVhdHdl ); //关闭DTMF音
//通知监控模块,当前线路信号处于去激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//来显同振铃
case EPSIG_CALLID_RING0:
case EPSIG_CALLID_RING1:
case EPSIG_CALLID_RING2:
case EPSIG_CALLID_RING3:
case EPSIG_CALLID_RING4:
case EPSIG_CALLID_RING5:
case EPSIG_CALLID_RING6:
case EPSIG_CALLID_RING7:
case EPSIG_CALLID_RINGING:
//判断线路不是DECT类型则触发,因为DECT类型不需要启动一个状态机后发送
//CLID,它可以在任何时候接收来显,在需要CLID时只需要接收一个EPSIG_CALLID
if (state->endptType != EPTYPE_DECT)
if ( value ) //开启振铃
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//获取来显状态机类型
Provision( state->endptArchive, EPPROV_CIDMode, &classStmType );
//获取振铃节奏等属性
GetRingPattern( signal, endptConfig.country, &pattern );
//根据来显状态机类型,初始化来显状态机
classStmReset( &state->classState, classStmType );
//保存振铃属性
state->classState.ringInfo = pattern;
//获取来显参数
Provision( state->endptArchive, EPPROV_CIDFskAfterRing,
&state->classState.fskAfterRing );
Provision( state->endptArchive, EPPROV_CIDRingAfterFSK,
&state->classState.ringAfterFsk );
Provision( state->endptArchive, EPPROV_CIDFskAfterDTAS,
&state->classState.fskAfterDtas );
Provision( state->endptArchive, EPPROV_CIDFskAfterRPAS,
&state->classState.fskAfterRp );
Provision( state->endptArchive, EPPROV_CIDDTASAfterLR,
&state->classState.dtasAfterLr );
Provision( state->endptArchive, EPPROV_CIDSigProtocol,
&state->classState.clidProtocol );
Provision( state->endptArchive, EPPROV_CIDFskParms,
&fskParmsPlaceHolder[lineId]);
state->classState.fskParmp = &fskParmsPlaceHolder[lineId];
Provision( state->endptArchive, EPPROV_CIDDtmfParms,
&dtmfParmsPlaceHolder[lineId]);
state->classState.dtmfParmp = &dtmfParmsPlaceHolder[lineId];
//标记来显不使用profile属性文件
state->classState.callWtgInfo.bUseCasProvProfile = VRG_FALSE;
else //关闭来显同振铃
//通知监控模块,当前线路信号处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//如果是挂机状态,则向来显状态机发送振铃停止事件,则驱动状态机完成
//相关停止发送的动作。
if ( !state->offHook )
classStmEventProcess( &state->classState, CLASSSTM_RING_OFF,
state->lineId );
//通知监控模块,当前线路信号处理未激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//如果之前触于CALLID事号时,这里通知监控模块,CALLERID线路信号已经
//关闭,当前为去激活状态。
if ( state->activeBriefSignal == EPSIG_CALLID )
hbUpdatePatientState( state->signalCallerIdHBId, HBSTATE_INACTIVE );
//来显
case EPSIG_CALLID:
//通知临控模块,CALLERID线路信号已经处于激活状态
hbUpdatePatientState( state->signalCallerIdHBId, HBSTATE_ACTIVE );
//根据摘挂机状态控制准备触发哪种事件
if ( !state->offHook )
event = CLASSSTM_CLID_RING;
else
event = CLASSSTM_CLID_INFO;
//将上层传来的来显字符串分解到指定结构体中
hdspClassParseStr( (char *) value, endptConfig.country, &state->classState.clidInfo );
//如果是DECT线路类型
if (state->endptType == EPTYPE_DECT)
//注释上说对DECT线路类型,只需要触发状态机放SAS、CAS音,不需要通过DSP
//发送CALLID,CALLID由DECT模块发送。
if (event == CLASSSTM_CLID_INFO)
classStmEventProcess( &state->classState, event, state->lineId );
else //非DECT线路类型
//获取FSK、DTMF参数
Provision( state->endptArchive, EPPROV_CIDFskParms, &fskParmsPlaceHolder[lineId]);
globeEndptGetFskType(&fskParmsPlaceHolder[lineId], period);
state->classState.fskParmp = &fskParmsPlaceHolder[lineId];
Provision( state->endptArchive, EPPROV_CIDDtmfParms,
&dtmfParmsPlaceHolder[lineId]);
state->classState.dtmfParmp = &dtmfParmsPlaceHolder[lineId];
//触发状态机进行来显或放SAS音
classStmEventProcess( &state->classState, event, state->lineId );
briefSignal = signal; //记载当前触发的信号
//消息等待指示音
case EPSIG_VMWI:
//通知临控模块,线路信号已经处于激活状态
hbUpdatePatientState( state->signalOnOffHBId, HBSTATE_ACTIVE );
//获取消息等待指示类型
Provision( state->endptArchive, EPPROV_VMWIMode, &vmwiType );
//复位CLASS状态机
classStmReset( &state->classState, vmwiType );
//获取消息等待指示参数
Provision( state->endptArchive, EPPROV_VMWIFskAfterDTAS,
&state->classState.fskAfterDtas );
Provision( state->endptArchive, EPPROV_VMWIFskAfterRPAS,
&state->classState.fskAfterRp );
Provision( state->endptArchive, EPPROV_VMWIDTASAfterLR,
&state->classState.dtasAfterLr );
Provision( state->endptArchive, EPPROV_CIDFskParms, &fskParmsPlaceHolder[lineId]);
state->classState.fskParmp = &fskParmsPlaceHolder[lineId];
Provision( state->endptArchive, EPPROV_CIDDtmfParms, &dtmfParmsPlaceHolder[lineId] );
state->classState.dtmfParmp = &dtmfParmsPlaceHolder[lineId];
Provision( state->endptArchive, EPPROV_VMWIMsgFormat,
&state->classState.vmwiMsgFormat);
Provision( state->endptArchive, EPPROV_VMWISigProtocol,
&state->classState.vmwiProtocol );
//标记不使用profile属性文件
state->classState.callWtgInfo.bUseCasProvProfile = VRG_FALSE;
if ( value == 0 ) //关闭
//触发关闭消息指示事件
state->classState.vmwiType = CLASS_VMWI_DEACTIVATE;
classStmEventProcess( &state->classState, CLASSSTM_VMWI_OFF, state->lineId );
//通知临控模块,线路信号已经处于去激活状态
hbUpdatePatientState( state->signalOnOffHBId, HBSTATE_INACTIVE );
else //开启
//触发开启消息指示事件
state->classState.vmwiType = CLASS_VMWI_ACTIVATE;
classStmEventProcess( &state->classState, CLASSSTM_VMWI_ON, state->lineId );
//极性反转
case EPSIG_REV:
slicDriver = boardHalSlicGetDriver( state->endptNum ); //获取SLIC驱动对象
//调用SLIC回调函数执行极性反转使能开关。
if( slicDriver != NULL )
casCtlSendCommand(CAS_REQ_SLIC_PHASE_REVERSAL_CONTROL,
(VRG_UINT32)slicDriver, value);
//open switch interval功能,不知道怎么翻译,用于语音服务断开控制
case EPSIG_OSI:
//通知临控模块,线路信号已经处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
if ( value )
//根据value来控制SLIC暂时断开服务多长时间
casCtlSupervisoryDisconnect( state->casCtlHandle, (VRG_UINT16) value,
CAS_OSI_DEFAULT );
else
//通知临控模块,线路信号已经处于去激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//模拟环路测试
case EPSIG_ANALOG_LOOPBACK:
requestLoopback(state, value);
//通知临控模块,线路信号已经处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
if (value)
//关闭回声消除
EcanStateSet(state, ECAN_OFF);
//标记正在进行模拟环路测试
state->testMode = TESTMODE_ANALOGLOOPBACK;
else
state->testMode = TESTMODE_NONE;
//设置SLIC模拟环路测试寄存器
boardHalSetAnalogLoopback( lineId, value );
if (!value)
//通知临控模块,线路信号已经处于去激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//保存短信号事件
briefSignal=state->activeBriefSignal;
//TDP线路诊断复位
case EPSIG_LINE_RESET:
//发送TDP线路诊断复位消息,由TDP主任务处理,详见《ENDPT_410_tpdTaskMain》
tpdCtlProcessSignal( TPD_CTL_SIGNAL_LINE_RESET, lineId, VRG_FALSE, -1 );
//进行各种线路诊断测试启动
case EPSIG_DIAGTESTS_PROV_START:
case EPSIG_DIAGTESTS_NOPROV_START:
case EPSIG_DIAGTESTS_PC15_START:
case EPSIG_DIAGTESTS_CALIBRATE_START:
requestTpd(state, signal, value);
state->testMode = TESTMODE_LINEDIAG; //标记测试模式为线路诊断
bActive = (state->offHook) || (state->cnxCnt > 0); //当前线路活动状态
//线路诊断测试请求
mltRequest( state->endptNum, value, bActive );
//根据用户设置测试类型,获取对应TPD控制标记位
translateRequest(portId, testCase);
//附加强制测试标记位
tpdCtl[portId].start |= TPD_CTL_TEST_FORCE;
//触发TDP任务执行对应类型的线路诊断测试,测试完成后通过事件回调报
//给上层。
tpdCtlProcessSignal(TPD_CTL_SIGNAL_NOPROV_TESTS, portId, isLineActive,
tpdCtl[portId].start);
//发送DTMF信号的按下时长
case EPSIG_UPDATE_DTMFPLAYOUT:
//通知临控模块,线路信号已经处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//向DSP进行设置
status = Provision( state->endptArchive, EPPROV_DTMFPlayout, &dtmfPlayout );
if ( status == EPSTATUS_SUCCESS )
hdspSendCmd( state->cnx[PRIMARY_CNX_INDEX]->vhdhdl, HAPINET_PTE_SETREG1,
HSCMDDATA, VRG_OFFSETOF( HAPI_PTE_REGS, minPulseOn ), ( dtmfPlayout << 3 ));
//通知临控模块,线路信号已经处于去激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//从FXO口发起呼叫
case EPSIG_PSTNCALLSETUP:
if (value)
pstnState = GetPstnVrgEndptState(); //获取FXO对象
pstnState->routedFxsLineId = state->lineId; //设置该FXS线路与FXO口相关联
//向PSTN控制任务发送呼叫事件
evt.hsxdevhdl = pstnState->pstnVhdHdl;
evt.hsxevt = PSTN_CTL_EVT_CALL_SETUP;
evt.hsxop1 = pstnState->lineId;
evt.hsxop2.ref = (char*)value;
pstnCtlSendEvent( &evt );
//从FXO口发起呼叫,透传Diall Tone
case EPSIG_PSTNCALLSETUP_CONNECTONLY:
if (value)
pstnState = GetPstnVrgEndptState(); //获取FXO对象
pstnState->routedFxsLineId = state->lineId; //设置该FXS线路与FXO口相关联
//向PSTN控制任务发送呼叫事件
evt.hsxdevhdl = pstnState->pstnVhdHdl;
evt.hsxevt = PSTN_CTL_EVT_CALL_SETUP;
evt.hsxop1 = pstnState->lineId;
evt.hsxop2.ref = PSTN_CONNECTONLY_DLSTRNG;
pstnCtlSendEvent( &evt )
//触发FXO口接机、应答
case EPSIG_OFFHOOK:
case EPSIG_ANSWER:
if (value)
pstnState = GetPstnVrgEndptState(); //获取FXO对象
//如果没有指明禁止触发线路侧信号
if( value != PSTN_CTL_DO_NOT_SIGNAL_LINE )
//控制FXO口芯片切到摘机模式,并上报线路摘机事件
casCtlSetStateFXS( pstnState->casCtlHandle, CAS_CTL_FXS_SEIZED );
//给PSTN控制任务发送摘机事件
pstnEvt.hsxdevhdl = pstnState->pstnVhdHdl;
pstnEvt.hsxevt = PSTN_CTL_EVT_OFFHOOK;
pstnEvt.hsxop1 = 0;
pstnEvt.hsxop2.ref = NULL;
pstnCtlSendEvent( &pstnEvt );
//关闭FSK来显检测
enableFskClidRx( VRG_FALSE, pstnState->pstnVhdHdl );
if( signal == EPSIG_ANSWER ) //如果控制应答
if ( pstnState->isFxsFxoCnxEstablished == VRG_FALSE ) //如果还没关联FXS口
pstnState->routedFxsLineId = state->lineId; //进行FXS口与FXO口关联
//将FXO口VHD对象与FXS口VHD对象连接
ConnectSB( pstnState->lineId, pstnState->routedFxsLineId );
pstnState->isFxsFxoCnxEstablished = VRG_TRUE; //标记已经关联
//设置检测摘机来显服务
classRxConfigure( pstnState->pstnVhdHdl, CLASS_MSG_OFFHOOK_CLID,
endptConfig.country )
//开启FXO口LED指示灯
xdrvLedCtrl(pstnState->lineId, 1);
if( value == PSTN_CTL_3_WAY_CONFERENCE ) //三方通话
//将FXO口VHD对象与当前线路的资源VHD对象相连
hdspRmSwitchBoardConnect( cnx->vhdhdl, HAPI_SWB_BOS,
pstnState->lineVhdHdl, HAPI_SWB_TOS, HAPI_SWB_DUPLEX,
VRG_TRUE );
pstnState->confCnxVhdHdl = cnx->vhdhdl; //记载当前会议VHD
pstnState->offHook = VRG_TRUE; //标记已经摘机
//触发FXO口挂机
case EPSIG_ONHOOK:
if (value)
pstnState = GetPstnVrgEndptState(); //获取PSTN对象
switch( value )
case PSTN_CTL_DO_NOT_DISCONNECT_PRIMARY:
case PSTN_CTL_3_WAY_CONFERENCE:
//如果之前有三方会议,则断开PSTN线路VHD与FXS资源VHD连接
if( pstnState->confCnxVhdHdl != 0x00 )
hdspRmSwitchBoardConnect( pstnState->confCnxVhdHdl, HAPI_SWB_BOS,
pstnState->lineVhdHdl, HAPI_SWB_TOS, HAPI_SWB_DUPLEX, VRG_FALSE );
pstnState->confCnxVhdHdl = 0x00;
case PSTN_CTL_DO_NOT_SIGNAL_LINE:
//什么都不做
default:
//控制FXO芯片挂机状态,并上报挂机事件
casCtlSetStateFXS( pstnState->casCtlHandle, CAS_CTL_FXS_RELEASED );
//给PSTN控制任务发送挂机事件
pstnEvt.hsxdevhdl = pstnState->pstnVhdHdl;
pstnEvt.hsxevt = PSTN_CTL_EVT_ONHOOK;
pstnEvt.hsxop1 = 0;
pstnEvt.hsxop2.ref = NULL;
pstnCtlSendEvent( &pstnEvt );
//如果先前配置FXS来显检测,则开启
Provision( state->endptArchive, EPPROV_CIDSigProtocol, &clidType );
if ( clidType == EPCLIDTYPE_FSK )
enableFskClidRx(VRG_TRUE, pstnState->pstnVhdHdl);
//如果有关联的FXS口,并且没有设置不能断开
if( pstnState->isFxsFxoCnxEstablished == VRG_TRUE &&value !=
PSTN_CTL_DO_NOT_DISCONNECT_PRIMARY )
//断开FXS线路VHD对象与PSTN线路VHD对象
DisconnectSB( state->lineId, pstnState->lineId );
//复位标记
pstnState->routedFxsLineId = -1;
pstnState->isFxsFxoCnxEstablished = VRG_FALSE;
//设置检测挂机来显服务
classRxConfigure( pstnState->pstnVhdHdl, CLASS_MSG_ONHOOK_CLID,
endptConfig.country );
xdrvLedCtrl(pstnState->lineId, 0); //关闭FXO口LED显示
pstnState->offHook = VRG_FALSE; //标记挂机
//设置DSP发送增益
case EPSIG_TXGAIN:
int gain = (int)value + 1;
state->txGain = gain;
setTxGain(state, gain);
//设置DSP接收增益
case EPSIG_RXGAIN:
int gain = (int)value + 1;
state->rxGain = gain;
setRxGain(state, gain);
//设置SLIC升压环路(不懂)
case EPSIG_BOOSTED_LOOP_CURRENT:
//通知临控模块,线路信号已经处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//获取SLIC驱动对象
slicDriver = boardHalSlicGetDriver( state->endptNum );
//设置SLIC升压环路
if (value)
casCtlSendCommand(CAS_REQ_SLIC_BOOTED_LOOP_CURRENT,
(VRG_UINT32)slicDriver, VRG_TRUE);
else
casCtlSendCommand(CAS_REQ_SLIC_BOOTED_LOOP_CURRENT,
(VRG_UINT32)slicDriver, VRG_FALSE);
//通知临控模块,线路信号已经处于去激活状态
if (!value)
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
//设置SLIC振铃参数
case EPSIG_RING_WAVEFORM:
SetRingParams(state);
//设置SLIC使能
case EPSIG_ADMIN_STATUS:
if (value)
casState = CAS_CTL_FXO_IDLE; //空闲模式
bEnable = VRG_TRUE;
else
casState = CAS_CTL_FXO_SERVICEDENIED; //服务冻结模式
bEnable = VRG_FALSE;
if (state->testMode != TESTMODE_LINEDIAG ) //非线路诊断才能执行
//设置SLIC驱动对应使能状态
casCtlSetState( state->casCtlHandle, casState );
casCtlSetStateGenEvent(state->casCtlHandle, casState, 0 );
switch (state)
case CAS_CTL_FXO_SERVICEDENIED:
actionState=CASBITS_LCFO|FXOBITS_SERVICEDENIED |CASEVENT_LCFO;
case CAS_CTL_FXO_IDLE:
actionState = CASBITS_LCF | FXOBITS_IDLE | CASEVENT_LCF;
case CAS_CTL_FXO_ALERTING_RING:
actionState = CASBITS_RINGING | FXOBITS_ALERTING | CASEVENT_LCF;
case CAS_CTL_FXO_ALERTING_OHT:
actionState = CASBITS_LCF | FXOBITS_ALERTING | CASEVENT_LCF;
case CAS_CTL_FXO_ALERTING_OHTR:
actionState = CASBITS_RLCF | FXOBITS_ALERTING | CASEVENT_RLCF;
case CAS_CTL_FXO_ADDRESSING:
actionState = CASBITS_LCF | FXOBITS_ADDRESSING | CASEVENT_LCF;
case CAS_CTL_FXO_ACTIVE:
actionState = CASBITS_LCF | FXOBITS_ACTIVE | CASEVENT_LCF;
casAction( idx, actionState );
casprofile.casstm.state[0].stateinfo =
( actionState & ~( CAS_NEXTBITS_MASK )) | CAS_ENDING_STATE;
casprofile.casstm.state[0].duration = 2;
casprofile.index = idx;
casCmdData( idx, CAS_STATECTL, CAS_REQ_NONE, sizeof(casprofile),
&casprofile);
bosSleep( 100 );
//设置高压生成控制块使能
boardHalSlicEnable( state->endptNum, bEnable );
boardHalSlicEnableApm( lineId, enableSlic );
boardHalSlicEnable9530(lineId, enableSlic);
pDev = (XDRV_SLIC*)&(gSlicDriver[lineId]);
if (enableSlic)
xdrvSlicModeControl(pDev, XDRV_SLIC_MODE_STANDBY);
if ( !hvg6816IsEnabled( lineId ) )
hvg6816Start( lineId );
else
xdrvSlicModeControl(pDev, XDRV_SLIC_MODE_LCFO);
hvg6816Stop(lineId);
// FXO口芯片去初始化
case EPSIG_DAA_DISABLE:
//FXO口芯片去初始化,在《ENDPT_410_endpoint_cleanup.doc》中有详细流程说明
boardHalDaaDeinit();
// FXO口芯片初始化
case EPSIG_DAA_ENABLE:
//FXO口芯片初始化,在《ENDPT_410_DoVrgEndptInit.doc》中有详细流程说明
boardHalDaaInit( endptConfig.country );
//向线路侧生成带内的DTMF按键音
case EPSIG_INGRESS_DTMF:
//在该线路上查找一个可用的资源对象
for( i=0; i < VRG_ENDPT_CFG_MAX_CNX_PER_ENDPT; i++ )
if ( state->cnx[i] != NULL )
if ((state->cnx[i]->cnxId != CNX_UNUSED) && (state->cnx[i]->cnxId != CNX_IDLE))
//获取要生成DTMF相关的属性值(能量值、按键时长、初始相位角)
globeEndptGetDefault(endptConfig.country, EPGLOBE_ID_DtmfDbLevel, -1,
&dbLevel);
globeEndptGetDefault(endptConfig.country, EPGLOBE_ID_DtmfPulseTime, -1,
&pulseTime);
Provision( state->endptArchive, EPPROV_DTMFSkew, &skew );
//向DSP发送DTMF按键生成操作
hdspDigitOn( state->lineVhdHdl, state->lineId, digitMap->digit, dbLevel, skew,
pulseTime, INGRESS_TONE );
//如果该FXS口与FXO口已经通道连接,则向PSTN侧生成DTMF按键音
pstnState = GetPstnVrgEndptState();
if ((pstnState->routedFxsLineId == state->lineId) &&
( pstnState->isFxsFxoCnxEstablished == VRG_TRUE ))
globeEndptGetDefault(endptConfig.country, EPGLOBE_ID_DtmfDbLevel, -1, &dbLevel);
globeEndptGetDefault(endptConfig.country, EPGLOBE_ID_DtmfPulseTime, -1,
&pulseTime);
Provision( pstnState->endptArchive, EPPROV_DTMFSkew, &skew );
hdspDigitOn( pstnState->lineVhdHdl, pstnState->lineId, digitMap->digit, dbLevel, skew
, pulseTime, EGRESS_TONE );
default:
//节奏振铃信号
if (( signal >= EPSIG_CADENCE_RING_BASE ) && ( signal <= EPSIG_CADENCE_RING_MAX ) )
if ( value ) //开启振铃
//通知临控模块,线路信号已经处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
//获取振铃节奏属性
GetRingPattern( signal, endptConfig.country, &pattern );
//根据振铃属性生成对应振铃CAS状态序列,由CAS主循环任务触发节奏振铃
//功能执行
casCtlRingProfileOn( state->casCtlHandle, &pattern, VRG_TRUE );
profileRingOn( idx, pattern );
else
//通知临控模块,线路信号已经处于激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_ACTIVE );
if( ! state->offHook )
casCtlRingOff( state->casCtlHandle, VRG_FALSE );
//设置SLIC为IDEL状态
casAction( idx, CASBITS_LCF | FXOBITS_IDLE | CASEVENT_LCF );
//通知临控模块,线路信号已经处于去激活状态
hbUpdatePatientState( state->signalHBId, HBSTATE_INACTIVE );
state->activeBriefSignal = briefSignal; //保存部分短信号事件
ENDPT_410_ProcessVrgEndptSignal
最新推荐文章于 2018-06-07 14:36:14 发布