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

📄 callcontrol_a.c

📁 基于嵌入式Linux平台的网络电话设计原程序部分代码段。
💻 C
📖 第 1 页 / 共 2 页
字号:

	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 + -