📄 callcontrol_a.c
字号:
//
// Copyright (c) Blueinfosys. All rights reserved.
//
// Module Name: CallControl.cpp
//
// Abstract:
//
// Author:
// Date: Feb 12, 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 "CallControl.h"
#include "ccuatype.h"
#include "queue.h"
#include "WebSrv.h"
#include "rtp.h"
#include "sipmessage.h"
#include "commtrace.h"
extern int iInitTapi();
extern int iQXget( P_QUEUE_X p_pqQueue, UCHAR *p_ucMsg );
extern int iQXInit( P_QUEUE_X p_pqQueue, UCHAR *p_ucMsg, DWORD *pdwClock, int iUnitLen, int iMaxNumMsg );
extern int iQXput( P_QUEUE_X p_pqQueue, UCHAR *p_ucMsg );
extern int iGetFxxType( int iChannel );
extern void vSignalTrace();
int giAutoTalk = 0;
int gmiLineType[MAX_LINE_NUM];
extern void vCloseDevices( void );
extern BOOL gblnShutdown;
BOOL gblnvSignalTrace = FALSE;
BOOL gblnvPlayandRecordManager = FALSE;
BOOL gblnvThreadSignalProc = FALSE;
BOOL gblnvThreadReadFromDriver = FALSE;
BOOL gblnvThreadReadDataFromDriver = FALSE;
BOOL gblnvInitCCProc = FALSE;
extern QUEUE_X gqxQueueTrace;
extern BOOL gblnPbxEnable;
extern BOOL gblnLayer3Enable;
tCC_UA_MSG gqQueueUaMsg[ MAX_UAMSG_SAVED ];
DWORD gdwQueueUaMsg[ MAX_UAMSG_SAVED ];
QUEUE_X gqxQueueUaMsg;
CCallControl goCC;
extern void vThreadReadFromDriver( void );
extern void vReceiveCCMesg( ptCC_UA_MSG ptCcUaMsg );
extern void vPlayandRecordManager( void );
void vThreadSignalProc( void )
{
tCC_UA_MSG tCcUaMsg;
tTraceResultMessage tTrace;
gblnvThreadSignalProc = TRUE;
printf( "vThreadSignalProc is up\n" );
while( gblnShutdown == FALSE ) {
sem_wait( &( gqxQueueUaMsg.smSemaphore ) );
if ( iQXget( &gqxQueueUaMsg, (BYTE *)&tCcUaMsg ) != 0 ) {
continue;
}
if ( gblnPbxEnable ) {
tTrace.eType = ePbxCommand;
tCcUaMsg.hdr.dwDirection = 0;
tCcUaMsg.hdr.dwStatus = goCC.eGetStatus( tCcUaMsg.hdr.dwChannel );
tTrace.u.tCcUaMsg = tCcUaMsg;
iQXput( &gqxQueueTrace, (UCHAR *)&tTrace );
}
if ( tCcUaMsg.hdr.eMsgType == eSetCodecType ) {
goCC.vSetCodec( tCcUaMsg.hdr.dwChannel, &tCcUaMsg );
continue;
}
if ( tCcUaMsg.hdr.eMsgType == eShutdownMsg ) {
continue;
}
if ( tCcUaMsg.hdr.eMsgType != eTimer ) {
goCC.vCallControl( tCcUaMsg.hdr.dwChannel, eMsgFromUa, (char *)&tCcUaMsg );
} else {
goCC.vCallControl( tCcUaMsg.hdr.dwChannel, eMsgFromTimer, (char *)&( tCcUaMsg.u.tTimerMsg ) );
}
}
gblnvThreadSignalProc = FALSE;
printf( "vThreadSignalProc is down\n" );
}
void vInitCCProc()
{
int iRet;
pthread_t tMyThread;
int i;
if ( iInitTapi() == -1 ) {
return;
}
// To initialize data of CC
goCC.vInitial();
iRet = pthread_create( &tMyThread, NULL, (void*(*)(void*))vPlayandRecordManager, NULL );
i = 0;
while( ( gblnvPlayandRecordManager == FALSE ) && i < MAX_THREAD_WAIT_CIRCLE ) {
i ++;
usleep( MAX_THREAD_WAIT_TIME_PIECE );
}
if ( gblnvPlayandRecordManager == FALSE ) {
printf( "gblnvPlayandRecordManager\n" );
return;
}
iRet = pthread_create( &tMyThread, NULL, (void*(*)(void*))vSignalTrace, NULL );
i = 0;
while( ( gblnvSignalTrace == FALSE ) && i < MAX_THREAD_WAIT_CIRCLE ) {
i ++;
usleep( MAX_THREAD_WAIT_TIME_PIECE );
}
if ( gblnvSignalTrace == FALSE ) {
printf( "gblnvSignalTrace\n" );
return;
}
iRet = pthread_create( &tMyThread, NULL, (void*(*)(void*))vThreadSignalProc, NULL );
i = 0;
while( ( gblnvThreadSignalProc == FALSE ) && i < MAX_THREAD_WAIT_CIRCLE ) {
i ++;
usleep( MAX_THREAD_WAIT_TIME_PIECE );
}
if ( gblnvThreadSignalProc == FALSE ) {
printf( "gblnvThreadSignalProc\n" );
return;
}
iRet = pthread_create( &tMyThread, NULL, (void*(*)(void*))vThreadReadFromDriver, NULL );
i = 0;
while( ( gblnvThreadReadFromDriver == FALSE ) && i < MAX_THREAD_WAIT_CIRCLE ) {
i ++;
usleep( MAX_THREAD_WAIT_TIME_PIECE );
}
if ( gblnvThreadReadFromDriver == FALSE ) {
printf( "gblnvThreadReadFromDriver\n" );
return;
}
gblnvInitCCProc = TRUE;
}
CCallControl::CCallControl()
{
sem_init( &m_smCallControl, 0, 1 );
mdwTimeoutLength[eT301] = 8000; // 8 seconds, waiting for response from controller
mdwTimeoutLength[eT302] = 1500000; // 8 seconds, querying status of trunk periodically
mdwTimeoutLength[eT303] = 8000; // 8 seconds, querying status of trunk periodically
mdwTimeoutLength[eT304] = 8000; // 8 seconds, querying status of trunk periodically
mdwTimeoutLength[eT305] = 8000; // 8 seconds, querying status of trunk periodically
mdwTimeoutLength[eT306] = 8000; // 8 seconds, querying status of trunk periodically
mdwTimeoutLength[eT307] = 8000; // 8 seconds, querying status of trunk periodically
mdwTimeoutLength[eT308] = 8000; // 8 seconds, querying status of trunk periodically
mdwTimeoutLength[eT309] = 5000; // 5 seconds, waiting for dtmf input after play over
mdwTimeoutLength[eT310] = 8000; // 8 seconds, waiting for dtmf codes following first code
mdwTimeoutLength[eT311] = 32000; // 32 seconds, waiting for response from SIP UA
mdwTimeoutLength[eT312] = 60000; // 60 seconds, waiting extension answer
mdwTimeoutLength[eT313] = 8000; // 8 seconds, waiting for response from controller
mdwTimeoutLength[eT314] = 5000; // 5 seconds, waiting for response from SIP UA
mdwTimeoutLength[eT315] = 32000; // 32 seconds, waiting for response from SIP UA ( waiting for connectack )
mdwTimeoutLength[eT316] = 100; // 6 seconds, waiting for callid message from controller
mdwTimeoutLength[eT317] = 180000; // 60 seconds, waiting for the calling success or fail
mdwTimeoutLength[eT101] = 30000; // 30 seconds, report state of trunk to CM
//
// init queues
//
if( iQXInit(
&gqxQueueUaMsg,
(UCHAR *)&gqQueueUaMsg[0],
gdwQueueUaMsg,
sizeof(tCC_UA_MSG),
MAX_UAMSG_SAVED
) != 0
) {
return;
}
memset( (char *)&m_tWebConfig, 0, sizeof(m_tWebConfig) );
DWORD dwTmp;
memset( (char *)&m_tCallidStat, 0, sizeof(m_tCallidStat) );
memset( (char *)m_mtReportStatus, 0xff, sizeof(m_mtReportStatus) );
for( dwTmp = 0; dwTmp < MAX_LINE_NUM; dwTmp ++ ) {
m_mdwReportSame[dwTmp] = 0;
m_tWebConfig.trunk_out.trunk_out_item[dwTmp].trunk_tel_no = START_TRUNK_TEL_NO + dwTmp;
m_tWebConfig.trunk_in.trunk_in_item[dwTmp].mode = AUTO_ATTENDANT;
mtFxxAttrib[dwTmp].boolSessionOK = FALSE;
mtFxxAttrib[dwTmp].tRtpHeader.dwVersion = 2;
mtFxxAttrib[dwTmp].tVoiceHead.iSocket = -1;
}
}
CCallControl::~CCallControl()
{
}
void CCallControl::vInitial()
{
DWORD dwTmp;
memset( mtFxxAttrib, 0, sizeof(mtFxxAttrib) );
for( dwTmp = 0; dwTmp < MAX_LINE_NUM; dwTmp ++ ) {
mtFxxAttrib[dwTmp].tmProc = new CMyTimer( dwTmp );
meChannelStatus[dwTmp] = eTrunkIdle;
// Updating trunk status according to response from Controller.
// vPutDriver( dwTmp, eLineStatusRequest, 0, 0 );
vSetTimer( dwTmp, eT301, mdwTimeoutLength[eT301] + dwTmp * 1000 );
}
}
// channel
// eType, type of timer
// dwTimelength, timeout of timer, in milisec
void CCallControl::vSetTimer( DWORD dwChannel, eChannelTimer eType, DWORD dwTimelength )
{
if ( gblnPbxEnable ) {
tTraceResultMessage tTrace;
tTrace.eType = ePbxCommand;
tTrace.u.tCcUaMsg.hdr.eMsgType = eSetTimer;
tTrace.u.tCcUaMsg.hdr.dwDirection = 1;
tTrace.u.tCcUaMsg.hdr.dwChannel = dwChannel;
tTrace.u.tCcUaMsg.hdr.dwStatus = goCC.eGetStatus( dwChannel );
tTrace.u.tCcUaMsg.u.tTimerMsg.dwChannel = dwChannel;
tTrace.u.tCcUaMsg.u.tTimerMsg.dwTimerType = eType;
iQXput( &gqxQueueTrace, (UCHAR *)&tTrace );
}
dwTimelength *= 1000;
if ( mtFxxAttrib[dwChannel].mdwTimeID[eType] != 0 ) {
mtFxxAttrib[dwChannel].mdwTimeID[eType] =
uSetUFTimer( mtFxxAttrib[dwChannel].mdwTimeID[eType], dwTimelength, eType, mtFxxAttrib[dwChannel].tmProc );
} else {
mtFxxAttrib[dwChannel].mdwTimeID[eType] =
uSetUFTimer( 0, dwTimelength, eType, mtFxxAttrib[dwChannel].tmProc );
}
}
void CCallControl::vKillAllTimer( DWORD dwChannel )
{
DWORD dwTmp;
for( dwTmp = 0; dwTmp < MAX_TIMEOUT_TYPE; dwTmp ++ ) {
if ( mtFxxAttrib[dwChannel].mdwTimeID[dwTmp] > 0 ) {
KillUFTimer( mtFxxAttrib[dwChannel].mdwTimeID[dwTmp] );
mtFxxAttrib[dwChannel].mdwTimeID[dwTmp] = 0;
}
}
}
void CCallControl::vKillTimer( DWORD dwChannel, eChannelTimer eType )
{
if ( gblnPbxEnable ) {
tTraceResultMessage tTrace;
tTrace.eType = ePbxCommand;
tTrace.u.tCcUaMsg.hdr.eMsgType = eKillTimer;
tTrace.u.tCcUaMsg.hdr.dwDirection = 1;
tTrace.u.tCcUaMsg.hdr.dwChannel = dwChannel;
tTrace.u.tCcUaMsg.hdr.dwStatus = goCC.eGetStatus( dwChannel );
tTrace.u.tCcUaMsg.u.tTimerMsg.dwChannel = dwChannel;
tTrace.u.tCcUaMsg.u.tTimerMsg.dwTimerType = eType;
iQXput( &gqxQueueTrace, (UCHAR *)&tTrace );
}
if ( mtFxxAttrib[dwChannel].mdwTimeID[eType] > 0 ) {
KillUFTimer( mtFxxAttrib[dwChannel].mdwTimeID[eType] );
mtFxxAttrib[dwChannel].mdwTimeID[eType] = 0;
}
}
DWORD CMyTimer::operator ()(const UTIMER_PP &tpp)
{
tCC_UA_MSG tCcUaMsg;
tCcUaMsg.hdr.eMsgType = eTimer;
tCcUaMsg.hdr.dwChannel = m_dwChannel;
tCcUaMsg.hdr.length = sizeof(tCcUaMsg.hdr) + sizeof(tCcUaMsg.u.tTimerMsg);
tCcUaMsg.u.tTimerMsg.dwChannel = m_dwChannel;
tCcUaMsg.u.tTimerMsg.dwTimerType = tpp.uType;
iQXput( &gqxQueueUaMsg, (UCHAR *)&tCcUaMsg );
return 0;
}
void CCallControl::vCallControl( DWORD dwChannel, eFxxMsgType eMsgType, char *pchMsg )
{
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
sem_wait( &m_smCallControl );
switch( meChannelStatus[dwChannel] ) {
case eTrunkIdle:
// vTrunkIdle( dwChannel, eMsgType, pchMsg );
break;
case eTrunkReady:
// vTrunkReady( dwChannel, eMsgType, pchMsg );
break;
case eTrunkStartCall:
// vTrunkStartCall( dwChannel, eMsgType, pchMsg );
break;
case eTrunkConnecting:
// vTrunkConnecting( dwChannel, eMsgType, pchMsg );
break;
case eTrunkConnect:
// vTrunkConnect( dwChannel, eMsgType, pchMsg );
break;
case eTrunkDisconnect:
// vTrunkDisconnect( dwChannel, eMsgType, pchMsg );
break;
case eTrunkAnswer:
// vTrunkAnswer( dwChannel, eMsgType, pchMsg );
break;
case eTrunkPlay:
// vTrunkPlay( dwChannel, eMsgType, pchMsg );
break;
case eTrunkCalling:
// vTrunkCalling( dwChannel, eMsgType, pchMsg );
break;
case eTrunkWaitConnect:
// vTrunkWaitConnect( dwChannel, eMsgType, pchMsg );
break;
case eTrunkDisaCalling:
// vTrunkDisaCalling( dwChannel, eMsgType, pchMsg );
break;
case eTrunkDisaAnswer:
// vTrunkDisaAnswer( dwChannel, eMsgType, pchMsg );
break;
case eTrunkWaitCallid:
// vTrunkWaitCallid( dwChannel, eMsgType, pchMsg );
break;
}
sem_post( &m_smCallControl );
}
void CCallControl::vSendMsgToUA( ptCC_UA_MSG ptCcUaMsg )
{
tTraceResultMessage tTrace;
if ( gblnPbxEnable && ptCcUaMsg->hdr.eMsgType != eAudioData ) {
tTrace.eType = ePbxCommand;
ptCcUaMsg->hdr.dwDirection = 1;
ptCcUaMsg->hdr.dwStatus = goCC.eGetStatus( ptCcUaMsg->hdr.dwChannel );
tTrace.u.tCcUaMsg = *ptCcUaMsg;
iQXput( &gqxQueueTrace, (UCHAR *)&tTrace );
}
// call function of HEGS
printf( "vReceiveCCMesg\n" );
vReceiveCCMesg( ptCcUaMsg );
}
void CCallControl::vChangeCCStatus( DWORD dwChannel, eCCStatus eStatus )
{
tTraceResultMessage tTrace;
// char chTmpPara[8];
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
if ( gblnPbxEnable || gblnLayer3Enable ) {
tTrace.eType = eLayer3Status;
tTrace.u.tLayer3.dwChannel = dwChannel;
tTrace.u.tLayer3.eStatus = goCC.eGetStatus( dwChannel );;
tTrace.u.tLayer3.eNewStatus = eStatus;
iQXput( &gqxQueueTrace, (UCHAR *)&tTrace );
}
mtFxxAttrib[dwChannel].dwT303TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwT304TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwT305TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwT306TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwT307TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwT308TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwT309TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwT313TimeoutCounter = 0;
mtFxxAttrib[dwChannel].dwDtmfRecvCounter = 0;
mtFxxAttrib[dwChannel].boolCallOriginateStart = FALSE;
if ( eStatus == eTrunkReady || eStatus == eTrunkIdle ) {
mtFxxAttrib[dwChannel].iDtmfQueueLength = 0;
mtFxxAttrib[dwChannel].boolSendDtmfEnable = FALSE;
mtFxxAttrib[dwChannel].boolStageTwo = FALSE;
memset( mtFxxAttrib[dwChannel].mchLastSendDtmf, 0, sizeof(mtFxxAttrib[dwChannel].mchLastSendDtmf) );
mtFxxAttrib[dwChannel].iLastDtmfMsglen = 0;
}
if ( eStatus == eTrunkConnect ) {
mtFxxAttrib[dwChannel].boolSendDtmfEnable = TRUE;
vSetTimer( dwChannel, eT317, mdwTimeoutLength[eT317] );
}
if ( eStatus == eTrunkReady ) {
mtFxxAttrib[dwChannel].eFxoCallType = eFxoCallin;
}
meChannelStatus[dwChannel] = eStatus;
if ( eStatus == eTrunkConnect || eStatus == eTrunkPlay ) {
vPutDriver( dwChannel, eACTION_TALK, 0, 0 );
} else {
vPutDriver( dwChannel, eACTION_TALK_DENY, 0, 0 );
}
vReportCCStatus( dwChannel );
}
void CCallControl::vReportCCStatus( DWORD dwChannel )
{
tCC_UA_MSG tCcUaMsg;
if ( dwChannel >= MAX_LINE_NUM ) {
return;
}
tCcUaMsg.hdr.eMsgType = eReportStatus;
tCcUaMsg.hdr.dwCcIdx = 0;
tCcUaMsg.hdr.dwUaIdx = 0;
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.hdr.length = sizeof(tCcUaMsg.hdr) + sizeof(tCcUaMsg.u.tReport);
tCcUaMsg.u.tReport.dwLineType = gmiLineType[dwChannel];
tCcUaMsg.u.tReport.dwChannel = m_tWebConfig.trunk_out.trunk_out_item[dwChannel].trunk_tel_no;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -