📄 fxotalking.c
字号:
//
// Copyright (c) Blueinfosys. All rights reserved.
//
// Module Name: Fxotalking.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::vFxotalking( 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;
char chDtmf;
switch( eMsgType ) {
case eMsgFromUa:
switch( ptMsgReq->hdr.eMsgType ) {
case eSetup:
if ( ptMsgReq->u.tSetup.boolTransfer == TRUE ) {
// receive a call transfered
// send Connect to UA
dwIdx = eFirstcall;
// current call is transfered
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.dwCaller = ptMsgReq->u.tSetup.dwCaller;
tCcUaMsg.u.tConnect.dwCallee = ptMsgReq->u.tSetup.dwCallee;
ptAttrib->mtCallInfo[dwIdx].dwUaIdx = ptMsgReq->hdr.dwUaIdx;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
ptAttrib->mtCallInfo[dwIdx].tSetup = ptMsgReq->u.tSetup;
vSendMsgToUA( &tCcUaMsg );
vSetTimer( dwChannel, eT208, mdwTimeoutLength[eT208] );
vChangeCCStatus( dwChannel, eFxo_connecting );
break;
}
COMMFUNC_V( dwChannel, &tCcUaMsg, ptMsgReq );
break;
case eInConference:
ptAttrib->boolInConference = TRUE;
break;
case eOutConference:
ptAttrib->boolInConference = FALSE;
break;
case eFxoFlash:
vPutDriver( dwChannel, eACTION_FXO_FLASH, NULL, 0 );
break;
case eAlerting:
vPutDriver( dwChannel, eACTION_TALK_DENY, NULL, 0 );
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_ON, NULL, 0 );
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_ON, NULL, 0 );
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_ON, NULL, 0 );
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_ON, NULL, 0 );
vPutDriver( dwChannel, eACTION_FXS_RINGBACK_ON, NULL, 0 );
dwIdx = eFirstcall;
if ( ptMsgReq->u.tAlert.dwLineType == 2
&& m_tModuleInfo.port.dwDirectTel[dwChannel] == 0 ) {
ptAttrib->mtCallInfo[dwIdx].boolFxoCall = TRUE;
}
ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee = ptMsgReq->u.tAlert.dwCallee;
ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller = ptMsgReq->u.tAlert.dwCaller;
ptAttrib->mtCallInfo[dwIdx].dwUaIdx = ptMsgReq->hdr.dwUaIdx;
vSetTimer( dwChannel, eT207, mdwTimeoutLength[eT207] );
vChangeCCStatus( dwChannel, eFxo_waitconnect );
break;
case eConnect:
dwIdx = eFirstcall;
if ( ptMsgReq->u.tConnect.dwLineType == 2
&& m_tModuleInfo.port.dwDirectTel[dwChannel] == 0 ) {
ptAttrib->mtCallInfo[dwIdx].boolFxoCall = TRUE;
}
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;
ptAttrib->mtCallInfo[dwIdx].dwUaIdx = ptMsgReq->hdr.dwUaIdx;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee = ptMsgReq->u.tConnect.dwCallee;
ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller = ptMsgReq->u.tConnect.dwCaller;
ptAttrib->mtCallInfo[dwIdx].dwUaIdx = ptMsgReq->hdr.dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
vSetTimer( dwChannel, eT116, mdwTimeoutLength[eT116] );
#ifdef FXO_CONTROL
vSetTimer( dwChannel, eT119, mdwTimeoutLength[eT119] );
#endif
ptAttrib->dwFxoStatusEnquiryCounter = 0;
vChangeCCStatus( dwChannel, eFxo_talking );
break;
case eRelease:
ptAttrib->eActiveCall = eFirstcall;
RELEASECOMP( dwChannel, &tCcUaMsg, eRls_ReleaseAns );
if ( ptMsgReq->u.tRls.eReason == eRls_Transfer ) {
// 呼叫转移产生的Rlease消息
vSetTimer( dwChannel, eT117, mdwTimeoutLength[eT117] );
break;
}
vPutDriver( dwChannel, eACTION_FXO_ONHOOK, NULL, 0 );
vSetTimer( dwChannel, eT114, mdwTimeoutLength[eT114] );
vChangeCCStatus( dwChannel, eFxo_end );
break;
case eHoldOn:
// answer HoldOk to UA
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eHoldOk;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tHoldOK );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tHoldOK.dwCaller = ptMsgReq->u.tHoldRequest.dwCaller;
tCcUaMsg.u.tHoldOK.dwCallee = ptMsgReq->u.tHoldRequest.dwCallee;
tCcUaMsg.u.tHoldOK.dwType = 0;
tCcUaMsg.hdr.dwCcIdx = ptMsgReq->hdr.dwCcIdx;
tCcUaMsg.hdr.dwUaIdx = ptMsgReq->hdr.dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
vPlayVoiceFile( dwChannel, eHoldMusic );
ptAttrib->dwPlayMode = 6;
vChangeCCStatus( dwChannel, eFxo_play );
break;
case eFxoStatusAck:
if ( ptMsgReq->u.tFxoStatusAck.dwStatus >= eFxo_idle ) {
// the partner is FXO
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eRelease;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tRls );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tRls.eReason = eRls_NoRight;
dwIdx = eFirstcall;
tCcUaMsg.u.tRls.dwCaller = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller;
tCcUaMsg.u.tRls.dwCallee = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
vSetTimer( dwChannel, eT107, mdwTimeoutLength[eT107] );
vChangeCCStatus( dwChannel, eFxo_disconnect );
break;
}
if ( ptMsgReq->u.tFxoStatusAck.boolOppositeOk == TRUE ) {
ptAttrib->dwFxoStatusEnquiryCounter = 0;
#ifdef FXO_CONTROL
vSetTimer( dwChannel, eT119, mdwTimeoutLength[eT119] );
#endif
} else {
// 收到对方的否认回应,按挂机处理
break;//0000 test
printf("fxotalking,error,%d\n",dwChannel);
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eRelease;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tRls );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tRls.eReason = eRls_Busy;
dwIdx = eFirstcall;
tCcUaMsg.u.tRls.dwCaller = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller;
tCcUaMsg.u.tRls.dwCallee = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
vSetTimer( dwChannel, eT107, mdwTimeoutLength[eT107] );
vChangeCCStatus( dwChannel, eFxo_disconnect );
break;
}
if ( ptMsgReq->u.tFxoStatusAck.dwStatus >= eFxo_idle ) {
// the partner is FXO
vPutDriver( dwChannel, eACTION_SCE_ON, NULL, 0 );
ptAttrib->eFxoPartnerType = eFxocall;
if ( ptAttrib->boolBusyToneSave ) {
memset( (char *)&tCcUaMsg, 0, sizeof(tCcUaMsg) );
tCcUaMsg.hdr.eMsgType = eRelease;
tCcUaMsg.hdr.length = sizeof( tCcUaMsg.hdr ) + sizeof( tCcUaMsg.u.tRls );
tCcUaMsg.hdr.dwChannel = dwChannel;
tCcUaMsg.u.tRls.eReason = eRls_Busy;
dwIdx = eFirstcall;
tCcUaMsg.u.tRls.dwCaller = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCaller;
tCcUaMsg.u.tRls.dwCallee = ptAttrib->mtCallInfo[dwIdx].tSetup.dwCallee;
tCcUaMsg.hdr.dwCcIdx = dwIdx;
tCcUaMsg.hdr.dwUaIdx = ptAttrib->mtCallInfo[dwIdx].dwUaIdx;
vSendMsgToUA( &tCcUaMsg );
vSetTimer( dwChannel, eT107, mdwTimeoutLength[eT107] );
vChangeCCStatus( dwChannel, eFxo_disconnect );
break;
}
} else {
ptAttrib->eFxoPartnerType = eFxscall;
}
#if 0
if ( ptMsgReq->u.tFxoStatusAck.dwStatus == eFxo_talking ||
ptMsgReq->u.tFxoStatusAck.dwStatus == eFxs_talking ||
ptMsgReq->u.tFxoStatusAck.dwStatus == eFxo_play ||
ptMsgReq->u.tFxoStatusAck.dwStatus == eFxs_playing ) {
}
#endif
break;
case eRtpSessionOK:
printf("eRtpSessionOK\n");
dwIdx = eFirstcall;
ptAttrib->mtCallInfo[dwIdx].boolDtmfTransferReady = TRUE;
vTransferDtmfCode( dwChannel );
break;
case eSceOn:
vPutDriver( dwChannel, eACTION_SCE_ON, NULL, 0 );
break;
case eSceOff:
vPutDriver( dwChannel, eACTION_SCE_OFF, NULL, 0 );
break;
case eDtmfCode:
dwIdx = eFirstcall;
printf( "eDtmfCode\n" );
if ( ptAttrib->mtCallInfo[dwIdx].boolFxoCall == TRUE &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -