⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fxotalking.c

📁 基于嵌入式Linux平台的网络电话外部交换局会话功能代码段。
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -