// IrdaMobileDlg.cpp : Implementierungsdatei
//
#include "stdafx.h"
#include "IrdaMobile.h"
#include "IrdaMobileDlg.h"
#include "IrdaPort.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
#define TIMEOUT 5000 // Timeout for the phone response in milliseconds
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg-Dialogfeld f�r Anwendungsbefehl "Info"
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialogfelddaten
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// Vom Klassenassistenten generierte �berladungen virtueller Funktionen
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterst�tzung
//}}AFX_VIRTUAL
// Implementierung
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)
// Keine Nachrichten-Handler
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIrdaMobileDlg Dialogfeld
CIrdaMobileDlg::CIrdaMobileDlg(CWnd* pParent /*=NULL*/)
: CDialog(CIrdaMobileDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CIrdaMobileDlg)
//}}AFX_DATA_INIT
// Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf ben�tigt
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CIrdaMobileDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CIrdaMobileDlg)
DDX_Control(pDX, IDC_LIST1, m_ctrlList);
DDX_Control(pDX, IDC_COMBO1, m_ctrlPort);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CIrdaMobileDlg, CDialog)
//{{AFX_MSG_MAP(CIrdaMobileDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnRead)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIrdaMobileDlg Nachrichten-Handler
BOOL CIrdaMobileDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Hinzuf�gen des Men�befehls "Info..." zum Systemmen�.
// IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
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);
}
}
// Symbol f�r dieses Dialogfeld festlegen. Wird automatisch erledigt
// wenn das Hauptfenster der Anwendung kein Dialogfeld ist
SetIcon(m_hIcon, TRUE); // Gro�es Symbol verwenden
SetIcon(m_hIcon, FALSE); // Kleines Symbol verwenden
// ZU ERLEDIGEN: Hier zus�tzliche Initialisierung einf�gen
m_ctrlPort.ResetContent();
for (int n = 0; n < 255; n++)
{
CString str;
str.Format(_T("COM%d"), n + 1);
m_ctrlPort.InsertString(n,str);
}
const int nPort = 3; // CIrdaPort::FindPortIndex();
m_ctrlPort.SetCurSel((nPort > 0 && nPort <= 255) ? (nPort - 1) : 2);
m_ctrlList.InsertColumn(0, _T("Name"), LVCFMT_LEFT);
m_ctrlList.InsertColumn(1, _T("Number"), LVCFMT_LEFT);
CRect rect;
m_ctrlList.GetClientRect(rect);
m_ctrlList.SetColumnWidth(0, rect.Width() / 2);
m_ctrlList.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER);
return TRUE; // Geben Sie TRUE zur�ck, au�er ein Steuerelement soll den Fokus erhalten
}
void CIrdaMobileDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// Wollen Sie Ihrem Dialogfeld eine Schaltfl�che "Minimieren" hinzuf�gen, ben�tigen Sie
// den nachstehenden Code, um das Symbol zu zeichnen. F�r MFC-Anwendungen, die das
// Dokument/Ansicht-Modell verwenden, wird dies automatisch f�r Sie erledigt.
void CIrdaMobileDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // Ger�tekontext f�r Zeichnen
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Symbol in Client-Rechteck zentrieren
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;
// Symbol zeichnen
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// Die Systemaufrufe fragen den Cursorform ab, die angezeigt werden soll, w�hrend der Benutzer
// das zum Symbol verkleinerte Fenster mit der Maus zieht.
HCURSOR CIrdaMobileDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CIrdaMobileDlg::OnRead()
{
// TODO: Add your control notification handler code here
CString strResponse;
CWaitCursor wait;
///////////////////////////////////////////////////////////////////////////
//
// Try to open the IRDA port.
//
UpdateData(TRUE);
const int nPort = m_ctrlPort.GetCurSel() + 1;
if (nPort <= 0 || nPort > 255)
{
AfxMessageBox(_T("Invalid IRDA port."));
return;
}
CIrdaPort port;
if (!port.Open(nPort))
{
AfxMessageBox(_T("Failed to open IRDA port."));
return;
}
GetDlgItem(IDC_PHONE)->SetWindowText(_T(""));
GetDlgItem(IDC_PHONE)->UpdateWindow();
GetDlgItem(IDC_MODEL)->SetWindowText(_T(""));
GetDlgItem(IDC_MODEL)->UpdateWindow();
GetDlgItem(IDC_ENTRIES)->SetWindowText(_T("0 Entries"));
GetDlgItem(IDC_ENTRIES)->UpdateWindow();
m_ctrlList.DeleteAllItems();
m_ctrlList.Invalidate();
m_ctrlList.UpdateWindow();
///////////////////////////////////////////////////////////////////////////
//
// Try to connect to the Mobile Phone.
//
// Command : AT<CR>
//
// Valid response: <CR><LF>OK<CR><LF>
//
// Error response: <CR><LF>ERROR<CR><LF>
//
// <CR> ... Carriage return
// <LF> ... Line feed
//
if (!port.Send(_T("AT"), TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Failed to write request to device."));
return;
}
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
strResponse.MakeUpper();
if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
else if (strResponse.Find(_T("OK")) == -1)
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
///////////////////////////////////////////////////////////////////////////
//
// Request the manufacturer identification.
//
// Command : AT+CGMI<CR>
//
// Valid response: <CR><LF>manufacturer<CR><LF>
// <CR><LF>OK<CR><LF>
//
// manufacturer ... manufacturer identification
//
// Error response: <CR><LF>ERROR<CR><LF>
//
// <CR> ... Carriage return
// <LF> ... Line feed
//
if (!port.Send(_T("AT+CGMI"), TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Failed to write request to device."));
return;
}
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
const CString strPhone(strResponse);
strResponse.MakeUpper();
if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
strResponse.MakeUpper();
if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
else if (strResponse.Find(_T("OK")) == -1)
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
GetDlgItem(IDC_PHONE)->SetWindowText(strPhone);
GetDlgItem(IDC_PHONE)->UpdateWindow();
///////////////////////////////////////////////////////////////////////////
//
// Request the model identification.
//
// Command : AT+CGMM<CR>
//
// Valid response: <CR><LF>model<CR><LF>
// <CR><LF>OK<CR><LF>
//
// model ... model identification
//
// Error response: <CR><LF>ERROR<CR><LF>
//
// <CR> ... Carriage return
// <LF> ... Line feed
//
if (!port.Send(_T("AT+CGMM"), TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Failed to write request to device."));
return;
}
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
const CString strModel(strResponse);
strResponse.MakeUpper();
if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
strResponse.MakeUpper();
if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
else if (strResponse.Find(_T("OK")) == -1)
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
GetDlgItem(IDC_MODEL)->SetWindowText(strModel);
GetDlgItem(IDC_MODEL)->UpdateWindow();
///////////////////////////////////////////////////////////////////////////
//
// Select the phonebook memory storage where phonebook commands operate.
//
// Command : AT+CPBS=storage<CR>
//
// storage ... memory where phonebook commands operate
//
// "FD" ... SIM fixdialling-phonebook
// "LD" ... SIM last-dialling-phonebook
// "ME" ... ME phonebook
// "MT" ... combined ME and SIM phonebook
// "SM" ... SIM phonebook
// "TA" ... TA phonebook
//
// Valid response: <CR><LF>OK<CR><LF>
//
// Error response: <CR><LF>ERROR<CR><LF>
//
// <CR> ... Carriage return
// <LF> ... Line feed
//
if (!port.Send(_T("AT+CPBS=\"SM\""), TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Failed to write request to device."));
return;
}
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
strResponse.MakeUpper();
if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
else if (strResponse.Find(_T("OK")) == -1)
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
///////////////////////////////////////////////////////////////////////////
//
// Read the size of the selected phonebook memory.
//
// Command : AT+CPBR=?<CR>
//
// Valid response: <CR><LF>+CPBR: (index-list),nlength,tlength<CR><LF>
// <CR><LF>OK<CR><LF>
//
// index ..... integer type values in the range of
// location numbers of phonebook memory
// list ...... integer type value indicating the size of
// the selected phonebook memory
// nlength ... integer type value indicating the maximum
// length of the number field
// tlength ... integer type value indicating the maximum
// length of name field
//
// Error response: <CR><LF>ERROR<CR><LF>
//
// <CR> ... Carriage return
// <LF> ... Line feed
//
if (!port.Send(_T("AT+CPBR=?"), TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Failed to write request to device."));
return;
}
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
const CString strMemory(strResponse);
strResponse.MakeUpper();
// Check the response
int nPhoneBookSize = 0;
if (strResponse.Find(_T("CPBR")) > -1)
{
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
strResponse.MakeUpper();
if (strResponse.Find(_T("OK")) > -1)
{
// Get the size of the phonebook memory
const int nStart = strMemory.Find(_T('-'));
const int nEnd = strMemory.Find(_T(')'), nStart + 1);
nPhoneBookSize = _ttoi((LPCTSTR) strMemory.Mid(nStart + 1, nEnd - nStart - 1));
ASSERT(nPhoneBookSize >= 0);
// AfxMessageBox(strMemory.Mid(nStart + 1, nEnd - nStart - 1));
}
else
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
}
else if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
else
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
///////////////////////////////////////////////////////////////////////////
//
// Read all phonebook entries.
//
// Command : AT+CPBR=index<CR>
//
// index ... integer type values in the range of
// location numbers of phonebook memory
//
// Valid response: <CR><LF>+CPBR: index, "number", type, "name"<CR><LF>
// <CR><LF>OK<CR><LF>
//
// index .... integer type values in the range of
// location numbers of phonebook memory
// number ... string type phone number of format type
// type ..... type of address octet in integer format
// name ..... the name of the phonebook entry
//
// Response for
// an empty entry: <CR><LF>OK<CR><LF>
//
// Error response: <CR><LF>ERROR<CR><LF>
//
// <CR> ... Carriage return
// <LF> ... Line feed
//
int nNumberOfEntries = 0;
for (int n = 1; n <= nPhoneBookSize; n++)
{
CString strCommand;
strCommand.Format(_T("AT+CPBR=%d"), n);
if (!port.Send(strCommand, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Failed to write request to device."));
return;
}
// Wait for response
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
const CString strEntry(strResponse);
strResponse.MakeUpper();
// Check the response
if (strResponse.Find(_T("CPBR")) > -1)
{
if (!port.WaitForResponse(strResponse, TIMEOUT))
{
port.Close();
AfxMessageBox(_T("Timeout, no response."));
return;
}
strResponse.MakeUpper();
if (strResponse.Find(_T("OK")) > -1)
{
// Insert the name and the number in the list box
int nStart = strEntry.Find(_T('\"'));
int nEnd = strEntry.Find(_T('\"'), nStart + 1);
const CString strNumber = strEntry.Mid(nStart + 1, nEnd - nStart - 1);
// AfxMessageBox(strNumber);
nStart = strEntry.Find(_T('\"'), nEnd + 1);
nEnd = strEntry.Find(_T('\"'), nStart + 1);
const CString strName = strEntry.Mid(nStart + 1, nEnd - nStart - 1);
// AfxMessageBox(strName);
m_ctrlList.InsertItem(0, strName);
m_ctrlList.SetItemText(0, 1, strNumber);
m_ctrlList.Update(n);
CString strEntries;
strEntries.Format(_T("%d Entries"), ++nNumberOfEntries);
GetDlgItem(IDC_ENTRIES)->SetWindowText(strEntries);
GetDlgItem(IDC_ENTRIES)->UpdateWindow();
}
else
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
}
else if (strResponse.Find(_T("OK")) > -1)
{
continue; // empty phonebook entry
}
else if (strResponse.Find(_T("ERROR")) > -1)
{
port.Close();
AfxMessageBox(_T("Invalid command."));
return;
}
else
{
port.Close();
AfxMessageBox(_T("Wrong response."));
return;
}
}
///////////////////////////////////////////////////////////////////////////
//
// Close the IRDA port.
//
port.Close();
}