📄 fxocallsetup.c
字号:
//
// Copyright (c) Blueinfosys. All rights reserved.
//
// Module Name: Fxowaitconnect.cpp
//
// Abstract:
//
// Author: Yang Xin
// Date: Feb 13, 2004
// Ver:1.00
//
// Modified by:
// Modified Date:
// Notes:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include "commondef.h"
#include "ccuatype.h"
#include "queue.h"
#include "WebSrv.h"
#include "rtp.h"
#include "sipmessage.h"
#include "commtrace.h"
#include "CallControl.h"
void CCallControl::vFxowaitconnect( DWORD dwChannel, eFxxMsgType eMsgType, char *pchMsg )
{
tCC_UA_MSG tCcUaMsg;
DWORD dwIdx;
char *ptr;
ptCC_UA_MSG ptMsgReq;
ptFXEVENTMESSAGE ptEvent;
ptMyTimerMsg ptTimer;
ptFxxAttrib ptAttrib = &mtFxxAttrib[dwChannel];
ptMsgReq = (ptCC_UA_MSG)pchMsg;
ptEvent = (ptFXEVENTMESSAGE)pchMsg;
ptTimer = (ptMyTimerMsg)pchMsg;
switch( eMsgType ) {
case eMsgFromUa:
switch( ptMsgReq->hdr.eMsgType ) {
case eSetup:
COMMFUNC_V( dwChannel, &tCcUaMsg, ptMsgReq );
break;
case eAlerting:
dwIdx = eFirstcall;
ptAttrib->mtCallInfo[dwIdx].dwUaIdx = ptMsgReq->hdr.dwUaIdx;
ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee = ptMsgReq->u.tAlert.dwCallee;
if ( ptAttrib->mtCallInfo[dwIdx].tSetup.cDispName[0] &&
ptAttrib->mtCallInfo[dwIdx].tSetup.cDispName[1] ) {
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eCallid;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tCallid );
tCcUaMsg.hdr.dwChannel = dwChannel;
memcpy( tCcUaMsg.u.tCallid.cDispName, ptAttrib->mtCallInfo[dwIdx].tSetup.cDispName, MAX_TELNO_LEN * 2 );
if ( ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee == m_tModuleInfo.port.dwTelno[dwChannel] ) {
tCcUaMsg.u.tCallid.iDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller;
} else {
tCcUaMsg.u.tCallid.iDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee;
}
tCcUaMsg.u.tCallid.dwSrcNumber = m_tModuleInfo.port.dwTelno[dwChannel];
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
}
if ( ptAttrib->mtCallInfo[dwIdx].dwDirectCall == 1 ) {
vSetTimer( dwChannel, eT207, mdwTimeoutLength[eT207] );
break;
}
if ( ptMsgReq->u.tAlert.dwLineType == 2
&& m_tModuleInfo.port.dwDirectTel[dwChannel] == 0 ) {
ptAttrib->mtCallInfo[dwIdx].boolFxoCall = TRUE;
}
vSetTimer( dwChannel, eT207, mdwTimeoutLength[eT207] );
break;
case eConnect:
vKillTimer( dwChannel, eT207 );
dwIdx = eFirstcall;
printf( "003KKKKKKKKKKKKKKKKKKKKKKK, %d\n", ptMsgReq->u.tConnect.dwLineType );
if ( ptMsgReq->u.tConnect.dwLineType == 2
&& m_tModuleInfo.port.dwDirectTel[dwChannel] == 0 ) {
ptAttrib->mtCallInfo[dwIdx].boolFxoCall = TRUE;
vKillAllTimer( dwChannel );
vReportBill( dwChannel, eBillEnd );
ptAttrib->dwBillSn = 0;
ptAttrib->eActiveCall = eFirstcall;
RELEASECOMP( dwChannel, &tCcUaMsg, eRls_OnHook );
ptAttrib->mtCallInfo[dwIdx].dwDirectCall = 0;
ptAttrib->mtCallInfo[eFirstcall].tSetup.cDispName[0] = 0;
ptAttrib->mchCallidNumber[0] = 0;
ptAttrib->dwDtmfCallidCounter = 0;
vPutDriver( dwChannel, eACTION_FXO_ONHOOK, NULL, 0 );
vPutDriver( dwChannel, eACTION_IDLE, NULL, 0 );
vSetTimer( dwChannel, eT114, mdwTimeoutLength[eT114] );
vChangeCCStatus( dwChannel, eFxo_end );
break;
}
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eConnectAck;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tConnectAck );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tConnectAck.dwCaller = ptMsgReq->u.tConnect.dwCaller;
tCcUaMsg.u.tConnectAck.dwCallee = ptMsgReq->u.tConnect.dwCallee;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptMsgReq->hdr.dwUaIdx;
ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee = ptMsgReq->u.tConnect.dwCallee;
ptAttrib->mtCallInfo[dwIdx].dwUaIdx = ptMsgReq->hdr.dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
if ( ptAttrib->mtCallInfo[dwIdx].dwDirectCall == 1 ) {
vReportBill( dwChannel, eBillStart );
vPutDriver( dwChannel, eACTION_FXO_OFFHOOK, NULL, 0 );
ptAttrib->mtCallInfo[dwIdx].dwDirectCall = 0;
} else {
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_OFF, NULL, 0 );
}
vSetTimer( dwChannel, eT116, mdwTimeoutLength[eT116] );
#ifdef FXO_CONTROL
vSetTimer( dwChannel, eT119, mdwTimeoutLength[eT119] );
#endif
ptAttrib->dwFxoStatusEnquiryCounter = 0;
vChangeCCStatus( dwChannel, eFxo_talking );
break;
case eRtpSessionOK:
dwIdx = eFirstcall;
ptAttrib->mtCallInfo[dwIdx].boolDtmfTransferReady = TRUE;
break;
case eReleaseComplete:
vKillTimer( dwChannel, eT207 );
dwIdx = eFirstcall;
if ( blnCOMMFUNC_FXO_ACD( dwChannel, &tCcUaMsg, ptMsgReq, dwIdx ) == TRUE ) {
break;
}
if ( ptAttrib->mtCallInfo[dwIdx].dwDirectCall == 1 ) {
vSetTimer( dwChannel, eT112, mdwTimeoutLength[eT112] );
vChangeCCStatus( dwChannel, eFxo_idle );
break;
}
if ( ptAttrib->mtCallInfo[eFirstcall].tSetup.dwCallee ==
ptAttrib->dwAgentNumber &&
ptAttrib->boolAutoAgentService == FALSE ) {
// 不使用电脑自动应答、人工值班台无人应答则挂机
vPutDriver( dwChannel, eACTION_FXO_ONHOOK, NULL, 0 );
vSetTimer( dwChannel, eT114, mdwTimeoutLength[eT114] );
vChangeCCStatus( dwChannel, eFxo_end );
break;
}
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_OFF, NULL, 0 );
switch( ptMsgReq->u.tRlscmplt.eReason ) {
case eRls_Busy:
vPlayVoiceFile( dwChannel, eBusyWelcome );
break;
case eRls_NoAnswer:
case eRls_AcdTimeout:
vPlayVoiceFile( dwChannel, eNoAnsWelcome );
break;
case eRls_Disable:
vPlayVoiceFile( dwChannel, eDisable );
break;
default:
vPlayVoiceFile( dwChannel, eWelcome );
break;
}
if ( ptAttrib->boolAutoAgentService == TRUE ) {
ptAttrib->dwPlayMode = 3;
} else {
if ( ptAttrib->mtCallInfo[eFirstcall].tSetup.dwCallee ==
ptAttrib->dwAgentNumber ) {
ptAttrib->dwPlayMode = 8;
} else {
ptAttrib->dwPlayMode = 7;
}
}
vChangeCCStatus( dwChannel, eFxo_play );
break;
default:
break;
}
break;
case eMsgFromDriver:
printf("fxocallsetup,%d\n",ptEvent->dwEventType);
switch( ptEvent->dwEventType ) {
case eEVENT_FXO_RING_ON:
vSetTimer( dwChannel, eT113, mdwTimeoutLength[eT113] );
if ( ptAttrib->dwDtmfCallidCounter ) {
ptAttrib->mchDtmfCallid[ptAttrib->dwDtmfCallidCounter] = 0;
if ( !ptAttrib->mchCallidNumber[0] ) {
memcpy( ptAttrib->mchCallidNumber, ptAttrib->mchDtmfCallid, MAX_TELNO_LEN );
dwIdx = eFirstcall;
strcpy( ptAttrib->mtCallInfo[dwIdx].tSetup.cDispName, ptAttrib->mchDtmfCallid );
if ( m_tModuleInfo.port.dwDirectTel[dwChannel] ) {
// 直通呼叫
ptAttrib->mtCallInfo[0].dwDirectCall = 1;
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eCallid;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tCallid );
tCcUaMsg.hdr.dwChannel = dwChannel;
memcpy( tCcUaMsg.u.tCallid.cDispName, ptAttrib->mtCallInfo[dwIdx].tSetup.cDispName, MAX_TELNO_LEN * 2 );
dwIdx = eFirstcall;
if ( ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee == m_tModuleInfo.port.dwTelno[dwChannel] ) {
tCcUaMsg.u.tCallid.iDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller;
} else {
tCcUaMsg.u.tCallid.iDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee;
}
tCcUaMsg.u.tCallid.dwSrcNumber = m_tModuleInfo.port.dwTelno[dwChannel];
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
break;
}
}
ptAttrib->dwDtmfCallidCounter = 0;
}
break;
case eEVENT_BUSY_TONE:
vKillTimer( dwChannel, eT207 );
ptAttrib->eActiveCall = eFirstcall;
RELEASECOMP( dwChannel, &tCcUaMsg, eRls_OnHook );
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_OFF, NULL, 0 );
vPutDriver( dwChannel, eACTION_FXO_ONHOOK, NULL, 0 );
vSetTimer( dwChannel, eT114, mdwTimeoutLength[eT114] );
vChangeCCStatus( dwChannel, eFxo_end );
break;
case eEVENT_DTMF_CODE:
if ( m_tModuleInfo.port.dwDirectTel[dwChannel] ) {
if ( ptEvent->chBuffer[0] >= 0 && ptEvent->chBuffer[0] <= 9 ) {
ptAttrib->mchDtmfCallid[ptAttrib->dwDtmfCallidCounter] = ptEvent->chBuffer[0] + '0';
ptAttrib->dwDtmfCallidCounter ++;
}
break;
}
dwIdx = eFirstcall;
ptr = ptAttrib->mtCallInfo[dwIdx].mchCallNumber;
ptr[ptAttrib->mtCallInfo[dwIdx].dwCallNumber++] = ptEvent->chBuffer[0];
if ( ptAttrib->mtCallInfo[dwIdx].dwCallNumber >= MAX_DTMF_SAVED ) {
ptAttrib->mtCallInfo[dwIdx].dwCallNumber = MAX_DTMF_SAVED - 1;
}
// ptAttrib->mtCallInfo[dwIdx].dwCallNumber %= MAX_DTMF_SAVED;
// if ( ptAttrib->dwInputFxsNumber ) { // 汇接
// if ( ( ptr[0] == 0 && ptAttrib->dwInputFxsGrade < INLAND_REMOTE_CALL )
// || ( ptr[0] == 0 && ptr[1] == 0 && ptAttrib->dwInputFxsGrade < OVERSEAS_CALL
// && ptAttrib->mtCallInfo[dwIdx].dwCallNumber > 1 ) ) {
// 长途呼叫必须要有长途权限
// no authorization to start a remote call
// vKillTimer( dwChannel, eT207 );
// ptAttrib->eActiveCall = eFirstcall;
// RELEASECOMP( dwChannel, &tCcUaMsg, eRls_OnHook );
// COMMFUNC_X( dwChannel );
// break;
// }
// }
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 = ptEvent->chBuffer[dwIdx];
// tCcUaMsg.u.tDtmfCode.dwSrcNumber = m_tModuleInfo.port.iTelno[dwChannel];
// if ( ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee == tCcUaMsg.u.tDtmfCode.dwSrcNumber ) {
// tCcUaMsg.u.tDtmfCode.dwDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller;
// } else {
// tCcUaMsg.u.tDtmfCode.dwDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee;
// }
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
break;
case eEVENT_FXO_CALLID_RCV:
printf("fxocallsetup recv callid:%s\n",ptEvent->chBuffer+8);
dwIdx = eFirstcall;
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eCallid;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tCallid );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tCallid.cDispName[0] = '9';
memcpy( tCcUaMsg.u.tCallid.cDispName, ptEvent->chBuffer + 8, MAX_TELNO_LEN * 2 - 1 );
strcpy( (char *)( ptAttrib->mtCallInfo[dwIdx].tSetup.cDispName ), (char *)( ptEvent->chBuffer + 8 ) );
if ( ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee == m_tModuleInfo.port.dwTelno[dwChannel] ) {
tCcUaMsg.u.tCallid.iDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller;
} else {
tCcUaMsg.u.tCallid.iDestNumber = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee;
}
tCcUaMsg.u.tCallid.dwSrcNumber = m_tModuleInfo.port.dwTelno[dwChannel];
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
break;
default:
break;
}
break;
case eMsgFromTimer:
switch( ptTimer->dwTimerType ) {
case eT207:
dwIdx = eFirstcall;
if ( ptAttrib->mtCallInfo[dwIdx].dwDirectCall == 1 ) {
vSetTimer( dwChannel, eT112, mdwTimeoutLength[eT112] );
vChangeCCStatus( dwChannel, eFxo_idle );
break;
}
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_OFF, NULL, 0 );
vPlayVoiceFile( dwChannel, eNoAnsWelcome );
ptAttrib->dwPlayMode = 3;
vChangeCCStatus( dwChannel, eFxo_play );
break;
case eT113:
vKillAllTimer( dwChannel );
// if ( ptAttrib->dwBillSn ) {
vReportBill( dwChannel, eBillEnd );
ptAttrib->dwBillSn = 0;
// }
ptAttrib->eActiveCall = eFirstcall;
RELEASECOMP( dwChannel, &tCcUaMsg, eRls_OnHook );
ptAttrib->mtCallInfo[dwIdx].dwDirectCall = 0;
ptAttrib->mtCallInfo[eFirstcall].tSetup.cDispName[0] = 0;
ptAttrib->mchCallidNumber[0] = 0;
ptAttrib->dwDtmfCallidCounter = 0;
vPutDriver( dwChannel, eACTION_IDLE, NULL, 0 );
vChangeCCStatus( dwChannel, eFxo_idle );
break;
default:
break;
}
break;
default:
break;
}
}
void CCallControl::vFxoconnecting( DWORD dwChannel, eFxxMsgType eMsgType, char *pchMsg )
{
tCC_UA_MSG tCcUaMsg;
DWORD dwIdx;
char *ptr;
char chBuffer[MAX_TELNO_LEN * 4];
ptCC_UA_MSG ptMsgReq;
ptFXEVENTMESSAGE ptEvent;
ptMyTimerMsg ptTimer;
ptFxxAttrib ptAttrib = &mtFxxAttrib[dwChannel];
ptMsgReq = (ptCC_UA_MSG)pchMsg;
ptEvent = (ptFXEVENTMESSAGE)pchMsg;
ptTimer = (ptMyTimerMsg)pchMsg;
switch( eMsgType ) {
case eMsgFromUa:
switch( ptMsgReq->hdr.eMsgType ) {
case eSetup:
if ( ptMsgReq->u.tSetup.boolTransfer == TRUE ) {
// receive a call transfered
// send alerting to UA
// save call information
vKillTimer( dwChannel, eT117 );
dwIdx = eFirstcall;
ptAttrib->mtCallInfo[dwIdx].tSetup = ptMsgReq->u.tSetup;
sprintf( chBuffer, "%ld%s",
ptMsgReq->u.tSetup.dwTransferNumber, ptMsgReq->u.tSetup.cDispName );
chBuffer[MAX_TELNO_LEN * 2 - 1] = 0;
strcpy( ptAttrib->mtCallInfo[dwIdx].tSetup.cDispName, chBuffer );
// save serial number of UA
ptAttrib->mtCallInfo[dwIdx].dwUaIdx = ptMsgReq->hdr.dwUaIdx;
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eConnect;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tConnect );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tConnect.dwCallee = ptMsgReq->u.tSetup.dwCallee;
tCcUaMsg.u.tConnect.dwCaller = ptMsgReq->u.tSetup.dwCaller;
tCcUaMsg.u.tConnect.dwLineType = 2;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptMsgReq->hdr.dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
break;
}
COMMFUNC_V( dwChannel, &tCcUaMsg, ptMsgReq );
break;
case eReleaseComplete:
if ( ptMsgReq->u.tRlscmplt.eReason == eRls_Transfer ) {
// 呼叫转移产生的RleaseComplete消息
vSetTimer( dwChannel, eT117, mdwTimeoutLength[eT117] );
break;
}
vKillTimer( dwChannel, eT208 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -