cnx = GetCnxStateFromVHD( hapiEvt->handle ); //获取线路对象
switch( hapiEvt->eventId )
case HAPI_CDIS_HDLCDETECT: //检测到V21 HDLC信号
int reason = EPEVTREASON_V21flag;
logEvent = VRG_TRUE;
endptState = GetEndptState( cnx->lineId ); //获取线路对象
EcanProcessStm( endptState, ECANEVT_HDLC ); //回音消除状态机处理
//保存最后传真事件
if ( cnx->dataMode == EPDATAMODE_T38_MUTE )
{
cnx->lastFaxEvent = EPFAX_EVT_HDLC;
}
//上报传真事件,T38模式下只上报一次
if ( ( cnx->dataMode == EPDATAMODE_T38_MUTE ) ||
( cnx->dataMode == EPDATAMODE_T38 ) )
if ( cnx->bNotifyFaxCall == VRG_FALSE )
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_FAX,
&reason, sizeof(reason), -1 );
cnx->bNotifyFaxCall = VRG_TRUE;
else
(*endptConfig.notify)( endptState->endptArchive, -1, EPEVT_FAX, &reason,
sizeof(reason), -1 );
case HAPI_CDIS_DETECT: //传真、MODEM事件被检测到
logEvent = VRG_TRUE;
endptState = GetEndptState( cnx->lineId );
if( hapiEvt->op1 & CDIS_CNG ) //检测到CNG信号
reason = EPEVTREASON_CNG;
//如果设置不关心CNG事件,则设置为空标记,后面将根据这个标记不上报事件
if ( cnx->bCngDetEnabled == VRG_FALSE )
evt = EPEVT_NULL;
else
evt = EPEVT_FAX;
EcanProcessStm(endptState, ECANEVT_CNG); //回音消除状态机处理
if ( cnx->dataMode == EPDATAMODE_T38_MUTE )
cnx->lastFaxEvent = EPFAX_EVT_CNG_INGRESS; //保存最后传真事件
cnx->bNotifyFaxCall = VRG_TRUE; //用于T38模式,控制只上报一次传真事件
else if ( hapiEvt->op1 & CDIS_PHASE_REVERSAL ) //检测到相位反转的应答信号
evt = EPEVT_MODEM;
reason = EPEVTREASON_prANS;
EcanProcessStm(endptState, ECANEVT_PHREV); //回音消除状态机处理
else if ( hapiEvt->op1 & CDIS_V18_DETECT ) //检测到V18信号
if ( hapiEvt->op2.val == CDIS_V18ASCII ) //V18相关的都不清楚
if ( cnx->bBell103Enabled == VRG_FALSE ) // 我们当前没有开启
logEvent = VRG_FALSE;
else
//停止自适应JB
hdspSendCmdAsync( endptState->lineVhdHdl,
HAPI_CODEC_STOP_ADAPT_CMD, HSCMDDATA, 1, 0 );
EcanProcessStm(endptState, ECANEVT_BELL103);//回音消除状态机处理
else
evt = EPEVT_TDD;
EcanProcessStm(endptState, ECANEVT_V18); //回音消除状态机处理
//不同V18声音映射不同V18事件
if( hapiEvt->op2.val == CDIS_V18ASCII )
reason = EPEVTREASON_BELLTONE;
else if( hapiEvt->op2.val == CDIS_V18BAUDOT )
reason = EPEVTREASON_BAUDOT;
else if( hapiEvt->op2.val == CDIS_V18PREAMBLE )
reason = EPEVTREASON_V21tone;
else if( hapiEvt->op2.val == CDIS_V18BAUDOT_SHORT )
reason = EPEVTREASON_BAUDOT_SHORT;
else if ( hapiEvt->op1 & CDIS_CUSTOMTONE_DETECT ) //自定义声音检测到
evt = EPEVT_CUSTOMTONE;
reason = EPEVTREASON_CUSTTONE_INGRESS;
else if ( hapiEvt->op1 & CDIS_MACHINE ) //检测到CED信号
evt = EPEVT_MODEM;
reason = EPEVTREASON_ANS;
EcanProcessStm(endptState, ECANEVT_MACHINE); //回音消除状态机处理
//检测到低声音能量
else if ( hapiEvt->op1 & (CDIS_LOW_ENERGY | CDIS_EXT_LOW_ENERGY) )
EcanProcessStm(endptState, ECANEVT_LOWEN); //回音消除状态机处理
//如果是外部声音低能量,则上报VBD停止事件,否则上报低能量事件
if ( hapiEvt->op1 & CDIS_EXT_LOW_ENERGY )
evt = EPEVT_VBD_STOP;
intData = (int)EVEVTVDBSTOP_EXTLOWENERGY;
else
evt = EPEVT_LOWENERGY;
else if( hapiEvt->op1 & CDIS_BELL103_DETECT ) //BELL103事件,不懂
if ( cnx->bBell103Enabled == VRG_FALSE )
logEvent = VRG_FALSE;
else
停止自适应JB
hdspSendCmdAsync( endptState->lineVhdHdl, HAPI_CODEC_STOP_ADAPT_CMD,
HSCMDDATA, 1, 0 );
EcanProcessStm(endptState, ECANEVT_BELL103); //回音消除状态机处理
//如果这前事件标记不为NULL,是上报等处理
if ( evt != EPEVT_NULL )
//上报事件
data = reason;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, evt, (void *)&data,
sizeof(data), intData );
//如果检测到传真事件,当前是T38模式,则上报VBD停止
if( (evt == EPEVT_FAX) && VRG_DATA_MODE_T38( cnx->dataMode ) )
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_VBD_STOP,
NULL, 0, -1 );
case HAPI_CDIS_EGRESS_DETECT: //外部的传真、MODEM事件被检测到
endptState = GetEndptState( cnx->lineId );
if( hapiEvt->op1 & CDIS_CNG ) //如果是CNG信号
reason = EPEVTREASON_EGRESS_CNG;
evt = (cnx->bCngDetEnabled == VRG_FALSE) ? EPEVT_NULL : EPEVT_FAX;
EcanProcessStm(endptState, ECANEVT_CNG); //回音消除状态机处理
else if ( hapiEvt->op1 & CDIS_PHASE_REVERSAL ) //相位反转信号
evt = EPEVT_MODEM;
reason = EPEVTREASON_EGRESS_prANS;
EcanProcessStm(endptState, ECANEVT_PHREV); //回音消除状态机处理
else if ( hapiEvt->op1 & CDIS_MACHINE ) //检测到CED信号
evt = EPEVT_MODEM;
reason = EPEVTREASON_EGRESS_ANS;
EcanProcessStm(endptState, ECANEVT_MACHINE); //回音消除状态机处理
else if ( hapiEvt->op1 & CDIS_V18_DETECT ) //V18信号,和上面本地类似,这块不懂
if ( hapiEvt->op2.val == CDIS_V18ASCII )
if ( cnx->bBell103Enabled == VRG_FALSE )
logEvent = VRG_FALSE;
else
hdspSendCmdAsync( endptState->lineVhdHdl,
HAPI_CODEC_STOP_ADAPT_CMD, HSCMDDATA, 1, 0 );
EcanProcessStm(endptState, ECANEVT_BELL103);
else
evt = EPEVT_TDD;
if( hapiEvt->op2.val == CDIS_V18BAUDOT_SHORT )
reason = EPEVTREASON_EGRESS_BAUDOT_SHORT;
else if ( hapiEvt->op1 & CDIS_CUSTOMTONE_DETECT ) //检测到自下义声音
evt = EPEVT_CUSTOMTONE;
reason = EPEVTREASON_CUSTTONE_EGRESS;
//检测到低能量
else if ( hapiEvt->op1 & (CDIS_LOW_ENERGY | CDIS_EXT_LOW_ENERGY) )
EcanProcessStm(endptState, ECANEVT_LOWEN); //回音消除状态机处理
//检测到BELL103信号,和上面本地侧类似,不懂BELL103是什么
else if( hapiEvt->op1 & CDIS_BELL103_DETECT )
if ( cnx->bBell103Enabled == VRG_FALSE )
logEvent = VRG_FALSE;
else
hdspSendCmdAsync( endptState->lineVhdHdl,
HAPI_CODEC_STOP_ADAPT_CMD, HSCMDDATA, 1, 0 );
EcanProcessStm(endptState, ECANEVT_BELL103);
//上报事件
if ( evt != EPEVT_NULL )
data = reason;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, evt, (void *)&data,
sizeof(data), intData );
case HAPI_PTE_TONE_ON_EVT: //检测到网络侧DTMF ON按键
endptState = GetEndptState( cnx->lineId ); //获取线路对象
VRG_UINT8 tone = hapiEvt->op2.val & 0xFF;
if ( tone >= HAPI_PTE_DTMFDMAXDGT ) //检测到长按键,上报上长按键事件
(*endptConfig.notify)( endptState->endptArchive, -1, EPEVT_DTMFL, NULL, 0, -1 );
else
//将网络侧DTMF按键转换为本地侧事件
const EPZPTEDIGIT2EPEVTMAP *digitMap = ntDigit2epevtMap;
while(( digitMap->digit != tone ) &&( digitMap->digit != HAPI_PTE_DTMFDDGTERROR ))
digitMap++;
//上报事件,并处理回音消除状态机
if(( digitMap->digit != HAPI_PTE_DTMFDDGTERROR ) && (digitMap->epEvent !=
EPEVT_NULL))
(*endptConfig.notify)( endptState->endptArchive, -1, digitMap->epEvent, NULL, 0,
EPDTMFACT_TONEON);
ClassEvent( endptState, hapiEvt );
//基于资源对象上的INBAND DTMF生成完成指示事件。(有些扩展通道如DECT没有INBAND
// DTMF,需要调用signal命令基于资源对象生成,这里是上报生成后的事件指示。
case HAPI_PTE_TONE_GEN_EVT:
endptState = GetEndptState( cnx->lineId ); ..//获取ENDPT对象
//当线路VHD与资源VHD断开时,并且当前资源对象上没有活动信号音时,才上报
//INBAND DTMF完成事件
if ( (cnx->bSBDisconnect == VRG_TRUE) && (cnx->activeSignal == VRG_FALSE) )
toneGenEvtp = (HAPI_PTE_TONEGENEVT *)hapiEvt->op2.ref;
if (toneGenEvtp->slotNum == 0xFFFF)
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId,
EPEVT_INGRESS_DTMF, NULL, 0, -1 );
else //否则更新RTP 收发模式
cnx->activeSignal = VRG_FALSE;
SetRtpMode( cnx, cnx->mode );
//网络服务类型变更通知事件。
case HAPINET_MODE:
switch (hapiEvt->op1)
//不清楚这三者的差别
case NETMODE_IDLE:
case NETMODE_CALLSETUP:
case NETMODE_DATARELAY:
cnx->vbData.bEnabled = VRG_FALSE; //标记为非VBD
case NETMODE_PACKETVOICE: //开始传送语音数据包
//如果当前开启VBD,则上报VBD停止事件,并告知原因为PAYLOAD切换
if( cnx->vbData.bEnabled == VRG_TRUE )
data = EPEVTREASON_PTSW;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_VBD_STOP,
(void*)&data, sizeof(data), -1 );
//复位VBD标记为否
cnx->vbData.bEnabled = VRG_FALSE;
case NETMODE_FAXRELAY: //开启传送T38
cnx->vbData.bEnabled = VRG_FALSE; //设置VBD开启为否
case NETMODE_VOICEBANDDATA: //开始传送VBD
//通知上层VBD启动事件,并告知原因为PAYLOAD切换
if( cnx->vbData.bEnabled == VRG_FALSE )
data = EPEVTREASON_PTSW;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_VBD_START,
(void *)&data, sizeof(data), -1 );
cnx->vbData.bEnabled = VRG_TRUE; //设置VBD开启
//显示一些语音编解码相关统计信息打印,各种信息不懂
case HAPI_NET_VOICESTATS_EVT:
hdspVhdDisplayVoiceStatsRaw( hapiEvt->handle, hapiEvt->op2.ref );
case HAPI_FAXR_CALLEND_EVT: //T38传真结束事件
// EPEVT_T38_STOP为成功结束
// EPEVT_T38_FAILURE为失败结束
if ( hapiEvt->op2.val & HAPI_FAXR_CALL_SUCCESS )
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_T38_STOP, NULL,
0, -1 );
else
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_T38_FAILURE,
NULL, 0, -1 );
case HAPI_FAXR_V21_PREAMBLE_EVT: //检测到T38 V21前导信号
//如果先前没有检测到CNG或没上报,则这里通知上层检测到T38 FAX事件,原因
//为V21信号
if ( cnx->bNotifyFaxCall == VRG_FALSE )
data = EPEVTREASON_V21flag;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_FAX, (void
*)&data, sizeof(data), -1 );
//如果在T38模式,则上报VBD停止事件,原因为V21信号
if( VRG_DATA_MODE_T38( cnx->dataMode ) )
data = EPEVTREASON_V21flag;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_VBD_STOP, (void
*)&data, sizeof(data), -1 );
case HAPI_FAXR_DEBUGRXTONE_EVT: //检测到T38 CNG或CED声音事件
//上报T38传真事件,原因为CNG
if ( hapiEvt->op1 == HSFAXRCNG )
data = EPEVTREASON_CNG;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_FAX, (void
*)&data, sizeof(data), -1 );
//上报T38 MODEM事件,原因为应答音(注意BCM驱动对于传真的应答事件也
//用MODEM类型来上报)
if ( hapiEvt->op1 == HSFAXRCED )
data = EPEVTREASON_ANS;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_MODEM, (void
*)&data, sizeof(data), -1 );
//这几个事件代码归在一起处理,处理动作仅仅是将logEvent变量改为VRG_TRUE,用于下
//面打印处理。没有功能代码,仅按字面文字意思写一下事件。
case HAPI_CODEC_VOICERATE_EVT: //编码速率改变事件
case HAPINET_VOICERATE: //网络侧编码速率改变事件
case HAPINET_EXCEPTION: //网络侧异常事件
case HAPINET_HEARTBEAT: //网络模块内部心跳事件
case HAPI_NET_FAXRATE_EVT: //网络侧传真速率改变事件
case HAPI_NET_FAXSTATS_EVT: //网络侧传真统计信息
case HAPI_FAXR_BM_DEBUG_EVT: //不清楚
case HAPI_VFAX_NOCARRIER_EVT: //传真无载波事件
case HAPI_RTP_EGRESS_ERROR_EVT: //外部来的RTP错误事件
case HAPI_RTP_EGRESS_SSRC_COLLISION_EVT: //外部来的RTP SSRC字段冲突事件
//这几个事件代码归在一起处理,处理动作仅仅是将logEvent变量改为VRG_FALSE,用于下
//面打印处理。没有功能代码,仅按字面文字意思写一下事件。
case HAPI_RTP_EGRESS_DTMF_EVT: //接收外部的DTMF事件
case HAPI_RTP_INGRESS_RTCP_REPORT_EVT: //发送 RTCP报告事件
case HAPI_RTP_EGRESS_RTCP_REPORT_EVT: //发送RTCP报告事件
case HAPI_RTP_BYE_EVT: //接收RTCP BYE事件
case HAPI_RTP_SID_INGRESS_EVT: //不清楚
case HAPI_RTP_THRESHOLD_MONITOR_EVT: //RTP阀值监控事件
//仅列举了一段示例代码,打印相关监控信息
if (thresholdEvt->monitorID == HAPI_RTP_MONITOR_SL || thresholdEvt->monitorID ==
HAPI_RTP_MONITOR_NL)
VRG_LOG_INFO(( VRG_LOG_MOD_EPT, "CNX %d -- ID: %u, zone %u, current %d,
threshold %d", cnx->lineId, thresholdEvt->monitorID, thresholdEvt->currentZone,
thresholdEvt->currentValue.sValue, thresholdEvt->thresholdValue.sValue));
else
VRG_LOG_INFO(( VRG_LOG_MOD_EPT, "CNX %d -- ID: %u, zone %u, current %u,
threshold %u", cnx->lineId, thresholdEvt->monitorID, thresholdEvt->currentZone,
thresholdEvt->currentValue.uValue, thresholdEvt->thresholdValue.uValue));
//检测到外部媒体从语音切为VBD
case HAPI_CODEC_EGRESS_VOICE_TO_VBD_DETECT_EVT:
//上报VBD开始事件,原因为PAYLOAD切换
data = EPEVTREASON_PTSW;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_VBD_START, (void
*)&data, sizeof(data), -1 );
//检测到外部媒体从VBD切为语音
case HAPI_CODEC_EGRESS_VBD_TO_VOICE_DETECT_EVT:
//上报VBD停止事件,原因为PAYLOAD切换
data = EPEVTREASON_PTSW;
(*endptConfig.notify)( endptState->endptArchive, cnx->cnxId, EPEVT_VBD_STOP, (void
*)&data, sizeof(data), -1 );
//如果之前上面一些事件设置logEvent标记,则触发事件信息打印,及部分事件的简单功
//能调用。上面大部分事件对于logEvent标记的设置,如果需要知道对应事件是否设置
//logEvent标记,则查看代码。
if ( logEvent )
HapiCnxEventPostProcess( hapiEvt );
cnx = GetCnxStateFromVHD( hapiEvt->handle ); //获取资源对象
//根据不同事件ID,填充事件名称evtStr字符串
switch( hapiEvt->eventId )
CASE_PROCESS_HAPI_EVT( HAPINET_MODE )
……
//如果是编码速率改变事件,则记载当前事件描述信息(编解码类型、编码类型
//、VAD类型)
if ( ( hapiEvt->eventId == HAPI_CODEC_VOICERATE_EVT ) || ( hapiEvt->eventId ==
HAPINET_VOICERATE ) )
codecIndex = HAPI_PKT_GETVC( hapiEvt->op1 );
while ( ( pAlgsMap->algsCode != codecIndex ) && ( pAlgsMap->algsCode !=
HAPI_PKT_VC_VOICE_NOCODE ) )
{
pAlgsMap++;
}
vadIndex = hapiEvt->op1 >> VPC_VADSHIFT;
strPrintf( evtDescriptionStr, sizeof( evtDescriptionStr ), "(%s: %s %s)",
hapiEvt->op2.val?"dec":"enc",pAlgsMap->algsName, vadtypes[vadIndex] );
//如果当前事件为检测到HDLC或检测到CNG,并且当时设置为T38静音模式时
//,则标记T38静音标记
if ( ( hapiEvt->eventId == HAPI_CDIS_HDLCDETECT ) ||
(( hapiEvt->eventId == HAPI_CDIS_DETECT ) && ( hapiEvt->op1 & CDIS_CNG )
&& ( cnx->bCngDetEnabled == VRG_TRUE )) )
if ( cnx->dataMode == EPDATAMODE_T38_MUTE )
cnx->bMuteT38 = VRG_TRUE;
//如果从语音切为VBD,则关闭VAD,否则如果从VBD切为语音,则开启VBD
if ( hapiEvt->eventId == HAPINET_MODE )
switch( hapiEvt->op1 )
case NETMODE_VOICEBANDDATA:
if ( cnx->silence )
plcType = vrgEndptRetrievePlcSettings( cnx->codecType );
vad = HAPI_GVAD_MODE_OFF;
cng = cnx->comfortNoise;
if ((cnx->VadMode != vad) ||(cnx->CngMode != cng) ||(cnx->PlcMode !=
plcType))
hdspVhdSetVadCngPlc( cnx->vhdhdl, vad, cng, plcType );
cnx->VadMode = vad;
cnx->CngMode = cng;
cnx->PlcMode = plcType;
case NETMODE_PACKETVOICE:
if ( cnx->vhdMode == NETMODE_VOICEBANDDATA )
if ( cnx->silence )
plcType = vrgEndptRetrievePlcSettings( cnx->codecType );
vad = HAPI_GVAD_MODE_TRANSPARENT;
cng = cnx->comfortNoise;
if ((cnx->VadMode != vad) ||(cnx->CngMode != cng)
||(cnx->PlcMode != plcType))
hdspVhdSetVadCngPlc( cnx->vhdhdl, vad, cng, plcType );
cnx->VadMode = vad;
cnx->CngMode = cng;
cnx->PlcMode = plcType;
//如果事件为RTP外部错误事件,则将事件描述填充为ERROR
if ( hapiEvt->eventId == HAPI_RTP_EGRESS_ERROR_EVT )
if ( hapiEvt->op1 )
strPrintf( evtDescriptionStr, sizeof( evtDescriptionStr ), "ERROR" );
//如果事件为RTP外部SSRC冲突事件,则事件描述填充冲突的SSRC号
if ( hapiEvt->eventId == HAPI_RTP_EGRESS_SSRC_COLLISION_EVT )
strPrintf( evtDescriptionStr, sizeof( evtDescriptionStr ), "SSRC (%d)",
(hapiEvt->op1 << 16)+(hapiEvt->op2.val) );
bosTimeGetMs( &timeStamp ); //获取时间戳
//打印事件信息
VRG_LOG_NOTICE(( VRG_LOG_MOD_EPT, "'%s' (0x%x), cnx:%d, line:%d, hdl:0x%x,
op1:0x%x, op2:0x%x %s ts: %u ", evtStr, hapiEvt->eventId, cnx->cnxId,
cnx->lineId, hapiEvt->handle, hapiEvt->op1, hapiEvt->op2.val, evtDescriptionStr,
timeStamp ));
//释放内存资源
if ( hapiEvt->reqId == HSEVTEXTDATA &&hapiEvt->op2.ref != NULL && hapiEvt->op1 != 0 )
free(hapiEvt->op2.ref);
ENDPT_410_HapiCnxEventProcess
最新推荐文章于 2020-06-29 14:39:51 发布