// StressTestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "StressTest.h"
#include "StressTestDlg.h"
#include "FolderDialog.h"


//Audio FORMAT
#define		GT_AUDIO_FORMAT_ADPCM					0x00000000
#define		GT_AUDIO_FORMAT_ADPCM_4_BIT             0x00000001
#define		GT_AUDIO_FORMAT_ADPCM_3_BIT             0x00000002
#define		GT_AUDIO_FORMAT_MU_LAW                  0x00000003  /* Default */
#define		GT_AUDIO_FORMAT_A_LAW                   0x00000004
#define		GT_AUDIO_FORMAT_PCM_16_BIT              0x00000005
#define		GT_AUDIO_FORMAT_PCM_8_BIT               0x00000006
#define		GT_AUDIO_FORMAT_PCM		                0x00000007
#define		GT_AUDIO_FORMAT_GSM						0x00000008
#define		GT_AUDIO_FORMAT_G726_16K				0x00000009
#define		GT_AUDIO_FORMAT_G726_24K				0x0000000A
#define		GT_AUDIO_FORMAT_G726_32K				0x0000000B
#define		GT_AUDIO_FORMAT_G726_40K				0x0000000C

#define		GT_AUDIO_FORMAT_G729a					0x0000000D

// optional, dialogic ADPCM 
#define		GT_AUDIO_FORMAT_OKI_ADPCM               0x00010000  


#define		GT_AUDIO_BIT_2							0x00000010
#define		GT_AUDIO_BIT_3							0x00000020
#define		GT_AUDIO_BIT_4							0x00000030
#define		GT_AUDIO_BIT_5							0x00000040
#define		GT_AUDIO_BIT_6							0x00000050
#define		GT_AUDIO_BIT_8							0x00000060
#define		GT_AUDIO_BIT_16							0x00000070

// audio sampling rates
#define		GT_AUDIO_SAMPLING_RATE_4_KHz            0x00000001
#define		GT_AUDIO_SAMPLING_RATE_6_KHz            0x00000002
#define		GT_AUDIO_SAMPLING_RATE_8_KHz            0x00000003  /* Default */
#define		GT_AUDIO_SAMPLING_RATE_11_KHz           0x00000004
#define		GT_AUDIO_SAMPLING_RATE_22_KHz           0x00000005
#define		GT_AUDIO_SAMPLING_RATE_44_KHz           0x00000006



#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStressTestDlg dialog

CStressTestDlg::CStressTestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CStressTestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CStressTestDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_pEnv = 0;
}

void CStressTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CStressTestDlg)
	DDX_Control(pDX, IDC_EDIT_CONNECT_DURATION, m_editConnectDuration);
	DDX_Control(pDX, IDC_CHECK_LOG, m_chkLog);
	DDX_Control(pDX, IDC_CHECK_USE_NAT, m_btnUseNAT);
	DDX_Control(pDX, IDC_EDIT_CODEC_PREFER, m_editCodecs);
	DDX_Control(pDX, IDC_BUTTON_STOP_SIP, m_btnStopSIP);
	DDX_Control(pDX, IDC_BUTTON_START_SIP, m_btnStartSIP);
	DDX_Control(pDX, IDC_STATIC_LINE_STATUS, m_LineStatus);
	DDX_Control(pDX, IDC_EDIT_SPANS, m_editSpans);
	DDX_Control(pDX, IDC_EDIT_SIP_PORT, m_editSIPPort);
	DDX_Control(pDX, IDC_EDIT_SIP_ADDR, m_editSIPAddr);
	DDX_Control(pDX, IDC_EDIT_RTP_PORT, m_editRTPPort);
	DDX_Control(pDX, IDC_EDIT_INET_PORT, m_editInetPort);
	DDX_Control(pDX, IDC_EDIT_CHANS, m_editChans);
	DDX_Control(pDX, IDC_EDIT_BOARDS, m_editBoards);
	DDX_Control(pDX, IDC_EDIT_AUDIO_RECORD_ROOT, m_editAudioRecordRoot);
	DDX_Control(pDX, IDC_EDIT_AUDIO_FILE_TO_PLAY, m_editAudioFileToPlay);
	DDX_Control(pDX, IDC_COMBO_APP_TYPE, m_cbxAppType);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CStressTestDlg, CDialog)
	//{{AFX_MSG_MAP(CStressTestDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_START_SIP, OnButtonStartSip)
	ON_BN_CLICKED(IDC_BUTTON_STOP_SIP, OnButtonStopSip)
	ON_BN_CLICKED(IDC_BUTTON_AF_BROWSE, OnButtonAfBrowse)
	ON_BN_CLICKED(IDC_BUTTON_RD_BROWSE, OnButtonRdBrowse)
	ON_CBN_SELCHANGE(IDC_COMBO_APP_TYPE, OnSelchangeComboAppType)
	ON_WM_DESTROY()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStressTestDlg message handlers

BOOL CStressTestDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here

	m_btnStartSIP.EnableWindow(TRUE);
	m_btnStopSIP.EnableWindow(FALSE);

	Log("IDLE");
	m_editBoards.SetWindowText("1");
	m_editSpans.SetWindowText("4");
	m_editChans.SetWindowText("8");

	m_editSIPPort.SetWindowText("5060");

	srand(time(0));

	int n = 21000 + ((rand()%100)*200);
	char stemp[100];
	sprintf(stemp, "%d", n);
	m_editRTPPort.SetWindowText(stemp);

	n = 5900 + ((rand()%100) * 2);
	sprintf(stemp, "%d", n);
	m_editInetPort.SetWindowText(stemp);

	//m_editCodecs.SetWindowText("102,101,100,3,98,0,8");
	//only use mulaw to do the test
	m_editCodecs.SetWindowText("0,8"); 

	m_cbxAppType.SetCurSel(0);
	m_editSIPAddr.EnableWindow(FALSE);
	m_editConnectDuration.EnableWindow(FALSE);

	SetTimer(1010, 1000, 0);

	srand(time(0));

#ifdef _DEBUG
	SetWindowText("");
#endif

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CStressTestDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here

	KillTimer(1010);
	
}


void CStressTestDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
/*
	if(nIDEvent == 1010)
	{
		if(m_pEnv)
		{
			if(m_pEnv->m_appType == 1)
			{
				if(rand() % 2 == 0)
				{
					GTAPI_Channel* pChan = m_pEnv->GetChannel(rand() % m_pEnv->GetTotalChannelNumber());
					if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
						m_pEnv->Send_HungUp(pChan->ch_index);
				}
			}
		}
	}
*/	
	CDialog::OnTimer(nIDEvent);
}


void CStressTestDlg::OnSelchangeComboAppType() 
{
	// TODO: Add your control notification handler code here
	if(m_cbxAppType.GetCurSel() == 0)
	{
		m_editSIPAddr.EnableWindow(FALSE);
		m_editConnectDuration.EnableWindow(FALSE);
	}
	else
	{
		m_editSIPAddr.EnableWindow(TRUE);
		m_editConnectDuration.EnableWindow(TRUE);
		m_editConnectDuration.SetWindowText("60");
	}

}


void CStressTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CStressTestDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CStressTestDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}



void CStressTestDlg::OnButtonStartSip() 
{
	CString s;
	

	// TODO: Add your control notification handler code here
	//SIP IP Address you want to use on local
	//Leave it unset if you want to listen on all the network interface
	//CFG_SetValue("gtsrv.sip.ip.address", "");

	//SIP Port, default 5060
	m_editSIPPort.GetWindowText(s);
	GT_CFG_SetValue("gtsrv.sip.ip.port", s);

	//RTP PORT
	m_editRTPPort.GetWindowText(s);
	GT_CFG_SetValue("gtsrv.sip.rtpstartrange", s);

	char sTemp[128];
	sprintf(sTemp, "%d", atoi(s) + 10000);
	GT_CFG_SetValue("gtsrv.sip.rtpendrange", sTemp);

//	if(m_btnUseNAT.GetCheck() == 1)
	{
		GT_CFG_SetValue("gtsrv.sip.use.nat.addr", "1");
		GT_CFG_SetValue("gtsrv.sip.stun.server", "");
	}
//	else
//	{
//		GT_CFG_SetValue("gtsrv.sip.use.nat.addr", "0");
//	}

	//Log 

	if(m_chkLog.GetCheck() == 1)
	{
		if(m_cbxAppType.GetCurSel() == 0)
		{
			GT_CFG_SetValue(GTSRV_INI_LOG_LEVEL, "4");
			GT_CFG_SetValue(GTSRV_INI_LOG, "c:\\stress_in.txt");
		}
		else
		{
			GT_CFG_SetValue(GTSRV_INI_LOG_LEVEL, "4");
			GT_CFG_SetValue(GTSRV_INI_LOG, "c:\\stress_out.txt");
		}
	}
	else
	{
		GT_CFG_SetValue(GTSRV_INI_LOG_LEVEL, "0");
	}

	m_editBoards.GetWindowText(s);
	GT_CFG_SetValue("gtsrv.sip.boardnum.per.server", s);

	m_editSpans.GetWindowText(s);
	GT_CFG_SetValue("gtsrv.sip.spannum.per.board", s);

	m_editChans.GetWindowText(s);
	GT_CFG_SetValue("gtsrv.sip.channum.per.span", s);

	m_editCodecs.GetWindowText(s);
	GT_CFG_SetValue("gtsrv.sip.prefered.codec", s);
/*
#We don’t recommend you set "gtsrv.sip.channum.per.span" more than 16.
#Sugguested Configuration of CHANNELS, SPANS, and Boards:
#Channels	gtsrv.sip.channum.per.span	gtsrv.sip.spannum.per.board	gtsrv.sip.boardnum.per.server
#4			4				1				1
#8			8				1				1
#16			8				2				1
#24			8				3				1
#32			8				4				1
#40			8				5				1
#64			8				8				1
#128			8				8				2
#256			8				8				4
#512			16				8				4
*/

	//define inbound and outbound channels
	//CFG_SetValue("gtsrv.channel.inbound", "0-3");
	//CFG_SetValue("gtsrv.channel.outbound", "4-15");

	//Internal communication port
	m_editInetPort.GetWindowText(s);
	GT_CFG_SetValue(GTSRV_INI_NET_PORT, s);

	//Configuration file, if you want to define parameters in a file
	//CFG_SetValue(GTSRV_CFG_FILENAME, "GTPBXSrv1.ini");

	//define outbound route, leave them unset if you don't know
	//CFG_SetValue("gtsrv.sip.outbound.via.type", "0");
	//CFG_SetValue("gtsrv.sip.outbound.via.proxy", "");

	//set sip client user info
	//you must get an account from sip service provider first
	/*
	CFG_SetValue("gtsrv.sip.reg.client.num", "1");

	CFG_SetValue("gtsrv.sip.reg1.displayname", m_sipAccDisplayName);
	CFG_SetValue("gtsrv.sip.reg1.username", m_sipAccUserName);
	CFG_SetValue("gtsrv.sip.reg1.domain", m_sipAccDomainName);
	CFG_SetValue("gtsrv.sip.reg1.proxy", m_sipAccProxyName);
	CFG_SetValue("gtsrv.sip.reg1.authorization", m_sipAccAuthName);
	CFG_SetValue("gtsrv.sip.reg1.password", m_sipAccPassword);
	CFG_SetValue("gtsrv.sip.reg1.expire", "3600");
	*/

	m_pEnv = new CGTSIPStressTestEnv();
	m_pEnv->m_pMainDlg = this;


	m_editAudioFileToPlay.GetWindowText(m_pEnv->m_sAudioFileToPlay, 255);

	m_editAudioRecordRoot.GetWindowText(m_pEnv->m_sAudioRecordRoot, 255);
	if(strlen(m_pEnv->m_sAudioRecordRoot))
		if(m_pEnv->m_sAudioRecordRoot[strlen(m_pEnv->m_sAudioRecordRoot)-1] != '\\')
		{
			strcat(m_pEnv->m_sAudioRecordRoot, "\\");
		}

	m_editSIPAddr.GetWindowText(m_pEnv->m_sOutboundSIPAddr, 255);
	m_pEnv->m_appType = m_cbxAppType.GetCurSel();

	if(m_pEnv->m_appType == 1)
	{
		//outbound
		m_editConnectDuration.GetWindowText(s);
		m_pEnv->m_callDuration = atoi(s);
		if(m_pEnv->m_callDuration < 10)
			m_pEnv->m_callDuration = 10;
	}


	//GT_CFG_SetValue( "gtsrv.sip.dyn.check.remote.rtp" , "0" );
	//GT_CFG_SetValue("gtsrv.sip.jb.min.delay", "2");
	//GT_CFG_SetValue("gtsrv.sip.jb.max.delay", "25");
	//m_bAdaptiveJB = CFG_GetIntValue("gtsrv.sip.jb.adaptive", 0)?true:false;
	//GT_CFG_SetValue("gtsrv.sip.jb.get.all.data", "1");

	//Application name, it is related to sdk licence
	//Please contact PCBest Network(www.pcbest.net) to get licence info
	m_pEnv->SetAppName("StressTest");

	//m_pEnv->SetAppName("TestServerApp");
	//GT_CFG_SetValue("gtsrv.licence.key", "");

	if(!m_pEnv->StartServer())
		MessageBox("StartServer Failed! Please check if SIP port is being used by another application!", "Error");

	m_btnStartSIP.EnableWindow(FALSE);
	m_btnStopSIP.EnableWindow(TRUE);


	//trying to use 8KZ PCM 16bit mono to write the data
	for(unsigned int i=0; i<m_pEnv->GetTotalChannelNumber(); i++)
	{
		m_pEnv->Send_SetAudioFormat(i, GT_AUDIO_FORMAT_PCM, GT_AUDIO_SAMPLING_RATE_8_KHz, GT_AUDIO_BIT_16);
	}

	Sleep(500);

	if(m_cbxAppType.GetCurSel() == 1)
	{
		//outbound application
		for(unsigned int i=0; i<m_pEnv->GetTotalChannelNumber(); i++)
		{
			m_pEnv->StartTimer(i, (200+i*50));
		}
	}

}

void CStressTestDlg::OnButtonStopSip() 
{
	// TODO: Add your control notification handler code here
	m_pEnv->StopServer();
	delete m_pEnv;
	m_pEnv = 0;

	m_btnStartSIP.EnableWindow(TRUE);
	m_btnStopSIP.EnableWindow(FALSE);

	Log("Connected Calls:0");

}

void CStressTestDlg::OnButtonAfBrowse() 
{
	// TODO: Add your control notification handler code here
	CFileDialog dlg(TRUE);

	if(dlg.DoModal() == IDOK)
	{
		m_editAudioFileToPlay.SetWindowText(dlg.GetPathName());
	}
}

void CStressTestDlg::OnButtonRdBrowse() 
{
	// TODO: Add your control notification handler code here
	CFolderDialog dlg;
	if(dlg.DoModal() == IDOK)
	{
		m_editAudioRecordRoot.SetWindowText(dlg.GetPathName());
	}	
}

void CStressTestDlg::Log(const char* info)
{
	m_LineStatus.SetWindowText(info);
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CGTSIPStressTestEnv
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CGTSIPStressTestEnv::CGTSIPStressTestEnv():CGTAPIEnv()
{
	m_pMainDlg = 0;
	m_sAudioFileToPlay[0] = 0;
	m_sAudioRecordRoot[0] = 0;

	m_sOutboundSIPAddr[0] = 0;
	m_appType = 0;

	m_CallCount = 0;

	m_bServerRunning = FALSE;

	m_callDuration = 60;

	m_pNoAudioStatus = 0;
}

CGTSIPStressTestEnv::~CGTSIPStressTestEnv()
{

}

bool CGTSIPStressTestEnv::StartServer()
{
	m_CallCount = 0;
	bool ret = CGTAPIEnv::StartServer();

	m_bServerRunning = TRUE;

	m_pNoAudioStatus = new NoAudioStatus[GetTotalChannelNumber()];

	return ret;

}

bool CGTSIPStressTestEnv::StopServer()
{
	m_bServerRunning = FALSE;

	delete []m_pNoAudioStatus;

	return CGTAPIEnv::StopServer();
}


void CGTSIPStressTestEnv::On_RecvConnected(int ch)
{
	CGTAPIEnv::On_RecvConnected(ch);

	if(*m_sAudioFileToPlay)
		Send_PlayAudio(ch, m_sAudioFileToPlay, 0, "", 0, 0);

	char sRecordAudioFile[255];
	memset(sRecordAudioFile, 0, 255);

	if(*m_sAudioRecordRoot)
	{
		_snprintf(sRecordAudioFile, 254, "%s%d_%d.wav", m_sAudioRecordRoot, ch, time(0));
		Send_RecordAudio(ch, sRecordAudioFile, 0, "", 0, 0);
	}

	m_mtxCount.Lock();
	m_CallCount++;
	m_mtxCount.Unlock();

	LogoutCallCount();

	if(m_appType == 1)
	{
/*
		if(rand()%4 == 0)
			StartTimer(ch, 100 + (rand()%20)*100);
		else
*/
			StartTimer(ch, (m_callDuration + (rand()%10))*1000);
	}
	else
		StartTimer(ch, (5 + (rand()%10))*1000);

	m_pNoAudioStatus[ch].m_noAudioTime = 0;
	m_pNoAudioStatus[ch].m_noAudioCount = 0;

}

void CGTSIPStressTestEnv::On_RecvOffered(int ch, const char* sCaller, const char* sCallee, const char* sDestAddr, \
	const char* sViaAddr, const char* sFromIP, unsigned short nFromPort)
{
	CGTAPIEnv::On_RecvOffered(ch, sCaller, sCallee, sDestAddr, \
	sViaAddr, sFromIP, nFromPort);

	if(m_appType == 0)
	{
		Send_Answer(ch);
	}
	else
	{
		Send_HangUp(ch, 0, "");
	}
}

void CGTSIPStressTestEnv::On_RecvDialing(int ch, const char* sCaller, const char* sCallee)
{
	CGTAPIEnv::On_RecvDialing(ch, sCaller, sCallee);
}

void CGTSIPStressTestEnv::On_RecvIdle(int ch, int code, const char* desc)
{
	m_mtxCount.Lock();
	GTAPI_Channel* pChan = GetChannel(ch);
	if(m_CallCount > 0 && pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
		m_CallCount--;
	m_mtxCount.Unlock();

	CGTAPIEnv::On_RecvIdle(ch, code, desc);

	LogoutCallCount();

	if(m_appType == 1)
	{
		StartTimer(ch, 2000);
	}
	else
		StopTimer(ch);

	m_pNoAudioStatus[ch].m_noAudioTime = 0;
	m_pNoAudioStatus[ch].m_noAudioCount = 0;
}

void CGTSIPStressTestEnv::On_RecvRinging(int ch)
{
	CGTAPIEnv::On_RecvRinging(ch);
}

void CGTSIPStressTestEnv::LogoutCallCount()
{
	char sTemp[255];
	
	//because this is the thread in SDK, and GUI thread may be waiting for server's shutdown
	if(m_bServerRunning)
	{
		sprintf(sTemp, "Connected Calls:%d", m_CallCount);
		m_pMainDlg->Log(sTemp);
	}
}

void CGTSIPStressTestEnv::MakeCallOut(int ch)
{
	char sTemp[255];
	memset(sTemp, 0, 255);

	_snprintf(sTemp, 254, "<sip:%s>", m_sOutboundSIPAddr);

	Send_Make(ch, sTemp, "");
}

void CGTSIPStressTestEnv::OnTimer(int ch)
{
	if(m_appType == 1)
	{
		GTAPI_Channel* pChan = (GTAPI_Channel*)GetChannel(ch);
		if(pChan->ch_status == 0) //IDLE
		{
			if(m_bServerRunning)
			{
				MakeCallOut(ch);
			}
		}
		else
		{
			if(rand()%2 == 0)
			{
				Log(GT_LOG_INFO, "CGTSIPStressTestEnv::OnTimer Send_HungUp %d", ch);
				Send_HangUp(ch, 0, "");
			}
			else
			{
				char sDTMF[2];
				sDTMF[0] = '0' + rand()%10; 
				sDTMF[1] = 0;
				Send_PlayDTMFStr(ch, sDTMF);
				StartTimer(ch, (2 + (rand()%5))*1000);
			}
		}
	}
	else
	{
		char sDTMF[2];
		sDTMF[0] = '0' + rand()%10; 
		sDTMF[1] = 0;
		Send_PlayDTMFStr(ch, sDTMF);
		StartTimer(ch, (5 + (rand()%10))*1000);
	}
}

void CGTSIPStressTestEnv::On_RecvNoAudio(int ch, int reserved)
{
	time_t tNow = time(0);
	if(m_pNoAudioStatus[ch].m_noAudioTime == 0)
	{
		m_pNoAudioStatus[ch].m_noAudioTime = tNow;
		m_pNoAudioStatus[ch].m_noAudioCount = 0;
	}
	else
	{
		if(tNow - m_pNoAudioStatus[ch].m_noAudioTime > 10)
		{
			m_pNoAudioStatus[ch].m_noAudioTime = tNow;
			m_pNoAudioStatus[ch].m_noAudioCount = 0;
		}
		else
		{
			if(++m_pNoAudioStatus[ch].m_noAudioCount > 4)
			{
				GTAPI_Channel* pChan = (GTAPI_Channel*)GetChannel(ch);
				if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
				{
					Log(GT_LOG_ERROR, "CGTSIPStressTestEnv::On_RecvNoAudio Send_HungUp %d, %d", ch, m_pNoAudioStatus[ch].m_noAudioCount);
					Send_HangUp(ch, 0, "");
				}
			}
		}
	}
}
