state = &vrgEndpt[physId]; //获取线路对象
//根据线路类型设置线路对象类型属性,当前只关心FXS
if (boardHalIsSlic(lineId))
state->endptType = EPTYPE_FXS;
endptState->endptFuncs = &gVrgEndptFuncs; //ENDPT相关函数集,所有主功能函数处理
endptState->lineId = lineId;
endptState->endptType = state->endptType;
state->endptArchive = (ENDPT_STATE *) endptState;
//向监控模块拖管5个线路级病人
hbRegisterPatient( HBSTATE_INACTIVE, HBPATIENT_TYPE_HOOKSTATE,
lineId, &state->hookStateHBId );
hbRegisterPatient( HBSTATE_INACTIVE, HBPATIENT_TYPE_OOSIGNAL,
lineId, &state->signalOnOffHBId );
hbRegisterPatient( HBSTATE_INACTIVE, HBPATIENT_TYPE_CALLERID,
lineId, &state->signalCallerIdHBId );
hbRegisterPatient( HBSTATE_INACTIVE, HBPATIENT_TYPE_SIGNAL,
lineId, &state->signalHBId );
hbRegisterPatient( HBSTATE_INACTIVE, HBPATIENT_TYPE_CNXSIGNAL,
lineId, &state->cnxSignalHBId );
//初始化
state->isLineUsed = VRG_TRUE;
state->lineId = lineId;
state->endptNum = physId;
state->cnx[PRIMARY_CNX_INDEX] = 0;
state->activeBriefSignal = EPSIG_NULL;
//创建线路通道并使能
InitVhds( state );
//获取检测DTMF不同细节参数区域值、DTMF最小能量检测、进展音能量的设置值
Provision(state->endptArchive, EPPROV_PteDetectAdmin, &pteAdmin);
Provision(state->endptArchive, EPPROV_PteMinDetectPower, &minDetectPower);
Provision(state->endptArchive, EPPROV_PveEgressVolume, &pveEgressVolume);
//挂载DSP相关ENDPT回调,如按键音检测等在这里上报,最终该回调将事件传放事
//件处理队列中,由事件处理队列任务来处理,详见《HapiEndptEventProcess》
endptVhdCallback = EndptVhdEventCallback;
// 根据线路类型向DSP申请不同类型通道创建,这里只关注FXS
hdspVhdOpen( HAPI_LINE_ECAN_VHD, endptVhdCallback, state->dspNum,
pteAdmin, minDetectPower, pveEgressVolume,
&(state->lineVhdHdl) );
//校正DTMF最小能力值检测
pteMinDetectPower = hdspVhdAdjustIngressPowerLevel( pteMinDetectPower*10 ) / 10;
//向DSP申请创建一个LINE_ECAN类型的VHD
*vhdhdl = hapiOpen( vhdType, callbackp, dspNum )
//开启PTE服务及DTMF按键事件上报
hdspSendCmd( *vhdhdl, HAPI_PTE_ENABLE_CMD, HSCMDDATA, VRG_TRUE,
HAPI_PTE_MODE_DIG_EVT | HAPI_PTE_DTMF )
//开启长按键事件上报
filterRegs.filterControl = ( HAPI_PTE_FILTER_TYPE_PERMANENT |
HAPI_PTE_FILTER_OFF_TO_HOST );
filterRegs.filterDigit = 0xFFFF;
filterRegs.filterLongDigit = 0xFFFF;
filterRegs.longDetectTime = 20;
hdspSendCmdDataAsync( *vhdhdl, HAPI_PTE_FILTER_CMD, HSCMDEXTDATA_ASYNC,
sizeof(HAPI_PTE_FILTER), &filterRegs )
//设置检测DTMF不同细节参数区域及DTMF最小能量检测值
hdspSendCmd( *vhdhdl, HAPI_PTE_SETREG1_CMD, HSCMDDATA,
VRG_OFFSETOF(HAPI_PTE_REGS, detectAdmin), pteDetectAdmin )
hdspSendCmd( *vhdhdl, HAPI_PTE_SETREG1_CMD, HSCMDDATA,
VRG_OFFSETOF(HAPI_PTE_REGS, minDetectPower), pteMinDetectPower )
//分别获取各参数设置值
//最小FLASH时间
//最大FLASH时间
//脉冲最小BREAK时间
//脉冲最大BREAK时间
//脉冲一个键生成时间
//脉冲最大一个键生成时间
//脉冲两个键之间空闲时间
//最小R键时间
//最大R键时间
Provision( state->endptArchive, EPPROV_MinHookFlash, &fxoParms.minHookFlash );
Provision( state->endptArchive, EPPROV_MaxHookFlash, &fxoParms.maxHookFlash );
Provision( state->endptArchive, EPPROV_PlsDlMinBreakTime, &fxoParms.pulseMinBreak );
Provision( state->endptArchive, EPPROV_PlsDlMaxBreakTime, &fxoParms.pulseMaxBreak );
Provision( state->endptArchive, EPPROV_PlsDlMinMakeTime, &fxoParms.pulseMinMake );
Provision( state->endptArchive, EPPROV_PlsDlMaxMakeTime, &maxMakeMsec );
Provision( state->endptArchive, EPPROV_PlsDlInterdigitTime, &interDigitMsec );
Provision( state->endptArchive, EPPROV_MinRKey, &fxoParms.minRKey);
Provision( state->endptArchive, EPPROV_MaxRKey, &fxoParms.maxRKey);
//自动计算脉冲一个键最大生成时间
fxoParms.pulseMaxMake = ( maxMakeMsec + interDigitMsec ) / 2;
//控制FXO口连接/断开的周期时间
Provision( state->endptArchive, EPPROV_MinConnect, &fxoParms.minConnect );
Provision( state->endptArchive, EPPROV_MinDisconnect, &fxoParms.minDisconnect );
//一个和脉冲相关,一个和挂机相关
fxoParms.minWink = CAS_CTL_DEFAULT_FXO_MINMAKE_MSEC;
fxoParms.minPostWink = CAS_CTL_DEFAULT_FXO_POSTWINK_MSEC;
//最小的HOOK状态改变时间
fxoParms.earlyActiveHookInterval = (fxoParms.pulseMinMake < fxoParms.pulseMinBreak) ?
fxoParms.pulseMinMake : fxoParms.pulseMinBreak;
//HOOK状态改变延时时间
fxoParms.delayActiveHookInterval = 100;
if ( state->endptType == EPTYPE_FXS )
channelType = CAS_TYPE_FXO; //在CAS控制模块,FXS与FXO口反向的
//获取CAS驱动对象,在DoVrgEndptInit中已经创建
casDriver = (XDRV_CAS *)boardHalCasGetDriver( state->endptNum );
//开启CAS线路
casCtlEndptInit( channelType, casDriver, &state->casCtlHandle, &fxoParms, NULL )
//分配一个CAS服务对象,并把句柄传回给vrgEndpt[i]. casCtlHandle中,以便
//后续方便使用
for( idx = 0; idx < CAS_CTL_CFG_NUM_ENDPTS; idx++ )
if ( !casState.service[ idx ].inUse )
casState.service[ idx ].inUse = VRG_TRUE;
*handle = (CAS_CTL_HANDLE) idx;
Break;
//配置CAS线路
// casState.service[idx].localmem.channelinfo.castype = CAS_TYPE_FXO
//casState.service[idx].localmem.channelinfo.channelnum = idx
//casState.service[idx].localmem.localp->channelinfo.state = FXOBITS_IDLE
//casState.service[idx].localmem.channelinfo.substate = FXO_STARTUP_IDLE;
//casState.service[idx].localmem.channelinfo.statechange = VRG_FALSE;
casCmdAsync( idx, CAS_CONFIG, CAS_REQ_NONE, channelType, idx );
casState.service[idx].localmem.channelinfo.casDriver = casDriver;
casState.service[idx].localmem.channelinfo.casCallback = casCallback; //NULL
casState.service[idx].localmem.channelinfo.earlyOffState = 1;
casState.service[idx].localmem.channelinfo.earlyOnState = 1;
casState.service[idx].localmem.channelinfo.delayOffState = 1;
casState.service[idx].localmem.channelinfo.delayOnState = 1;
//配置FXO口参数
// casState.service[idx].localmem. channelinfo.fxoParms = fxoParms
casCmdData( idx, CAS_CONFIG_FXO, CAS_REQ_NONE, sizeof(CAS_CTL_FXO_PARMS), fxoParms );
//开启CAS服务
// casState.service[idx].localmem. channelinfo. Profilep = NULL
// casState.service[idx].localmem. status |= CAS_ENABLED;
casCmdAsync( idx, CAS_ENABLE, CAS_REQ_NONE, VRG_TRUE, 0 );
if ( state->endptType == EPTYPE_FXS ) //如果FXS口
//设置振铃参数
SetRingParams(state);
slicDriver = boardHalSlicGetDriver( state->endptNum ); //获以SLIC驱动对象
apmDriver = boardHalApmGetDriver( state->dspNum ); //获取APM驱动对象
ProvisionRingParams(state, ringParam);
//默认20HZ
Provision(state->endptArchive,EPPROV_PowerRingFrequency,
&(ringParam->frequency) );
//默认正弦波
Provision( state->endptArchive, EPPROV_RingWaveform,
&(ringParam->waveshape) );
//默认50V
Provision( state->endptArchive, EPPROV_RingVoltage, &(ringParam->voltage) );
//默认高升振铃关闭
Provision( state->endptArchive, EPPROV_HighVring, &ringHighVoltage );
//默认振铃偏移量校准因素 0
Provision( state->endptArchive, EPPROV_RingOffsetCal, &(ringParam->offsetCal) )
parms.drvHdl = (void*)apmDriver;
parms.arguments[0] = ringParam->frequency; //20
parms.arguments[1] = ringParam->waveshape; //正弦
parms.arguments[2] = ringParam->voltage; //50
parms.arguments[3] = ringParam->offset; //0
parms.arguments[4] = ringParam->offsetCal; //0
//调用APM驱动函数apm6816SetRingParms设置振铃参数,主要是设置APM
//模块相关寄存器,很细节目前还不懂
casCtlSendExtendedCommand(CAS_REQ_APM_SET_RING_PARMS,
CAS_CMD_MODE_ASYNC, &parms );
//调用SLIC驱动函数slicSetRingParms设置振铃参数
//pDev->bRingDCoffsetEnabled = XDRV_FALSE;
//pDev->ringVoltage = ringVoltage;
//pDev->ringOffset = ringOffset;
//pDev->ringOffsetCal = ringOffsetCal;
//pDev->ringFrequency = ringFrequency;
//pDev->ringWaveshape = ringWaveshape;
parms.drvHdl = (void*)slicDriver;
casCtlSendExtendedCommand( CAS_REQ_SLIC_SET_RING_PARMS,
CAS_CMD_MODE_ASYNC, &parms );
//获取升压环路电路配置(当前值为FALSE)
status = Provision( state->endptArchive, EPPROV_BoostedLoopCurrent, &provItem );
if(provItem == 1)
casCtlSendCommand(CAS_REQ_SLIC_BOOTED_LOOP_CURRENT, (VRG_UINT32)slicDriver, VRG_TRUE);
if(provItem == 2)
casCtlSendCommand(CAS_REQ_SLIC_BOOTED_LOOP_CURRENT, (VRG_UINT32)slicDriver, VRG_TRUE);
//设置模拟环回,当前值为FALSE
status = Provision( state->endptArchive, EPPROV_AnalogLoopback,
&enableAnalogLoopback);
if(enableAnalogLoopback == 1)
EcanStateSet(state, ECAN_OFF);
state->testMode = TESTMODE_ANALOGLOOPBACK;
boardHalSetAnalogLoopback( state->lineId, VRG_TRUE );
else if(enableAnalogLoopback == 2)
state->testMode = TESTMODE_NONE;
boardHalSetAnalogLoopback( state->lineId, VRG_FALSE );
classStmInit( &state->classState, state->casCtlHandle, state->lineVhdHdl, endptConfig.country );
stmMemp->casCtlHandle = casCtlHandle; //CAS控制对象句柄
stmMemp->vhdHdl = vhdhdl; //DSP线路对象
stmMemp->country = country; //国家码
stmMemp->evBlock = VRG_FALSE; //事件阻塞标记
classStmReset( stmMemp, CLASSSTM_TYPE_ONHOOK_RING_CLID );
clidState->vhdHdl = vhdHdl;
clidState->casCtlHandle = casCtlHandle;
clidState->country = country;
clidState->currentStatep = stateClidTxNaIdle; //初始状态
clidState->classType = CLASS_MSG_ONHOOK_CLID; //CLID状态机类型
clidState->idleStatep = clidState->currentStatep; //恢复为IDEL时状态
//设置CAS暂时忽略摘挂机
casCtlIgnoreHookState( casCtlHandle, CAS_IGNOREHOOKSTATE_OFF );
hdspClassEnable( vhdhdl ) //开启来显传送
if( state->endptType == EPTYPE_PSTN ) //如果FXO口类型
//PSTN控制状态初始化
pstnCtlEndptInit( state->pstnVhdHdl )
pstnCtlState.numChannels++;
pstnCtlState.chanState[ pstnCtlState.numChannels - 1 ].state =
PSTN_CTL_CHAN_STATE_IDLE;
pstnCtlState.chanState[ pstnCtlState.numChannels - 1 ].vhdHdl = handle;
//获取FXO口检测来显类型
Provision( state->endptArchive, EPPROV_CIDSigProtocol, &clidType );
if ( clidType == EPCLIDTYPE_DTMF ) //DTMF类型
//DTMF来显相关参数
Provision(state->endptArchive, EPPROV_CIDDtmfParms, &dtmfParmsp);
pstnCtlDTMFClidRxInit( state->country, state->pstnVhdHdl, &dtmfParmsp );
chanState = getChanState( handle ); //获取FXO口线路对象
//复位chanState->dtmfClidRx所有状态信息
resetDTMFClidRxState( &chanState->dtmfClidRx );
chanState->dtmfClidRx.vhdHdl = handle;
chanState->dtmfClidRx.enabled = VRG_TRUE;
//初始化所有相关定时器信息
for( i=0; i < DTMFCLIDRX_MAX_TIMERS; i++ )
switch( i )
case DTMFCLIDRX_DTMF_PAUSE_TIMER:
chanState->dtmfClidRx.stateInfo.timer[i].timeout =
dtmfParmsp->DTMFpauseTimeout;
chanState->dtmfClidRx.stateInfo.timer[i].timeoutEvent |=
DTMFCLIDRX_EVT_DTMF_PAUSE_TIMEOUT;
chanState->dtmfClidRx.stateInfo.timer[i].type =
DTMFCLIDRX_DTMF_PAUSE_TIMER;
case DTMFCLIDRX_SESSION_TIMER:
chanState->dtmfClidRx.stateInfo.timer[i].timeout =
dtmfParmsp->DTMFsessionTimeout;
chanState->dtmfClidRx.stateInfo.timer[i].timeoutEvent |=
DTMFCLIDRX_EVT_SESSION_TIMEOUT;
chanState->dtmfClidRx.stateInfo.timer[i].type =
DTMFCLIDRX_SESSION_TIMER;
case DTMFCLIDRX_RINGAFTERCLID_TIMER:
chanState->dtmfClidRx.stateInfo.timer[i].timeout =
dtmfParmsp->ringAfterClidTimeout;
chanState->dtmfClidRx.stateInfo.timer[i].timeoutEvent |=
DTMFCLIDRX_EVT_RINGAFTERCLID_TIMEOUT;
chanState->dtmfClidRx.stateInfo.timer[i].type =
DTMFCLIDRX_RINGAFTERCLID_TIMER;
//保存DTMF检测相关参数及国家码
chanState->dtmfClidRx.dtmfClidParms =
(PSTN_CTL_DTMF_CLID_PARMS*)malloc(sizeof(PSTN_CTL_DTMF_CLID_PARMS));
memcpy(chanState->dtmfClidRx.dtmfClidParms, dtmfParmsp,
sizeof(CLASS_MSG_DTMF_PARMS));
chanState->dtmfClidRx.country = country;
enableFskClidRx(VRG_FALSE, state->pstnVhdHdl); //关闭FSK来显检测
else
enableFskClidRx(VRG_TRUE, state->pstnVhdHdl); //开启FSK来显检测
if ( state->endptType == EPTYPE_PSTN ) //如果FXO口类型
//来显接收配置
classRxConfigure( state->pstnVhdHdl, CLASS_MSG_ONHOOK_CLID, endptConfig.country )
regs.hsxminseizurelen = 250; //最小的检测时长
regs.hsxminmarklen = 150; //最小的标记时长?
regs.hsxmaxmsglen = 255; //最大的来显消息长度
regs.hsxminrxthreshold = -35; //最小的能量接收阀值
hdspSendCmdData( vhdHdl, HAPI_CLIDRX_SETREGS_CMD, HSCMDEXTDATA_SYNC,
sizeof( HSZCLIDRXREGS ), ®s ); //向DSP设置来显接收参数
if ( state->endptType == EPTYPE_PSTN )
//设置当前FXO通道为挂机控制状态
casCtlSendCommand(CAS_REQ_DAA_MODE_CONTROL, (VRG_UINT32)boardHalDaaGetDriver( state->endptNum ),
XDRV_DAA_MODE_ONHOOK_DATA);
ENDPT_410_ProcessVrgEndptCreate
最新推荐文章于 2014-11-05 11:49:46 发布