Click here to Skip to main content
Click here to Skip to main content

IntelliPort

, 21 Jul 2014 Zlib
Rate this:
Please Sign up or sign in to vote.
An alternative Windows version to the famous HyperTerminal

HyperTerminal

Introduction

As you already know, Microsoft has dropped the development of HyperTerminal starting with Windows 7. IntelliPort is a program that you can use to connect to other computers, using either your null modem cable or Ethernet connection. IntelliPort records the messages passed to and from the computer on the other end of your connection. Therefore, it can serve as a valuable troubleshooting tool when setting up and using your modem. To make sure that your modem is connected properly or to view your modem's settings, you can send commands through IntelliPort and check the results. IntelliPort has scroll functionality that allows you to look at received text that has scrolled off the screen. You can use IntelliPort to transfer large files from a computer onto your portable computer using a serial port rather than going through the process of setting up your portable computer on a network. IntelliPort is designed to be an easy-to-use tool and is not meant to replace other full-feature tools available on the market. You can use IntelliPort to perform the specific tasks described above, but do not attempt to use IntelliPort for more complex communication needs.

Background

The main purpose of this MFC application is to get logs via serial port or UDP socket from embedded systems, such as EFTPOS devices, and it is based on PJ Naughter's CSerialPort and CWSocket classes. For those who do not know, EFTPOS is the method for paying for goods or services without needing to carry cash. On making a purchase, the EFTPOS customer gives an EFTPOS card to the cashier who inserts it into an on-site EFTPOS machine. When the EFTPOS customer confirms the purchase, either by signature or security PIN, the EFTPOS equipment contacts the store's bank electronically about the transaction. A message is also sent to the customer's bank. Unless there is reason for the EFTPOS transaction not to be completed, the funds will then be transferred between the two accounts. The EFTPOS transaction takes a matter of only a few seconds. Before the EFTPOS customer has had the goods put into a bag, the EFTPOS transaction will be complete. Confirmation of the EFTPOS transaction is sent to the store and passed on to the customer in the form of a printed EFTPOS transaction record.

How Do I Get Started?

First, configure the MFC application to get logs from either serial port or TCP/UDP socket connection. Please check the CConfigureDlg class for implementation details.

Configure serial port or TCP/UDP socket

Next, now you can connect/disconnect from your data source. Please check the OnOpenSerialPort and OnCloseSerialPort functions for implementation details.

Reading/Writing data to serial port or TCP/UDP socket

void CMainFrame::OnOpenSerialPort()
{
   CString strMessage;
   switch (theApp.GetInt(_T("Connection"), 0))
   {
      case 0:
      {
         m_pSerialPort.Open(
            (LPCTSTR) theApp.GetString
            (_T("SerialName"), _T("COM1")),
            theApp.GetInt(_T("BaudRate"), CBR_115200),
            (CSerialPort::Parity) theApp.GetInt
            (_T("Parity"), CSerialPort::NoParity),
            (BYTE) theApp.GetInt(_T("DataBits"), 8),
            (CSerialPort::StopBits) theApp.GetInt
            (_T("StopBits"), CSerialPort::OneStopBit),
            (CSerialPort::FlowControl) theApp.GetInt
            (_T("FlowControl"), CSerialPort::NoFlowControl),
            FALSE);

         if (m_pSerialPort.IsOpen())
         {
            m_nThreadRunning = TRUE;
            AfxBeginThread(SerialPortThreadFunc, this);
            strMessage.Format(_T("Serial port %s has been opened."), 
            theApp.GetString(_T("SerialName"), _T("COM1")));
            SetCaptionBarText(strMessage);
         }
         break;
      }
      case 1:
      case 2:
      {
         CString strServerIP = theApp.GetString
         (_T("ServerIP"), _T("127.0.0.1"));
         if (strServerIP.IsEmpty()) strServerIP = _T("127.0.0.1");
         const UINT nServerPort = 
         theApp.GetInt(_T("ServerPort"), 0);
         CString strClientIP = theApp.GetString
         (_T("ClientIP"), _T("127.0.0.1"));
         if (strClientIP.IsEmpty()) strClientIP = _T("127.0.0.1");
         const UINT nClientPort = 
         theApp.GetInt(_T("ClientPort"), 0);

         m_pSocket.SetBindAddress(strClientIP);
         m_pSocket.CreateAndBind(nClientPort, ((theApp.GetInt
         (_T("Connection"), 0) == 1) ? SOCK_STREAM : SOCK_DGRAM), AF_INET);

         if (m_pSocket.IsCreated())
         {
            if (theApp.GetInt(_T("Connection"), 0) == 1) // TCP Socket
            {
               if (theApp.GetInt(_T("SocketType"), 0) == 1) // Client
               {
                  m_pSocket.Connect(strServerIP, nServerPort);
               }
               else // TCP Server
               {
                  m_dlgIncoming.ShowWindow(SW_SHOW);
                  m_dlgIncoming.CenterWindow(this);
                  m_dlgIncoming.Invalidate();
                  m_dlgIncoming.UpdateWindow();
                  m_pSocket.Listen();
                  m_pSocket.Accept(m_pIncomming);
                  m_dlgIncoming.ShowWindow(SW_HIDE);
               }
            }
            else // UDP Socket
            {
            }

            m_nThreadRunning = TRUE;
            AfxBeginThread(SocketThreadFunc, this);
            strMessage.Format(_T("%s socket %s:%d has been created."), 
            ((theApp.GetInt(_T("Connection"), 0) == 1) ? 
            _T("TCP") : _T("UDP")), strServerIP, nServerPort);
            SetCaptionBarText(strMessage);
         }
         break;
      }
   }
}

void CMainFrame::OnCloseSerialPort()
{
   CString strMessage;
   m_nThreadRunning = FALSE;
   ::Sleep(1000);
   switch (theApp.GetInt(_T("Connection"), 0))
   {
      case 0:
      {
         m_pSerialPort.Close();

         if (!m_pSerialPort.IsOpen())
         {
            strMessage.Format(_T("Serial port %s has been closed."), 
            theApp.GetString(_T("SerialName"), _T("COM1")));
            SetCaptionBarText(strMessage);
         }
         break;
      }
      case 1:
      case 2:
      {
         CString strServerIP = theApp.GetString
         (_T("ServerIP"), _T("127.0.0.1"));
         if (strServerIP.IsEmpty()) strServerIP = _T("127.0.0.1");
         const UINT nServerPort = theApp.GetInt(_T("ServerPort"), 0);

         m_pSocket.Close();
         m_pIncomming.Close();

         if (!m_pSocket.IsCreated())
         {
            strMessage.Format(_T("%s socket %s:%d has been closed."), 
            ((theApp.GetInt(_T("Connection"), 0) == 1) ? 
            _T("TCP") : _T("UDP")), strServerIP, nServerPort);
            SetCaptionBarText(strMessage);
         }
         break;
      }
   }
}

void CMainFrame::OnSendReceive()
{
   CInputDlg dlgInput(this);
   if (dlgInput.DoModal() == IDOK)
   {
      CStringA pBuffer(dlgInput.m_strSendData);
      const int nLength = pBuffer.GetLength();

      switch (theApp.GetInt(_T("Connection"), 0))
      {
         case 0:
         {
            m_pMutualAccess.Lock();
            m_pSerialPort.Write
            (pBuffer.GetBufferSetLength(nLength), nLength);
            m_pMutualAccess.Unlock();
            pBuffer.ReleaseBuffer();
            break;
         }
         case 1:
         case 2:
         {
            CString strServerIP = theApp.GetString
            (_T("ServerIP"), _T("127.0.0.1"));
            if (strServerIP.IsEmpty()) strServerIP = _T("127.0.0.1");
            const UINT nServerPort = theApp.GetInt(_T("ServerPort"), 0);
            // CString strClientIP = theApp.GetString
            (_T("ClientIP"), _T("127.0.0.1"));
            // if (strClientIP.IsEmpty()) strClientIP = _T("127.0.0.1");
            // const UINT nClientPort = theApp.GetInt(_T("ClientPort"), 0);

            if (theApp.GetInt(_T("Connection"), 0) == 1) // TCP Socket
            {
               if (theApp.GetInt(_T("SocketType"), 0) == 1) // Client
               {
                  if (m_pSocket.IsWritable(1000))
                  {
                     m_pMutualAccess.Lock();
                     m_pSocket.Send
                     (pBuffer.GetBufferSetLength(nLength), nLength, 0);
                     pBuffer.ReleaseBuffer();
                     m_pMutualAccess.Unlock();
                  }
               }
               else
               {
                  if (m_pIncomming.IsWritable(1000))
                  {
                     m_pMutualAccess.Lock();
                     m_pIncomming.Send
                     (pBuffer.GetBufferSetLength(nLength), nLength, 0);
                     pBuffer.ReleaseBuffer();
                     m_pMutualAccess.Unlock();
                  }
               }
            }
            else
            {
               if (m_pSocket.IsWritable(1000))
               {
                  m_pMutualAccess.Lock();
                  m_pSocket.SendTo(pBuffer.GetBufferSetLength(nLength), 
                  nLength, nServerPort, strServerIP, 0);
                  pBuffer.ReleaseBuffer();
                  m_pMutualAccess.Unlock();
               }
            }
            break;
         }
      }
   }
}

Points of Interest

In order to be GUI responsive, the MFC application does the reading in separate working threads:

UINT SerialPortThreadFunc(LPVOID pParam)
{
   COMSTAT status = { 0, };
   char pBuffer[0x1000] = { 0, };
   CMainFrame* pMainFrame = (CMainFrame*) pParam;
   CRingBuffer& pRingBuffer = pMainFrame->m_pRingBuffer;
   CSerialPort& pSerialPort = pMainFrame->m_pSerialPort;
   CMutex& pMutualAccess = pMainFrame->m_pMutualAccess;

   while (pMainFrame->m_nThreadRunning)
   {
      memset(&status, 0, sizeof(status));
      pSerialPort.GetStatus(status);
      if (status.cbInQue > 0)
      {
         memset(pBuffer, 0, sizeof(pBuffer));
         const int nLength = 
         pSerialPort.Read(pBuffer, sizeof(pBuffer));
         pMutualAccess.Lock();
         pRingBuffer.WriteBinary(pBuffer, nLength);
         pMutualAccess.Unlock();
      }
      ::Sleep(10);
   }
   return 0;
}

UINT SocketThreadFunc(LPVOID pParam)
{
   char pBuffer[0x1000] = { 0, };
   CMainFrame* pMainFrame = (CMainFrame*) pParam;
   CRingBuffer& pRingBuffer = pMainFrame->m_pRingBuffer;
   CWSocket& pSocket = pMainFrame->m_pSocket;
   CWSocket& pIncomming = pMainFrame->m_pIncomming;
   CMutex& pMutualAccess = pMainFrame->m_pMutualAccess;
   BOOL bIsTCP = (theApp.GetInt(_T("Connection"), 0) == 1);
   BOOL bIsClient = (theApp.GetInt(_T("SocketType"), 0) == 1);

   CString strServerIP = theApp.GetString
   (_T("ServerIP"), _T("127.0.0.1"));
   if (strServerIP.IsEmpty()) strServerIP = _T("127.0.0.1");
   UINT nServerPort = theApp.GetInt(_T("ServerPort"), 0);

   while (pMainFrame->m_nThreadRunning)
   {
      if (bIsTCP)
      {
         if (bIsClient)
         {
            if (pSocket.IsReadible(1000))
            {
               memset(pBuffer, 0, sizeof(pBuffer));
               const int nLength = 
               pSocket.Receive(pBuffer, sizeof(pBuffer), 0);
               pMutualAccess.Lock();
               pRingBuffer.WriteBinary(pBuffer, nLength);
               pMutualAccess.Unlock();
            }
         }
         else
         {
            if (pIncomming.IsReadible(1000))
            {
               memset(pBuffer, 0, sizeof(pBuffer));
               const int nLength = 
               pIncomming.Receive(pBuffer, sizeof(pBuffer), 0);
               pMutualAccess.Lock();
               pRingBuffer.WriteBinary(pBuffer, nLength);
               pMutualAccess.Unlock();
            }
         }
      }
      else
      {
         if (pSocket.IsReadible(1000))
         {
            memset(pBuffer, 0, sizeof(pBuffer));
            const int nLength = pSocket.ReceiveFrom
            (pBuffer, sizeof(pBuffer), strServerIP, nServerPort, 0);
            pMutualAccess.Lock();
            pRingBuffer.WriteBinary(pBuffer, nLength);
            pMutualAccess.Unlock();
         }
      }
      ::Sleep(10);
   }
   return 0;
}

Final Words

IntelliPort application uses many components that have been published on The Code Project. Many thanks to:

  • PJ Naughter for his EnumSerialPorts class
  • Larry Antram for his CRingBuffer class
  • PJ Naughter for his CSerialPort class
  • PJ Naughter for his CWSocket class
  • PJ Naughter for his CVersionInfo class

Further plans: I would like to add Telnet and SSH support as soon as possible.

History

  • Version 1.3 (20th July, 2014) - Initial release
  • Version 1.5 (28th July, 2014) - Fix several bugs regarding logging functions for serial port and UDP socket

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License

Share

About the Author

Mihai MOGA
Architect Printec Group Romania SRL
Romania Romania
My professional background includes knowledge of analyst programmer for Microsoft Visual C++, Microsoft Visual C#, Microsoft Visual Basic, Sun Java, assembly for Intel 80x86 microprocessors, assembly for PIC microcontrollers (produced by Microchip Inc.), relational databases (MySQL, Oracle, SQL Server), concurrent version systems, bug tracking systems, web design (XHTML, CSS, XML, PHP/MySQL, JavaScript, Flash).

If you like my articles, please visit my website for more: http://www.mihaimoga.com/
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
QuestionWhere on your site to download exe? PinmemberLen20209-Sep-14 17:07 
AnswerRe: Where on your site to download exe? PinprofessionalMihai MOGA13-Sep-14 20:07 
GeneralRe: Where on your site to download exe? PinmemberLen202015-Sep-14 6:32 
GeneralRe: Where on your site to download exe? PinprofessionalMihai MOGA15-Sep-14 7:19 
QuestionFormat issues PinmemberNelek30-Aug-14 4:59 
AnswerRe: Format issues PinprofessionalMihai MOGA30-Aug-14 7:36 
GeneralRe: Format issues PinmemberNelek30-Aug-14 8:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150414.1 | Last Updated 21 Jul 2014
Article Copyright 2014 by Mihai MOGA
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid