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

📄 pocketsmdlg.cpp

📁 Pocket SIP Messenger is a SIP instant messaging client for small devices that use Windows CE (iPAQ P
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// PocketSMDlg.cpp : implementation file 
//

#include "stdafx.h"
#include "PocketSM.h"
#include "PocketSMDlg.h"
#include "rfc2617.h"
#include <stdio.h>
#include <Mmsystem.h>

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

#define ID_TIMER_A		2001
#define TIMER_A_PERIOD	400
#define RET_MILISEC		500
#define MAX_CONTACTS	10
#define EOH				"\r\n"

////////////////////////////////////////////////////////////////////////////
// CPocketSMDlg dialog

/**
 * class constructor
 */
CPocketSMDlg::CPocketSMDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPocketSMDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CPocketSMDlg)
	m_strEditView = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_nIPPort = 5060;
	m_pCSock = new CAsyncSocket();
	//m_pCSock = NULL;
	m_strIPAddress = GetIP();
	m_strUserName = _T("");
	m_strSipSrvAddress = _T("");
	m_strUserPart = _T("");
	m_strSrvPart = _T("");
	m_strPassword = _T("");
	m_strAuthHdr = _T("");

	m_nSipSrvPort = 5060;
	m_nFlag = m_nCounter = m_nCallID = 0;
	m_bDlgHide = false;
	m_bTrayIcon = false;
	m_bSetupOK = false;
	m_dlgSetup = new CSetupDlg(this);
	size=first=last=0;
	MSG_LIST_SIZE = 10;
	m_strEditMsg = _T("");
}

/**
 * data exchange between controls and variables
 */
void CPocketSMDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPocketSMDlg)
	DDX_Control(pDX, IDC_BUTTON_SEND, m_ctlButtonSend);
	DDX_Control(pDX, IDC_EDIT_MSG, m_ctlEditMsg);
	DDX_Control(pDX, IDC_COMBO_TO, m_ctlComboTo);
	DDX_Text(pDX, IDC_EDIT_VIEW, m_strEditView);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPocketSMDlg, CDialog)

	ON_MESSAGE(WM_ICON_NOTIFY,OnIconNotify) // macro for message handler !!

	//{{AFX_MSG_MAP(CPocketSMDlg)
	ON_WM_TIMER()
	ON_WM_PAINT()
	ON_BN_CLICKED(IDC_BUTTON_SETUP, OnButtonSetup)
	ON_BN_CLICKED(IDC_BUTTON_HIDE, OnButtonHide)
	ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend)
	ON_BN_CLICKED(IDC_BUTTON_EXIT, OnButtonExit)
	ON_BN_CLICKED(ID_BUTTON_HIDE, OnButtonHide)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPocketSMDlg message handlers

/**
 * init dialog
 */
BOOL CPocketSMDlg::OnInitDialog()
{
	char userName[70], srvAddress[50];
	int srvPort;
	CString lStr;
	FILE *f = NULL;

	CDialog::OnInitDialog();

	DWORD nonblock = 1;

	// 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
	
	CenterWindow(GetDesktopWindow());	// center to the hpc screen

	// TODO: Add extra initialization here

	m_ctlComboTo.LimitText(100);
	if((f = fopen("psm.cfg", "rt")) != NULL)
	{
		if(fscanf(f, "%s%s%d", userName, srvAddress, &srvPort) == 3)
		{
			m_strUserName = userName;
			m_strSipSrvAddress = srvAddress;
			m_nSipSrvPort = srvPort;

			while(fscanf(f, "%s", userName) == 1)
			{
				lStr = userName;
				m_ctlComboTo.AddString(lStr);
			}
		}
		fclose(f);
	}
	m_dlgSetup->setUserName(m_strUserName);
	m_dlgSetup->setServerAddress(m_strSipSrvAddress);
	m_dlgSetup->setServerPort(m_nSipSrvPort);

	//m_strEditView = "Creating socket ...";
	//UpdateData(FALSE);

	if( m_pCSock == NULL )
		AfxMessageBox(_T("Warning when creating socket."));

	if(m_pCSock->Create(5060, SOCK_DGRAM) == 0)
	{
		AfxMessageBox(_T("Cannot create the socket! Please restart."));
	} 
	m_pCSock->IOCtl(FIONBIO, &nonblock);

	SetTimer(ID_TIMER_A, TIMER_A_PERIOD, 0);

	//m_strEditView.Format(_T("Listening on: %s:%d"), 
	//	m_strIPAddress, m_nIPPort);
	//UpdateData(FALSE);

	AddSystemTrayIcon();

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

/**
 * send REGISTER packet to SIP server
 */
int CPocketSMDlg::SendSIPRegister(char* expires, int nr)
{
	CString strBuf, strPort, callID;
	CString servAddress;
	UINT servPort;
	char outBuf[2048], pBuf[2048], callIDBuf[50];
	int i, l, n, f;
	CTime t = CTime::GetCurrentTime();

	if(m_nFlag != 1)
		return -1;

	m_bSetupOK = false;
	m_ctlButtonSend.EnableWindow(FALSE);

	UpdateCallID();
	callID.Format(_T("70710PkSM@%s.%08lX-%X"), m_strIPAddress, t.GetTime(), m_nCallID);
	l = callID.GetLength();
	for(i=0; i<l && i < 49; i++)
		callIDBuf[i] = (char)(callID.GetAt(i) & 0xFF);
	callIDBuf[i] = 0;

	strPort.Format(_T("%d"), m_nIPPort);

	strBuf="REGISTER sip:";
	strBuf += m_strSrvPart;

	strBuf += " SIP/2.0\r\nVia: SIP/2.0/UDP "+m_strIPAddress+":"+strPort;
    strBuf += "\r\nFrom: sip:"+m_strUserName;
    strBuf += "\r\nTo: sip:"+m_strUserName;
    strBuf += "\r\nCall-ID: "+callID;
    strBuf += "\r\nCSeq: 1 REGISTER\r\nContact: <sip:"
		+m_strIPAddress+":"+strPort+";transport=udp>;methods=\"MESSAGE\"\r\nExpires: ";
	strBuf += expires;
    strBuf += "\r\nUser-Agent: PocketSipM v0.1\r\nContent-Length: 0\r\n\r\n";

	// convert from UNICODE to ASCII
	l = strBuf.GetLength();
	for(i=0; i<l; i++)
		outBuf[i] = (char)(strBuf.GetAt(i) & 0xFF);
	
	n = 1;
	f = 0;

	/*** clean up the socket buffer ***/
	while(m_pCSock->ReceiveFrom((void*)pBuf, 2047, servAddress, servPort) > 0)
		Sleep(10);

	while(n < nr+1)
	{
		i = m_pCSock->SendTo(outBuf, l, m_nSipSrvPort, (LPCTSTR)m_strSipSrvAddress);
		if(i == SOCKET_ERROR || i != l)
			return -1;
		Sleep(RET_MILISEC);
		i = m_pCSock->ReceiveFrom((void*)pBuf, 2047, servAddress, servPort);
		if(i > 0)
		{
			pBuf[i] = 0;
			if(!strncmp(pBuf, "SIP/2.0 ", 8) && strstr(pBuf, callIDBuf))
			{
				if(*(pBuf+8) == '2')
				{
					if(expires && expires[0]!='0')
					{
						m_bSetupOK = true;
						m_ctlButtonSend.EnableWindow(TRUE);
					}
					return 0;
				}
				if(*(pBuf+8) == '3' || *(pBuf+8) == '5' || *(pBuf+8) == '6')
					return -1;
				if(*(pBuf+8) == '4' && *(pBuf+9) == '0' && *(pBuf+10) == '1')
				{
					f = 1;
					break;
				}
				else
					return -1;
			}
		}
		n++;
	}
	if(f!=1)
		return -1;
	if(computeAuthHeader(pBuf)<0)
		return -1;

	UpdateCallID();
	callID.Format(_T("70710PkSM@%s.%08lX-%X"), m_strIPAddress, t.GetTime(), m_nCallID);
	l = callID.GetLength();
	for(i=0; i<l && i < 49; i++)
		callIDBuf[i] = (char)(callID.GetAt(i) & 0xFF);
	callIDBuf[i] = 0;

	strBuf="REGISTER sip:";
	strBuf += m_strSrvPart;

	strBuf += " SIP/2.0\r\nVia: SIP/2.0/UDP "+m_strIPAddress+":"+strPort;
    strBuf += "\r\nFrom: sip:"+m_strUserName;
    strBuf += "\r\nTo: sip:"+m_strUserName;
    strBuf += "\r\nCall-ID: "+callID;
    strBuf += "\r\nCSeq: 2 REGISTER\r\nContact: <sip:"
		+m_strIPAddress+":"+strPort+";transport=udp>;methods=\"MESSAGE\"\r\nExpires: ";
	strBuf += expires;
	strBuf += "\r\n"+m_strAuthHdr;
    strBuf += "\r\nUser-Agent: PocketSipM v0.1\r\nContent-Length: 0\r\n\r\n";

	// convert from UNICODE to ASCII
	l = strBuf.GetLength();
	for(i=0; i<l; i++)
		outBuf[i] = (char)(strBuf.GetAt(i) & 0xFF);
	
	n = 1;
	/*** clean up the socket buffer ***/
	while(m_pCSock->ReceiveFrom((void*)pBuf, 2047, servAddress, servPort) > 0)
		Sleep(10);
	while(n < nr+1)
	{
		i = m_pCSock->SendTo(outBuf, l, m_nSipSrvPort, (LPCTSTR)m_strSipSrvAddress);
		if(i == SOCKET_ERROR || i != l)
			return -1;
		Sleep(RET_MILISEC);
		i = m_pCSock->ReceiveFrom((void*)pBuf, 2047, servAddress, servPort);
		if(i > 0)
		{
			pBuf[i] = 0;
			if(!strncmp(pBuf, "SIP/2.0 ", 8) && strstr(pBuf, callIDBuf))
			{
				if(*(pBuf+8) == '2')
				{
					if(expires && expires[0]!='0')
					{
						m_bSetupOK = true;
						m_ctlButtonSend.EnableWindow(TRUE);
					}
					return 0;
				}
				if(*(pBuf+8) == '3' || *(pBuf+8) == '4' || *(pBuf+8) == '5' || *(pBuf+8) == '6')
					return -1;
			}
		}
		n++;
	}
	return -1;
}

/**
 * send MESSAGE packet to SIP server
 */
int CPocketSMDlg::SendSIPMessage(CString to, CString body, int nr)
{
	CString strBuf, strPort, callID;
	CString servAddress;
	UINT servPort;
	char outBuf[2048], pBuf[1024], callIDBuf[50];
	int i, l, n;
	CTime t = CTime::GetCurrentTime();

	if(!m_bSetupOK)
		return -1;

	strPort.Format(_T("%d"), m_nIPPort);
	UpdateCallID();
	callID.Format(_T("8923PkSM@%s.%08lX-%X"), m_strIPAddress, t.GetTime(), m_nCallID);
	l = callID.GetLength();
	for(i=0; i<l && i < 49; i++)
		callIDBuf[i] = (char)(callID.GetAt(i) & 0xFF);
	callIDBuf[i] = 0;

	strBuf="MESSAGE sip:";
	strBuf += to;

	strBuf += " SIP/2.0\r\nVia: SIP/2.0/UDP "+m_strIPAddress+":"+strPort;
    strBuf += "\r\nFrom: sip:"+m_strUserName;
    strBuf += ";tag=a8437-3mkdsf-9474kjf-2323\r\nTo: sip:"+to;
    strBuf += "\r\nCall-ID: "+callID;
    strBuf += "\r\nCSeq: 1 MESSAGE\r\nContact: <sip:"
		+m_strUserName+">\r\nContent-Type: text/plain; charset=UTF-8";
    strBuf += "\r\nUser-Agent: PocketSipM v0.1\r\nContent-Length: ";
	strPort.Format(_T("%d"), body.GetLength());
	strBuf += strPort+"\r\n\r\n";
	strBuf += body;

	// convert from UNICODE to ASCII
	l = strBuf.GetLength();
	for(i=0; i<l; i++)
		outBuf[i] = (char)(strBuf.GetAt(i) & 0xFF);
	
	n = 1;
	/*** clean up the socket buffer ***/
	while(m_pCSock->ReceiveFrom((void*)pBuf, 2047, servAddress, servPort) > 0)
		Sleep(10);
	while(n < nr+1)
	{
		i = m_pCSock->SendTo(outBuf, l, m_nSipSrvPort, (LPCTSTR)m_strSipSrvAddress);
		if(i == SOCKET_ERROR || i != l)
			return -1;
		Sleep(RET_MILISEC);
		i = m_pCSock->ReceiveFrom((void*)pBuf, 1023, servAddress, servPort);
		if(i > 0)
		{
			pBuf[i] = 0;
			if(!strncmp(pBuf, "SIP/2.0 ", 8) && strstr(pBuf, callIDBuf))
			{
				if(*(pBuf+8) == '2')
				{
					AddSentMessage(to, body);
					UpdateDisplayedMessage();
					return 0;
				}
				if(*(pBuf+8) == '3' || *(pBuf+8) == '4' 
						|| *(pBuf+8) == '5' || *(pBuf+8) == '6')
					return -1;
			}
		}
		n++;
	}
	return -1;
}

/**
 * get local IP address
 */
CString CPocketSMDlg::GetIP()
{
	CString strIp;

	//Init winsock
	WSADATA wsaData;
	int nErrorCode = WSAStartup(MAKEWORD(1,1), &wsaData);
	if (nErrorCode != 0) {
		//Cannot initialize winsock
		return _T("");
	}

	char strHostName[81];
	if (gethostname(strHostName, 80)==0)
	{
		hostent *pHost = gethostbyname(strHostName);
		if (pHost->h_addrtype == AF_INET)
		{
			in_addr **ppip=(in_addr**)pHost->h_addr_list; 
			
			//Enumarate all addresses
			while (*ppip) 
			{
				in_addr ip=**ppip;
				strIp = CString(inet_ntoa(ip));
				ppip++; 
				if (strIp!=_T("")) {
					break;
				}
			}
		}
	}

	return strIp;
}


/**
 * timer handler
 */
void CPocketSMDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	CString servAddress;
	int nrBytes=1, nBufLen = 2047;
	UINT servPort;
	char pBuf[2048], oBuf[1024], c, c1;
	str from, body, res;
	CTime crtTime;

	if(nIDEvent == ID_TIMER_A && m_bSetupOK)
	{
		m_nCounter++;
		if(m_nCounter > 3000)
		{
			m_nCounter = 0;
			if(SendSIPRegister("3600", 10) != 0)
			{
				AddInfoMessage("Can not register again. Please restart\r\n");
				UpdateDisplayedMessage();
			}
		}


		res.s = oBuf;
		res.len = 1024;
		// check for MESSAGE messages
		nrBytes = m_pCSock->ReceiveFrom((void*)pBuf, nBufLen, servAddress, servPort);
		while(nrBytes > 7 && (strncmp(pBuf, "MESSAGE", 7) == 0))
		{
			crtTime = CTime::GetCurrentTime();
			pBuf[nrBytes] = 0;
			if(!m_sipMsg.isIdentic(pBuf, nrBytes))
			{
				m_sipMsg.setSIPMsg(pBuf, nrBytes);
				if(!m_bTrayIcon && m_bDlgHide)
				{
					m_bTrayIcon = true;
					SetNewTrayIcon();
				}
				if(m_sipMsg.getFrom(&from) == 0 && m_sipMsg.getBody(&body) == 0)
				{
					// build response
					m_sipMsg.buildResponse(&res, "SIP/2.0 200 OK\r\n", m_strIPAddress, m_nIPPort);
					// send response
					m_pCSock->SendTo(res.s, res.len, m_nSipSrvPort, (LPCTSTR)m_strSipSrvAddress);

					// display to user
					c = from.s[from.len];
					from.s[from.len] = 0;
					c1 = body.s[body.len];
					body.s[body.len] = 0;
					AddRecvMessage(from.s, body.s, crtTime);
					from.s[from.len] = c;
					body.s[body.len] = c1;
					
					UpdateDisplayedMessage();
					PlaySound(TEXT("DOORBELL"), GetModuleHandle(NULL), SND_RESOURCE | SND_ASYNC);
					//PlaySound (TEXT("bell.wav"), NULL, SND_SYNC);

				}
				else
				{
					// build response
					m_sipMsg.buildResponse(&res, "SIP/2.0 400 Bad request\r\n", m_strIPAddress, m_nIPPort);
					// send response
					m_pCSock->SendTo(res.s, res.len, m_nSipSrvPort, (LPCTSTR)m_strSipSrvAddress);
					
					// display to user
					AddInfoMessage("Wrong formatted MESSAGE received");
					UpdateDisplayedMessage();
				}

			}
			/***
			else
			{
				m_strEditView = "Non MESSAGE received";
				UpdateData(FALSE);
			}
			***/
			nrBytes = m_pCSock->ReceiveFrom((void*)pBuf, nBufLen, servAddress, servPort);
		}
	}
	else
		if(!m_bSetupOK)
		{
			//AddInfoMessage("Config params are not set!\r\nClick on 'Setup' to set them");
			//UpdateDisplayedMessage();
		}
	CDialog::OnTimer(nIDEvent);
}

/**
 * PAINT event - callback function
 */
void CPocketSMDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	CBitmap bmp, *poldbmp;
	CDC memdc;

	// Load the bitmap resource
	bmp.LoadBitmap( IDB_BITMAP_IPTEL );

	// Create a compatible memory DC
	memdc.CreateCompatibleDC( &dc );

	// Select the bitmap into the DC
	poldbmp = memdc.SelectObject( &bmp );

	// Copy (BitBlt) bitmap from memory DC to screen DC
	dc.BitBlt( 0, 0, 240, 300, &memdc, 0, 0, SRCCOPY );

	memdc.SelectObject( poldbmp );

	// Do not call CDialog::OnPaint() for painting messages
}

/**
 *
 */
void CPocketSMDlg::OnOK() 
{
	FILE *f = NULL;
	char userName[70], srvAddress[50];
	int i, j;
	CString lStr;

	// TODO: Add extra validation here
	if(m_bSetupOK)
		SendSIPRegister("0", 2);

	// remove icon from system tray
	RemoveSystemTrayIcon();

	// close the SOCKET
	if( m_pCSock != NULL )
		m_pCSock->Close();
	
	if((f = fopen("psm.cfg", "wt")) != NULL)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -