📄 pocketsmdlg.cpp
字号:
// 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 + -