home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 035 / pmics.zip / sescom.cc < prev    next >
C/C++ Source or Header  |  1994-12-10  |  8KB  |  223 lines

  1. /*
  2.     PMICS -- PM interface for playing chess on internet chess server
  3.     Copyright (C) 1994  Kevin Nomura
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     Author can be reached at email: chow@netcom.com
  20. */
  21. #define INCL_DOSPROCESS
  22. #define INCL_DOSFILEMGR
  23. #define INCL_DOSDEVIOCTL
  24. #define INCL_DOSDEVICES
  25. #define INCL_DOSDATETIME
  26. #define INCL_DOSQUEUES
  27. #define INCL_DOSEXCEPTIONS
  28. #include <os2.h>
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <strstrea.h>
  33. #include <istring.hpp>
  34. #include <iexcbase.hpp>
  35. #include "session.hh"
  36. #include "pmics.hh"
  37.  
  38. extern strstream commStream;
  39. extern int getIntOption(IString s, int def);
  40. extern IString getStringOption(IString s, IString def);
  41.  
  42. // if we put this in the class, users have to include the DOS garbage
  43. static HFILE hcom;
  44.  
  45. /*****************************************************************************/
  46. /* thread does blocking reads against COM: and send data via window */
  47. /* messages to the parent window as data arrives */
  48. /*****************************************************************************/
  49. static VOID _System ComListen(ULONG ulhcom)
  50. {
  51.   ULONG         bytesRead;
  52.   APIRET        rc;
  53.   char          buf[2049];
  54.   HFILE         hcom = (HFILE)ulhcom;
  55.  
  56.   IFUNCTRACE_DEVELOP();
  57.   ITRACE_DEVELOP(IString("listening to com port"));
  58.   if (! IThread::current().isPMInitialized())
  59.     IThread::current().initializePM();
  60.  
  61.   while (1) {
  62.     rc = DosRead(hcom, (BYTE *)buf, 2048, &bytesRead);
  63.     if (bytesRead == 0) continue;
  64.     buf[bytesRead] = 0;        // for debug print
  65.     commStream.clear();
  66.     commStream.write(buf, bytesRead);
  67.     ITRACE_DEVELOP("sescom: bytes received: " + IString(bytesRead));
  68. //    ITRACE_DEVELOP(IString("wrote: ") + IString(buf));
  69.  
  70.     while(1) {
  71.       try {
  72.     hComm.postEvent(MSG_COM_IN);
  73.     break;
  74.       }
  75.       catch (IInvalidParameter) {
  76.     ITRACE_DEVELOP("ComListen: exception caught, sleeping 250");
  77.     IThread::current().sleep(250);
  78.       }
  79.     }
  80.  
  81.     if (bytesRead < 16)        // avoid flooding queue
  82.       IThread::current().sleep(100);
  83.   }
  84. }
  85.  
  86.  
  87.  
  88. /* do blocking reads against COM: and send data via windowing messages */
  89. /* to the parent window as data arrives */
  90. AComSession::write(char *s)
  91. {
  92.   ULONG         cbWritten;
  93.  
  94.   IFUNCTRACE_DEVELOP();
  95.   ITRACE_DEVELOP(IString("<")+IString(s)+IString(">"));
  96. //  DosGetDateTime(&keyDt);
  97.   DosWrite(hcom, s, strlen(s), &cbWritten);
  98. }
  99.  
  100.  
  101.  
  102.  
  103.  
  104. #define COMOPEN(s) \
  105.       DosOpen((PSZ)(s), &hcom, &crap, 0, FILE_NORMAL, \
  106.            FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_FLAGS_FAIL_ON_ERROR | \
  107.           OPEN_SHARE_DENYREADWRITE, (PEAOP2) NULL)
  108.  
  109. AComSession::AComSession()
  110. {
  111.   APIRET rc;
  112.   DCBINFO     dcbinfo;        /* Device control block for Ioctl 53H, 73H */
  113.   LINECONTROL lnctlBuf;
  114.   ULONG       ulParmLen;
  115.   ULONG       crap;
  116.   char          comfile[5];
  117.   IString     dialString;
  118.   char        msgbuf[256];
  119.  
  120.   IFUNCTRACE_DEVELOP();
  121.   isActive = false;        // preset
  122.  
  123.   // get modem initialization string specified -dial option
  124.   dialString = getStringOption("dial", "ATE1");
  125.   ITRACE_DEVELOP("dialString=" + dialString);
  126.   
  127.   // get baud rate specified with -baud option
  128.   comBaud = getIntOption("baud", 19200);
  129.   ITRACE_DEVELOP("comBaud = " + IString(comBaud));
  130.  
  131.   // get com port (0 if not specified)
  132.   comPort = getIntOption("port", 0);
  133.   ITRACE_DEVELOP("comPort = " + IString(comPort));
  134.  
  135.  
  136.   /**********************************************************************/
  137.   /* Get File Handle hcom for COM port (shared read/write access)       */
  138.   /* if /Cn was specified then use com port n.  Otherwise try com ports */
  139.   /* 1-4 in turn and use the first one that opens succesfully.          */
  140.   /**********************************************************************/
  141.   if (comPort != 0) {
  142.     sprintf(comfile, "COM%1d", comPort);
  143.     if (COMOPEN(comfile)) {
  144.       throw IException(IString("Unable to open ") + comfile + " at " +
  145.                    IString(comBaud) + " baud");
  146.     }
  147.   }
  148.  
  149.   else {
  150.     for (comPort = 1; comPort <= 4; comPort++) {
  151.       sprintf(comfile, "COM%1d", comPort);
  152.       if (COMOPEN(comfile) == 0)
  153.     break;
  154.     }
  155.     if (comPort > 4) {
  156.       throw IException(IString("Unable to open any COM port 1-4 at ") +
  157.                    IString(comBaud) + " baud");
  158.     }
  159.   }
  160.         
  161. #ifdef CRAP
  162.   // Call Category 1 Function 42H   Set Line Characteristics
  163.   lnctlBuf.bDataBits  = 8;
  164.   lnctlBuf.bParity    = 0;
  165.   lnctlBuf.bStopBits  = 1;    /* IDD_ONESTOP = 20 */
  166.   ulParmLen = sizeof(LINECONTROL);
  167.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETLINECTRL, &lnctlBuf, sizeof(LINECONTROL), &ulParmLen, NULL, 0, (PULONG)NULL);
  168.   ITRACE_DEVELOP("line characteristics rc="+IString(rc));
  169. #endif
  170.  
  171.   // Call Category 1 Function 73H   Query Device Control Block
  172.   ulParmLen = 0;
  173.   crap = sizeof(DCBINFO);
  174.  
  175.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_GETDCBINFO, NULL, 0, &ulParmLen, &dcbinfo, sizeof(DCBINFO), &crap);
  176.  
  177.   sprintf(msgbuf,"query dcb rc=%d crap=%d\n"
  178.       "  WriteTimeout %4x\n"
  179.       "  ReadTimeout  %4x\n"
  180.       "  flags1 %2x flags2 %x flags3 %x\n",
  181.       rc, crap,
  182.       dcbinfo.usWriteTimeout,
  183.       dcbinfo.usReadTimeout,
  184.       dcbinfo.fbCtlHndShake,
  185.       dcbinfo.fbFlowReplace,
  186.       dcbinfo.fbTimeout);
  187.   ITRACE_DEVELOP(msgbuf);
  188.   
  189.   // Call Category 1 Function 41H   Set Baud Rate
  190.   ulParmLen = 4;
  191.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETBAUDRATE, &comBaud, 
  192.            sizeof(comBaud), &ulParmLen, NULL, 0, (PULONG)NULL);
  193.   ITRACE_DEVELOP("baud rate set rc=" + IString(rc));
  194.   
  195.   /**********************************************************************/
  196.   /* Use wait-for-input mode so the COM thread can do blocking reads    */
  197.   /* against hcom until any data is available.                          */
  198.   /**********************************************************************/
  199.   dcbinfo.fbTimeout           &= ~(0x06);     /* Clear bits, then set */
  200.   dcbinfo.fbTimeout           |= MODE_WAIT_READ_TIMEOUT;
  201.   dcbinfo.usReadTimeout       = (USHORT)(-1);           /* Never! */
  202.  
  203.   // Call Category 1 Function 53H   Set Device Control Block
  204.   ulParmLen = sizeof(DCBINFO);
  205.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcbinfo, sizeof(DCBINFO), &ulParmLen, NULL, 0, (PULONG)NULL);
  206.   ITRACE_DEVELOP("set dcb rc = "+IString(rc)+" ulParmLen="+IString(ulParmLen));
  207.   
  208.   write(dialString);
  209.   write("\015");
  210.  
  211.   /**********************************************************************/
  212.   /* Spawn a task to listen to the port                                 */
  213.   /**********************************************************************/
  214.   listenThread = new IThread(&ComListen, (ULONG)hcom);
  215.   isActive = true;
  216. }
  217.  
  218. AComSession::~AComSession()
  219. {
  220.   IFUNCTRACE_DEVELOP();
  221.   if (listenThread) delete listenThread;
  222. }
  223.