// GTSimplePhoneDlg.cpp : implementation file
//

#include "stdafx.h"
#include "GTSimplePhone.h"
#include "GTSimplePhoneDlg.h"
//#include "mmsystem.h"
//#include "GTAPI_Face2.h"


#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()

/////////////////////////////////////////////////////////////////////////////
// CGTSimplePhoneDlg dialog

CGTSimplePhoneDlg::CGTSimplePhoneDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CGTSimplePhoneDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CGTSimplePhoneDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CGTSimplePhoneDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGTSimplePhoneDlg)
	DDX_Control(pDX, IDC_STATIC_LOG, m_staticLog);
	DDX_Control(pDX, IDC_EDIT1, m_editPhoneNum);
	DDX_Control(pDX, IDC_BUTTON_HUNGUP, m_btnHungup);
	DDX_Control(pDX, IDC_BUTTON_DIAL, m_btnDial);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CGTSimplePhoneDlg, CDialog)
	//{{AFX_MSG_MAP(CGTSimplePhoneDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON_2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON_3, OnButton3)
	ON_BN_CLICKED(IDC_BUTTON_4, OnButton4)
	ON_BN_CLICKED(IDC_BUTTON_5, OnButton5)
	ON_BN_CLICKED(IDC_BUTTON_6, OnButton6)
	ON_BN_CLICKED(IDC_BUTTON_7, OnButton7)
	ON_BN_CLICKED(IDC_BUTTON_8, OnButton8)
	ON_BN_CLICKED(IDC_BUTTON_9, OnButton9)
	ON_BN_CLICKED(IDC_BUTTON_STAR, OnButtonStar)
	ON_BN_CLICKED(IDC_BUTTON_11, OnButton11)
	ON_BN_CLICKED(IDC_BUTTON_POUND, OnButtonPound)
	ON_BN_CLICKED(IDC_BUTTON_DIAL, OnButtonDial)
	ON_BN_CLICKED(IDC_BUTTON_HUNGUP, OnButtonHungup)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON_TEST, OnButtonTest)
	ON_BN_CLICKED(IDC_CHECK_MUTE_SPEAKER, OnCheckMuteSpeaker)
	ON_BN_CLICKED(IDC_CHECK_MUTE_MIC, OnCheckMuteMic)
	ON_MESSAGE(WM_SDKAPP_OFFERED, OnSDKAppMessage)
	ON_MESSAGE(WM_SDKAPP_DIALING, OnSDKAppMessage)
	ON_MESSAGE(WM_SDKAPP_RINGING, OnSDKAppMessage)
	ON_MESSAGE(WM_SDKAPP_CONNECTED, OnSDKAppMessage)
	ON_MESSAGE(WM_SDKAPP_IDLE, OnSDKAppMessage)
	ON_MESSAGE(WM_SDKAPP_REGSTATUS, OnSDKAppMessage)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGTSimplePhoneDlg message handlers

BOOL CGTSimplePhoneDlg::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_Env.m_pMainDlg = this;
	m_Env.SetMainWnd(m_hWnd);
	m_Env.StartServer();

/*
	if(m_Env.GetDetectedNATType() < 0 || m_Env.GetDetectedNATType() >= 0x0A)
	{
		MessageBox("You may not be able to make Internet calls because you have a blocked network! \n Check your network configuration or firewall.", "Warn", MB_OK);
	}
*/
/*
	for(int i=0; i < GTAPI_GetRenderDeviceCount(); i++)
	{
		m_Env.Log(1, "Render Device %d:%s", i, GTAPI_GetRenderDeviceName(i));
	}

	for(int i=0; i < GTAPI_GetCaptureDeviceCount(); i++)
	{
		m_Env.Log(1, "Capture Device %d:%s", i, GTAPI_GetCaptureDeviceName(i));
	}
*/

	Log("IDLE");

	m_btnDial.SetWindowText("Dial");
	m_btnDial.EnableWindow(TRUE);
	m_btnHungup.EnableWindow(FALSE);

	m_editPhoneNum.SetWindowText("8888@sip.pcbest.net");

/*
	char sInfo[255];

	sprintf(sInfo, "Mic : %f", m_Env.GetMicVolume());
	MessageBox(sInfo);


	m_Env.SetMicVolume(0.5);
*/

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


void CGTSimplePhoneDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	m_Env.StopServer();
}


void CGTSimplePhoneDlg::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 CGTSimplePhoneDlg::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 CGTSimplePhoneDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CGTSimplePhoneDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;
	
	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "1");
		Log("CONNECTED pressed 1");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "1";
		m_editPhoneNum.SetWindowText(s);
	}

	m_Env.PlayNumTone('1');
}

void CGTSimplePhoneDlg::OnButton2() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "2");
		Log("CONNECTED pressed 2");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "2";
		m_editPhoneNum.SetWindowText(s);
	}

	m_Env.PlayNumTone('2');
}

void CGTSimplePhoneDlg::OnButton3() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "3");
		Log("CONNECTED pressed 3");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "3";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('3');
}

void CGTSimplePhoneDlg::OnButton4() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "4");
		Log("CONNECTED pressed 4");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "4";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('4');
}

void CGTSimplePhoneDlg::OnButton5() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "5");
		Log("CONNECTED pressed 5");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "5";
		m_editPhoneNum.SetWindowText(s);
	}

	m_Env.PlayNumTone('5');
}

void CGTSimplePhoneDlg::OnButton6() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "6");
		Log("CONNECTED pressed 6");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "6";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('6');
}

void CGTSimplePhoneDlg::OnButton7() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "7");
		Log("CONNECTED pressed 7");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "7";
		m_editPhoneNum.SetWindowText(s);
	}

	m_Env.PlayNumTone('7');
}

void CGTSimplePhoneDlg::OnButton8() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "8");
		Log("CONNECTED pressed 8");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "8";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('8');
}

void CGTSimplePhoneDlg::OnButton9() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "9");
		Log("CONNECTED pressed 9");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "9";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('9');
}

void CGTSimplePhoneDlg::OnButtonStar() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "*");
		Log("CONNECTED pressed *");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "*";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('*');
}

void CGTSimplePhoneDlg::OnButton11() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "0");
		Log("CONNECTED pressed 0");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "0";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('0');
}

void CGTSimplePhoneDlg::OnButtonPound() 
{
	// TODO: Add your control notification handler code here
	GTAPI::GTAPI_Channel* pChan = m_Env.GetChannel(0);

	if(!pChan) return;

	if(pChan->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
	{
		m_Env.Send_PlayDTMFStr(0, "#");
		Log("CONNECTED pressed #");
	}
	else
	{
		CString s;
		m_editPhoneNum.GetWindowText(s);
		s += "#";
		m_editPhoneNum.SetWindowText(s);
	}
	
	m_Env.PlayNumTone('#');
}

void CGTSimplePhoneDlg::OnButtonDial() 
{
	// TODO: Add your control notification handler code here
	char s[256];
	char sTemp[256];

	memset(s, 0, 256);
	memset(sTemp, 0, 256);

	m_editPhoneNum.GetWindowText(s, 255);

	if(!*s) return;

	if(strstr(s, "sip:") == s) //there are NOT '<' and '>'
	{
		sprintf(sTemp, "<%s>", s);
	}
	else if(strstr(s, "<sip:") == s) //there are '<' and '>'
	{
		sprintf(sTemp, "%s", s);
	}
	else if(strchr(s, '@')) //there is '@' but without 'sip:'
	{
		sprintf(sTemp, "<sip:%s>", s);
	}
	else //there is not '@', and no 'sip:'
	{
		if(*m_Env.CFG_GetValue("gtsrv.sip.reg1.domain", ""))
		{
			sprintf(sTemp, "<sip:%s@%s>", s, m_Env.CFG_GetValue("gtsrv.sip.reg1.domain", ""));
		}
		else
		{
			//there is no sip account
			//cannot call, just return
			return;
		}
	}

	m_Env.Send_Make(0, sTemp, "");
}

void CGTSimplePhoneDlg::OnButtonHungup() 
{
	// TODO: Add your control notification handler code here
	m_Env.Send_HangUp(0, 0, "");

}


void CGTSimplePhoneDlg::On_RecvConnected(int ch)
{
	Log("CONNECTED");

	m_btnDial.EnableWindow(FALSE);
	m_btnHungup.EnableWindow(TRUE);
}

void CGTSimplePhoneDlg::On_RecvOffered(int ch, const char* sCaller, const char* sCallee, const char* sDestAddr, \
		const char* sViaAddr, const char* sFromIP, unsigned short nFromPort)
{
	Log("NEW CALL IN");

    m_Env.StopSound();
    m_Env.PlayLocalRingSound();

	//answer call anyway here
	m_Env.Send_Answer(ch);

	m_btnDial.SetWindowText("Answer");
	m_btnDial.EnableWindow(TRUE);
	m_btnHungup.EnableWindow(FALSE);
}

void CGTSimplePhoneDlg::On_RecvDialing(int ch, const char* sCaller, const char* sCallee)
{
	Log("DIALING");

	m_btnDial.EnableWindow(FALSE);
	m_btnHungup.EnableWindow(TRUE);
}

void CGTSimplePhoneDlg::On_RecvIdle(int ch, int code, const char* desc)
{
	Log("IDLE");

    m_Env.StopSound();

	m_btnDial.SetWindowText("Dial");
	m_btnDial.EnableWindow(TRUE);
	m_btnHungup.EnableWindow(FALSE);
}

void CGTSimplePhoneDlg::On_RecvRinging(int ch)
{
	Log("Remote Side Ringing");
}

void CGTSimplePhoneDlg::On_RecvRegStatus(int user_id, int status, int regtime)
{
}

void CGTSimplePhoneDlg::Log(const char* info)
{
	m_staticLog.SetWindowText(info);
}


void CGTSimplePhoneDlg::OnButtonTest() 
{
	// TODO: Add your control notification handler code here
	m_Env.CFG_SetValue("gtsrv.sip.dxsound.device.playback", "");
	m_Env.CFG_SetValue("gtsrv.sip.dxsound.device.capture", "");
	m_Env.Send_ResetDXAudio(0);
}

void CGTSimplePhoneDlg::OnCheckMuteSpeaker() 
{
	// TODO: Add your control notification handler code here
	CButton *pButton = (CButton *)GetDlgItem(IDC_CHECK_MUTE_SPEAKER);
	if(pButton->GetCheck())
		m_Env.SetSpeakerMuteStatus(GT_TRUE);
	else
		m_Env.SetSpeakerMuteStatus(GT_FALSE);

}

void CGTSimplePhoneDlg::OnCheckMuteMic() 
{
	// TODO: Add your control notification handler code here
	CButton *pButton = (CButton *)GetDlgItem(IDC_CHECK_MUTE_MIC);
	if(pButton->GetCheck())
		m_Env.SetMicMuteStatus(GT_TRUE);
	else
		m_Env.SetMicMuteStatus(GT_FALSE);
	
}

LRESULT CGTSimplePhoneDlg::OnSDKAppMessage(WPARAM wParam, LPARAM lParam)
{
	sdkapp_msg* msg = (sdkapp_msg*)lParam;
	if(!msg) return 0;
	
	switch(msg->eventID)
	{
		case WM_SDKAPP_OFFERED:
		On_RecvOffered(msg->chanID, msg->args[0], msg->args[1], msg->args[2], msg->args[3], msg->args[4], atoi(msg->args[5]));
		break;
		case WM_SDKAPP_DIALING:
		On_RecvDialing(msg->chanID, msg->args[0], msg->args[1]);
		break;
		case WM_SDKAPP_RINGING:
		On_RecvRinging(msg->chanID);
		break;
		case WM_SDKAPP_CONNECTED:
		On_RecvConnected(msg->chanID);
		break;
		case WM_SDKAPP_IDLE:
		On_RecvIdle(msg->chanID, atoi(msg->args[0]), msg->args[1]);
		break;
		case WM_SDKAPP_REGSTATUS:
		On_RecvRegStatus(msg->chanID, atoi(msg->args[0]), atoi(msg->args[1]));
		break;
	}

	delete msg;
	
	return 0;
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CGTSIPSimplePhoneEnv
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CGTSIPSimplePhoneEnv::CGTSIPSimplePhoneEnv():CGTAPIEnv()
{
	m_pMainDlg = 0;
}

CGTSIPSimplePhoneEnv::~CGTSIPSimplePhoneEnv()
{

}

bool CGTSIPSimplePhoneEnv::StartServer()
{
	CFG_SetValue("gtsrv.sip.server.model", "0"); //client phone

	//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", "192.168.2.14");

	//SIP Port, default 5060
	CFG_SetValue("gtsrv.sip.ip.port", "5066");

	CFG_SetValue("gtsrv.sip.protocol", "4"); //TLS
	CFG_SetValue("gtsrv.sip.ssl.type", "12"); //TLS_V12
	CFG_SetValue("gtsrv.sip.ssl.cert.file", "C:\\SVNSrc2\\SIPProjectV1\\thirdparty\\cert.pem"); //TLS_V12
	CFG_SetValue("gtsrv.sip.ssl.key.file", "C:\\SVNSrc2\\SIPProjectV1\\thirdparty\\key.pem"); //TLS_V12


	//RTP PORT
	CFG_SetValue("gtsrv.sip.rtpstartrange", "17400");
	CFG_SetValue("gtsrv.sip.rtpendrange", "17800");

	//Log 
	CFG_SetValue(GTSRV_INI_LOG_LEVEL, "4");
	CFG_SetValue(GTSRV_INI_LOG, "c:\\temp\\gtsimplephone.txt");

	//audio codecs
	CFG_SetValue("gtsrv.sip.prefered.codec", "0,8");
	//CFG_SetValue("gtsrv.sip.prefered.video.codec", "124,34,115"); //H263 only
	//CFG_SetValue("gtsrv.sip.prefered.codec", "0,8");

	//channnel numbers, here we only use 1 channel
	CFG_SetValue("gtsrv.sip.boardnum.per.server", "1");
	CFG_SetValue("gtsrv.sip.spannum.per.board", "1");
	CFG_SetValue("gtsrv.sip.channum.per.span", "1");


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

	//Internal communication port
	CFG_SetValue(GTSRV_INI_NET_PORT, "8914");

	//CFG_SetValue("gtsrv.sip.vad.enabled", "0");

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

	//Application name, it is related to sdk licence
	//Please contact admin@pcbest.net to get licence info
	SetAppName("GTSimplePhone");

	//CFG_SetValue("gtsrv.sip.use.prack", "1");


	//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", "");

	//CFG_SetValue("gtsrv.sip.stun.server", "stun.callwithus.com");
	//CFG_SetValue("gtsrv.sip.enable.dns.srv", "1");

	//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", "FirstName LastName");
	//CFG_SetValue("gtsrv.sip.reg1.username", "122");
	//CFG_SetValue("gtsrv.sip.reg1.domain", "myvoip.com");
	//CFG_SetValue("gtsrv.sip.reg1.proxy", "myvoip.com");
	//CFG_SetValue("gtsrv.sip.reg1.authorization", "122");
	//CFG_SetValue("gtsrv.sip.reg1.password", "xxx");
	//CFG_SetValue("gtsrv.sip.reg1.expire", "300");
	//CFG_SetValue("gtsrv.sip.reg1.prot", "0"); //0=UDP, 1=TCP, 2=TLS, register as SIPS

	CFG_SetValue("gtsrv.sip.reg.client.num", "1");
	CFG_SetValue("gtsrv.sip.reg1.displayname", "Yonge");
	CFG_SetValue("gtsrv.sip.reg1.username", "1003");
	CFG_SetValue("gtsrv.sip.reg1.domain", "sip.pcbest.net:5061 ");
	CFG_SetValue("gtsrv.sip.reg1.proxy", "sip.pcbest.net:5061 ");
	CFG_SetValue("gtsrv.sip.reg1.authorization", "1003");
	CFG_SetValue("gtsrv.sip.reg1.password", "ly1111");
	CFG_SetValue("gtsrv.sip.reg1.expire", "300");
	CFG_SetValue("gtsrv.sip.reg1.prot", "2"); //0=UDP, 1=TCP, 2=TLS, register as SIPS

	CFG_SetValue("gtsrv.sip.ssl.type", "3");
	CFG_SetValue("gtsrv.sip.ssl.cert.file", "C:\\SVNSrc2\\SIPProjectV1\\thirdparty\\cert.pem");
	CFG_SetValue("gtsrv.sip.ssl.key.file", "C:\\SVNSrc2\\SIPProjectV1\\thirdparty\\key.pem");


	//CFG_SetValue("gtsrv.sip.reg1.subscribe", "1");
	//CFG_SetValue("gtsrv.sip.reg1.subscribe.expire", "1800");
	//CFG_SetValue("gtsrv.sip.reg1.subscribe.accept", "1");
	//CFG_SetValue("gtsrv.sip.reg1.subscribe.addr", "<sip:102@sipnetwork.com>;<sip:103@sipnetwork.com>;<sip:105@sipnetwork.com>");

	bool ret = CGTAPIEnv::StartServer();

	if(!ret)
		MessageBox(NULL, "StartServer Failed! Please make sure SIP port you set is not being used by another application!", "ERROR", MB_OK);

	Send_GetRegStatus(0);

	EnableChanVideo(0, GT_TRUE);
	ShowCameraWnd(GT_TRUE);

	return ret;
}

bool CGTSIPSimplePhoneEnv::StopServer()
{
	return CGTAPIEnv::StopServer();
}


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

	StopSound();

	//start directx audio control
	//if you are writing a server to handle media yourself, you don't need this
	Send_StartDXAudio(ch);
	
	sdkapp_msg* msg = new sdkapp_msg;
	msg->eventID = WM_SDKAPP_CONNECTED;
	msg->chanID = ch;
	
	if(m_pMainDlg)
		//It is safer to post a message to Main Window instead of directly calling here as it is in low level SDK thread
		//m_pMainDlg->On_RecvConnected(ch);
		m_pMainDlg->PostMessage(WM_SDKAPP_CONNECTED, 0, (LPARAM)msg);
}

void CGTSIPSimplePhoneEnv::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);

	//GTAPI_Channel* pChan = (GTAPI_Channel*)GetChannel(ch);

    StopSound();
    PlayLocalRingSound();

	//::MessageBox(NULL, GetChanSIPMsg(ch), "SIP INVITE", MB_OK);
	
	sdkapp_msg* msg = new sdkapp_msg;
	msg->eventID = WM_SDKAPP_OFFERED;
	msg->chanID = ch;
	msg->args[0] = sCaller;
	msg->args[1] = sCallee;
	msg->args[2] = sDestAddr;
	msg->args[3] = sViaAddr;
	msg->args[4] = sFromIP;
	msg->args[5].Format("%d", nFromPort);
	

	if(m_pMainDlg)
		//It is safer to post a message to Main Window instead of directly calling here as it is in low level SDK thread
		//m_pMainDlg->On_RecvOffered(ch, sCaller, sCallee, sDestAddr, sViaAddr, sFromIP, nFromPort);
		m_pMainDlg->PostMessage(WM_SDKAPP_OFFERED, 0, (LPARAM)msg);
}

void CGTSIPSimplePhoneEnv::On_RecvDialing(int ch, const char* sCaller, const char* sCallee)
{
	CGTAPIEnv::On_RecvDialing(ch, sCaller, sCallee);
	
	sdkapp_msg* msg = new sdkapp_msg;
	msg->eventID = WM_SDKAPP_DIALING;
	msg->chanID = ch;
	msg->args[0] = sCaller;
	msg->args[1] = sCallee;	

	if(m_pMainDlg)
		//It is safer to post a message to Main Window instead of directly calling here as it is in low level SDK thread
		//m_pMainDlg->On_RecvDialing(ch, sCaller, sCallee);
		m_pMainDlg->PostMessage(WM_SDKAPP_DIALING, 0, (LPARAM)msg);
}

void CGTSIPSimplePhoneEnv::On_RecvIdle(int ch, int code, const char* desc)
{
	CGTAPIEnv::On_RecvIdle(ch, code, desc);

    StopSound();
    
  	sdkapp_msg* msg = new sdkapp_msg;
	msg->eventID = WM_SDKAPP_IDLE;
	msg->chanID = ch;
	msg->args[0].Format("%d", code);
	msg->args[1] = desc;

	if(m_pMainDlg)
		//It is safer to post a message to Main Window instead of directly calling here as it is in low level SDK thread
		//m_pMainDlg->On_RecvIdle(ch, code, desc);
		m_pMainDlg->PostMessage(WM_SDKAPP_IDLE, 0, (LPARAM)msg);
}

void CGTSIPSimplePhoneEnv::On_RecvRinging(int ch)
{
	CGTAPIEnv::On_RecvRinging(ch);

    StopSound();
    PlayRemoteRingSound();
    
	sdkapp_msg* msg = new sdkapp_msg;
	msg->eventID = WM_SDKAPP_RINGING;
	msg->chanID = ch;    

	if(m_pMainDlg)
		//It is safer to post a message to Main Window instead of directly calling here as it is in low level SDK thread
		//m_pMainDlg->On_RecvRinging(ch);
		m_pMainDlg->PostMessage(WM_SDKAPP_RINGING, 0, (LPARAM)msg);
}

void CGTSIPSimplePhoneEnv::On_RecvRegStatus(int user_id, int status, int regtime)
{
	CGTAPIEnv::On_RecvRegStatus(user_id, status, regtime);
/*
	char sTemp[100];
	if(status)
	{
		sprintf(sTemp, "%s", CFG_GetValue("gtsrv.sip.reg1.authorization", ""));
	}
	else
	{
		sprintf(sTemp, "%s XXX!",  CFG_GetValue("gtsrv.sip.reg1.authorization", ""));
	}
*/

	sdkapp_msg* msg = new sdkapp_msg;
	msg->eventID = WM_SDKAPP_REGSTATUS;
	msg->chanID = user_id;
	msg->args[0].Format("%d", status);
	msg->args[1].Format("%d", regtime);

	if(m_pMainDlg)
		//It is safer to post a message to Main Window instead of directly calling here as it is in low level SDK thread
		//m_pMainDlg->On_RecvRegStatus(user_id, status, regtime);
		m_pMainDlg->PostMessage(WM_SDKAPP_REGSTATUS, 0, (LPARAM)msg);		
}

