📄 callcontrol_a.c
字号:
switch( meChannelStatus[dwChannel] ) {
case eTrunkIdle:
tCcUaMsg.u.tReport.dwPortStatus = 4; // busy
break;
case eTrunkReady:
tCcUaMsg.u.tReport.dwPortStatus = 0; // idle
break;
// case eFxs_ringing:
// tCcUaMsg.u.tReport.dwPortStatus = 2; // ring
// break;
default:
tCcUaMsg.u.tReport.dwPortStatus = 4; // busy
break;
}
if ( memcmp( &(tCcUaMsg.u.tReport), &m_mtReportStatus[dwChannel], sizeof(tReportStatus) ) ) {
m_mdwReportSame[dwChannel] = 0;
vSendMsgToUA( &tCcUaMsg );
m_mtReportStatus[dwChannel] = tCcUaMsg.u.tReport;
} else {
m_mdwReportSame[dwChannel] ++;
if ( m_mdwReportSame[dwChannel] < 2 ) {
vSendMsgToUA( &tCcUaMsg );
}
}
vSetTimer( dwChannel, eT101, mdwTimeoutLength[eT101] );
}
void CCallControl::vReportBill( DWORD dwChannel, eBillType eType )
{
tCC_UA_MSG tCcUaMsg;
DWORD dwTmp;
struct tm *ptSys;
time_t ttCur;
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.hdr.dwCcIdx = 0;
tCcUaMsg.hdr.dwUaIdx = mtFxxAttrib[dwChannel].tCall.dwUaIdx;
if ( eType == eBillStart ) {
tCcUaMsg.hdr.eMsgType = eReportBillStart;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tBillStart );
ttCur = time(0);
ptSys = localtime( &ttCur );
mtFxxAttrib[dwChannel].dwBillSn = ptSys->tm_mday * 1000000 + ptSys->tm_hour * 10000 +
ptSys->tm_min * 100 + ptSys->tm_sec;
tCcUaMsg.u.tBillStart.dwBillSn = mtFxxAttrib[dwChannel].dwBillSn;
tCcUaMsg.u.tBillStart.dwCallee = m_tWebConfig.trunk_out.trunk_out_item[dwChannel].trunk_tel_no;
tCcUaMsg.u.tBillStart.dwCaller = mtFxxAttrib[dwChannel].tCall.tSetup.dwCaller;
tCcUaMsg.u.tBillStart.dwLastCaller = tCcUaMsg.u.tBillStart.dwCaller;
tCcUaMsg.u.tBillStart.mchCallNumber[0] = 0;
} else {
if ( mtFxxAttrib[dwChannel].dwBillSn == 0 ) {
// null command
return;
}
tCcUaMsg.hdr.eMsgType = eReportBillEnd;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tBillEnd );
tCcUaMsg.u.tBillEnd.dwBillSn = mtFxxAttrib[dwChannel].dwBillSn;
tCcUaMsg.u.tBillEnd.dwCallee = m_tWebConfig.trunk_out.trunk_out_item[dwChannel].trunk_tel_no;
if ( mtFxxAttrib[dwChannel].eFxoCallType == eFxoCallout ) {
tCcUaMsg.u.tBillEnd.dwLastCaller = mtFxxAttrib[dwChannel].tCall.tSetup.dwCaller;
if ( mtFxxAttrib[dwChannel].tCall.tSetup.dwCaller == (DWORD)( m_tWebConfig.trunk_out.trunk_out_item[dwChannel].trunk_tel_no ) ) {
tCcUaMsg.u.tBillEnd.dwLastCaller = mtFxxAttrib[dwChannel].tCall.tSetup.dwCallee;
}
memcpy( tCcUaMsg.u.tBillEnd.mchCallNumber, mtFxxAttrib[dwChannel].tCall.mchReceiveNumber,
MAX_TELNO_LEN );
// for( dwTmp = 0; dwTmp < mtFxxAttrib[dwChannel].tCall.dwReceiveNumber; dwTmp ++ ) {
// tCcUaMsg.u.tBillEnd.mchCallNumber[dwTmp] += '0';
// }
if ( tCcUaMsg.u.tBillEnd.mchCallNumber[0] == '9' ) {
for( dwTmp = MAX_SHORT_DTMF_SAVED; dwTmp < mtFxxAttrib[dwChannel].tCall.dwReceiveNumber; dwTmp ++ ) {
tCcUaMsg.u.tBillEnd.mchCallNumber[dwTmp] = 0;
}
}
tCcUaMsg.u.tBillEnd.mchCallNumber[mtFxxAttrib[dwChannel].tCall.dwReceiveNumber] = 0;
} else {
if ( mtFxxAttrib[dwChannel].tCall.tSetup.dwCallee == (DWORD)( m_tWebConfig.trunk_out.trunk_out_item[dwChannel].trunk_tel_no ) ) {
tCcUaMsg.u.tBillEnd.dwLastCaller = mtFxxAttrib[dwChannel].tCall.tSetup.dwCaller;
} else {
tCcUaMsg.u.tBillEnd.dwLastCaller = mtFxxAttrib[dwChannel].tCall.tSetup.dwCallee;
}
memcpy( tCcUaMsg.u.tBillEnd.mchCallNumber, mtFxxAttrib[dwChannel].tCall.tSetup.cDispName,
MAX_TELNO_LEN );
}
}
vSendMsgToUA( &tCcUaMsg );
}
void vReceiveUaMsg( ptCC_UA_MSG ptCcUaMsg )
{
tTraceResultMessage tTrace;
if ( ptCcUaMsg->hdr.dwChannel < 0 || ptCcUaMsg->hdr.dwChannel >= MAX_LINE_NUM ) {
return;
}
if ( ptCcUaMsg->hdr.eMsgType == eCMConnect ) {
if ( gblnPbxEnable ) {
ptCcUaMsg->hdr.dwDirection = 0;
ptCcUaMsg->hdr.dwStatus = (DWORD)-1;
tTrace.eType = ePbxCommand;
tTrace.u.tCcUaMsg = *ptCcUaMsg;
iQXput( &gqxQueueTrace, (UCHAR *)&tTrace );
}
goCC.vReportAll();
return;
}
iQXput( &gqxQueueUaMsg, (UCHAR *)ptCcUaMsg );
}
void CCallControl::vTransferDtmfCode( DWORD dwChannel, DWORD dwCode )
{
DWORD dwIdx;
tCC_UA_MSG tCcUaMsg;
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eDtmfCode;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tDtmfCode );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tDtmfCode.dwDtmfValue = dwCode;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = mtFxxAttrib[dwChannel].tCall.dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
mtFxxAttrib[dwChannel].tCall.dwCallNumberPtr = mtFxxAttrib[dwChannel].tCall.dwCallNumber;
}
void CCallControl::vTransferDtmfCode( DWORD dwChannel )
{
DWORD dwIdx, dwTmp;
tCC_UA_MSG tCcUaMsg;
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
if ( mtFxxAttrib[dwChannel].boolRedialLast && mtFxxAttrib[dwChannel].dwLastDialNumberCounter > 1 ) {
mtFxxAttrib[dwChannel].tCall.dwCallNumberPtr = 0;
memcpy( mtFxxAttrib[dwChannel].tCall.mchCallNumber, mtFxxAttrib[dwChannel].mchLastDialNumber + 1,
mtFxxAttrib[dwChannel].dwLastDialNumberCounter - 1 );
mtFxxAttrib[dwChannel].tCall.dwCallNumber = mtFxxAttrib[dwChannel].dwLastDialNumberCounter - 1;
mtFxxAttrib[dwChannel].boolRedialLast = FALSE;
}
if ( mtFxxAttrib[dwChannel].tCall.dwCallNumber >= MAX_DTMF_SAVED ) {
mtFxxAttrib[dwChannel].tCall.dwCallNumber = MAX_DTMF_SAVED - 1;
}
for( dwTmp = mtFxxAttrib[dwChannel].tCall.dwCallNumberPtr; dwTmp < mtFxxAttrib[dwChannel].tCall.dwCallNumber; dwTmp ++ ) {
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eDtmfCode;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tDtmfCode );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tDtmfCode.dwDtmfValue = mtFxxAttrib[dwChannel].tCall.mchCallNumber[dwTmp];
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = mtFxxAttrib[dwChannel].tCall.dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
}
mtFxxAttrib[dwChannel].tCall.dwCallNumberPtr = mtFxxAttrib[dwChannel].tCall.dwCallNumber;
}
void CCallControl::vChangeCodec( DWORD dwChannel )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
vPutDriver( dwChannel, eACTION_TALK_DENY, 0, 0 );
vPutDriver( dwChannel, eACTION_CHANGE_CODEC, (char *)&( mtFxxAttrib[dwChannel].tCall.dwCodec ), sizeof(DWORD) );
vPutDriver( dwChannel, eACTION_TALK, 0, 0 );
}
eCCStatus CCallControl::eGetStatus( DWORD dwChannel )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return eTrunkIdle;
}
return meChannelStatus[dwChannel];
}
void CCallControl::vEnableDtmfSend( DWORD dwChannel )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
mtFxxAttrib[dwChannel].tCall.boolDtmfTransferReady = TRUE;
}
void CCallControl::vDirectLineCallOver( DWORD dwChannel )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
mtFxxAttrib[dwChannel].boolDirectLine = FALSE;
}
void CCallControl::vSetCodec( DWORD dwChannel, ptCC_UA_MSG ptCcUaMsg )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
vPutDriver( dwChannel, eACTION_TALK_DENY, 0, 0 );
mtFxxAttrib[dwChannel].tCall.dwCodec = ptCcUaMsg->u.tSetCodecType.dwCodec;
vPutDriver( dwChannel, eACTION_CHANGE_CODEC, (char *)&( mtFxxAttrib[dwChannel].tCall.dwCodec ), sizeof(DWORD) );
vPutDriver( dwChannel, eACTION_TALK, 0, 0 );
}
DWORD CCallControl::dwGetCallee( DWORD dwChannel )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return 0;
}
return mtFxxAttrib[dwChannel].tCall.tSetup.dwCallee;
}
DWORD CCallControl::dwGetCaller( DWORD dwChannel )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return 0;
}
return mtFxxAttrib[dwChannel].tCall.tSetup.dwCaller;
}
DWORD CCallControl::dwGetCCIdx( DWORD dwChannel )
{
return 0;
}
// pchBuf: [out] Buffer containing the data of channels
// return the total number of data in buffer
DWORD CCallControl::dwGetChannelInfo( char *pchBuf )
{
ptCCInfo ptInfo;
ptInfo = (ptCCInfo)pchBuf;
memcpy( ptInfo->meChannelStatus, meChannelStatus, sizeof(meChannelStatus) );
memcpy( ptInfo->mtFxxAttrib, mtFxxAttrib, sizeof(mtFxxAttrib) );
memcpy( ptInfo->mdwTimeoutLength, mdwTimeoutLength, sizeof(mdwTimeoutLength) );
memcpy( &(ptInfo->tCallidStatData), (char *)&m_tCallidStat, sizeof(m_tCallidStat) );
return sizeof(tCCInfo);
}
// pchBuf: [out] Buffer containing the data of current used
// return the total number of data in buffer
DWORD CCallControl::dwGetDataInfo( char *pchBuf )
{
memcpy( pchBuf, (char *)&m_tWebConfig, sizeof(m_tWebConfig) );
return sizeof(m_tWebConfig);
}
void CCallControl::vUpdateConfiguration( void )
{
int i;
tTrunkVoiceVolume tVoice;
if ( m_tWebConfig.voice.echo_tail == 0 ) {
// disable echo cancel
vPutDriver( 0, eDisableEchoCancel, 0, 0 );
} else {
// enable echo cancel
vPutDriver( 0, eEnableEchoCancel, 0, 0 );
}
for( i = 0; i < MAX_LINE_NUM; i ++ ) {
tVoice.iRx_in[i] = m_tWebConfig.voice.trunk_item[i].rx_in + 0x20;
tVoice.iTx_out[i] = m_tWebConfig.voice.trunk_item[i].tx_out + 0x20;
}
vPutDriver( 0, eUpdateVoiceVolume, (char *)&tVoice, sizeof(tVoice) );
}
void vSetData( void *ptr, int iLength )
{
if ( ptr == NULL ) {
return;
}
printf(" Set Data \n");
memcpy( &( goCC.m_tWebConfig ), ptr, sizeof(goCC.m_tWebConfig) );
goCC.vUpdateConfiguration();
}
void CCallControl::vReportAll()
{
DWORD dwTmp;
for( dwTmp = 0; dwTmp < MAX_LINE_NUM; dwTmp ++ ) {
m_mdwReportSame[dwTmp] = 0;
vReportCCStatus( dwTmp );
}
}
BOOL CCallControl::boolTalk( DWORD dwChannel )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return FALSE;
}
if ( meChannelStatus[dwChannel] == eTrunkConnect ) {
return TRUE;
}
return FALSE;
}
void CCallControl::vRinging( DWORD dwChannel, eFxxMsgType eMsgType, char *pchMsg )
{
tCC_UA_MSG tCcUaMsg;
ptFxxAttrib ptAttrib = &mtFxxAttrib[dwChannel];
char chTmpPara[8];
char chBuffer[MAX_TELNO_LEN];
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
chTmpPara[0] = 0;
if ( m_tWebConfig.trunk_in.trunk_in_item[dwChannel].mode == DISA ) {
// DISA
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eSetup;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tSetup );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tSetup.dwCallee = DISA_RING_GROUP_NO + dwChannel;
ptAttrib->tCall.tSetup.dwCallee = DISA_RING_GROUP_NO + dwChannel;
tCcUaMsg.u.tSetup.dwCaller = ptAttrib->tCall.tSetup.dwCaller;
sprintf( chBuffer, "%s", ptAttrib->tCall.tSetup.cDispName );
chBuffer[MAX_TELNO_LEN - 1] = 0;
strcpy( tCcUaMsg.u.tSetup.cDispName, chBuffer );
tCcUaMsg.hdr.dwCcIdx = 0;
ptAttrib->tCall.dwUaIdx = (DWORD)-1;
tCcUaMsg.hdr.dwUaIdx = (DWORD)-1;
vSendMsgToUA( &tCcUaMsg );
vSetTimer( dwChannel, eT314, mdwTimeoutLength[eT314] );
vChangeCCStatus( dwChannel, eTrunkDisaCalling );
} else {
vSetTimer( dwChannel, eT308, mdwTimeoutLength[eT308] );
// vPutDriver( dwChannel, eCallAnswerRequest, 0, 0 );
vChangeCCStatus( dwChannel, eTrunkAnswer );
}
}
BOOL CCallControl::boolMatchDialPlan( char *pchSrc, int iLen )
{
int i;
dialplan_param_t *ptPlan;
char chTmp[MAX_DIALPLAN_LENGTH * 2];
int j;
if ( iLen > MAX_DIALPLAN_LENGTH ) {
return FALSE;
}
ptPlan = &( m_tWebConfig.dialplan );
for( i = 0; i < ptPlan->dial_plan_num; i ++ ) {
printf( "DIGIT is %s\n", ptPlan->item[i] );
if ( strlen( ptPlan->item[i] ) != iLen ) {
continue;
}
memcpy( chTmp, pchSrc, iLen );
for( j = 0; j < MAX_DIALPLAN_LENGTH; j ++ ) {
if ( ptPlan->item[i][j] == 'x' || ptPlan->item[i][j] == 'X' ) {
chTmp[j] = ptPlan->item[i][j];
}
}
if ( memcmp( chTmp, ptPlan->item[i], iLen ) == 0 ) {
printf( "matched\n" );
return TRUE;
}
}
return FALSE;
}
void CCallControl::vCommonResponse( DWORD dwChannel, eFxxMsgType eMsgType, char *pchMsg )
{
// tCC_UA_MSG tCcUaMsg;
ptFXEVENTMESSAGE ptEvent;
char chBuffer[128];
int iLen = 0;
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
ptEvent = (ptFXEVENTMESSAGE)pchMsg;
}
void vGetHardwareInfo( char *pchBuf )
{
memset( pchBuf, LINE_NULL, sizeof(gmiLineType) );
memcpy( pchBuf, gmiLineType, sizeof(gmiLineType) );
}
void vErrorLog( char* p_ccMessage )
{
char cTemp_1[ 1024 ];
time_t ttCur;
struct tm *tmCur;
FILE *ofLog = fopen( "/root/errlog.dat", "a" );
if ( ofLog == NULL ) {
return;
}
ttCur = time(0);
tmCur = localtime( &ttCur );
sprintf( cTemp_1, "%d/%02d/%02d %02d:%02d:%02d %d==>%s\n\r", tmCur->tm_year, tmCur->tm_mon + 1,
tmCur->tm_mday, tmCur->tm_hour, tmCur->tm_min, tmCur->tm_sec, errno, p_ccMessage
);
fputs( cTemp_1, ofLog );
if ( ftell( ofLog ) >= 100000 ) {
fclose( ofLog );
system( "cp /root/errlog.dat /root/errlog.bak" );
system( "rm -f /root/errlog.dat" );
}
fclose(ofLog);
}
BOOL blnInitCCProc( void )
{
pthread_t tMyThread;
int iRet;
int i;
vInitCCProc();
if ( gblnvInitCCProc == FALSE ) {
printf( "Create vInitCCProc fail\n" );
return FALSE;
}
printf( "Create vInitCCProc success\n" );
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -