home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spiele Shareware / os2games.iso / os2games / addons / pmics / src / sescom.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-17  |  7.4 KB  |  224 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. extern IString stringOption(IString s);
  42.  
  43. // if we put this in the class, users have to include the DOS garbage
  44. static HFILE hcom;
  45.  
  46. /*****************************************************************************/
  47. /* thread does blocking reads against COM: and send data via window */
  48. /* messages to the parent window as data arrives */
  49. /*****************************************************************************/
  50. static VOID _System ComListen(ULONG ulhcom)
  51. {
  52.   ULONG         bytesRead;
  53.   APIRET        rc;
  54.   char          buf[2049];
  55.   HFILE         hcom = (HFILE)ulhcom;
  56.  
  57.   IFUNCTRACE_DEVELOP();
  58.   ITRACE_DEVELOP(IString("listening to com port"));
  59.   if (! IThread::current().isPMInitialized())
  60.     IThread::current().initializePM();
  61.  
  62.   while (1) {
  63.     rc = DosRead(hcom, (BYTE *)buf, 2048, &bytesRead);
  64.     if (bytesRead == 0) continue;
  65.     buf[bytesRead] = 0;        // for debug print
  66.     commStream.clear();
  67.     commStream.write(buf, bytesRead);
  68.     ITRACE_DEVELOP("sescom: bytes received: " + IString(bytesRead));
  69. //    ITRACE_DEVELOP(IString("wrote: ") + IString(buf));
  70.  
  71.     while(1) {
  72.       try {
  73.     hComm.postEvent(MSG_COM_IN);
  74.     break;
  75.       }
  76.       catch (IInvalidParameter) {
  77.     ITRACE_DEVELOP("ComListen: exception caught, sleeping 250");
  78.     IThread::current().sleep(250);
  79.       }
  80.     }
  81.  
  82.     if (bytesRead < 16)        // avoid flooding queue
  83.       IThread::current().sleep(100);
  84.   }
  85. }
  86.  
  87.  
  88.  
  89. /* do blocking reads against COM: and send data via windowing messages */
  90. /* to the parent window as data arrives */
  91. AComSession::write(char *s)
  92. {
  93.   ULONG         cbWritten;
  94.  
  95.   IFUNCTRACE_DEVELOP();
  96.   ITRACE_DEVELOP(IString("<")+IString(s)+IString(">"));
  97. //  DosGetDateTime(&keyDt);
  98.   DosWrite(hcom, s, strlen(s), &cbWritten);
  99. }
  100.  
  101.  
  102.  
  103.  
  104.  
  105. #define COMOPEN(s) \
  106.       DosOpen((PSZ)(s), &hcom, &crap, 0, FILE_NORMAL, \
  107.            FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_FLAGS_FAIL_ON_ERROR | \
  108.           OPEN_SHARE_DENYREADWRITE, (PEAOP2) NULL)
  109.  
  110. AComSession::AComSession()
  111. {
  112.   APIRET rc;
  113.   DCBINFO     dcbinfo;        /* Device control block for Ioctl 53H, 73H */
  114.   LINECONTROL lnctlBuf;
  115.   ULONG       ulParmLen;
  116.   ULONG       crap;
  117.   char          comfile[5];
  118.   IString     dialString;
  119.   char        msgbuf[256];
  120.  
  121.   IFUNCTRACE_DEVELOP();
  122.   isActive = false;        // preset
  123.  
  124.   // get modem initialization string specified -dial option
  125.   dialString = getStringOption("dial", "ATE1");
  126.   ITRACE_DEVELOP("dialString=" + dialString);
  127.   
  128.   // get baud rate specified with -baud option
  129.   comBaud = getIntOption("baud", 19200);
  130.   ITRACE_DEVELOP("comBaud = " + IString(comBaud));
  131.  
  132.   // get com port (0 if not specified)
  133.   comPort = getIntOption("port", 0);
  134.   ITRACE_DEVELOP("comPort = " + IString(comPort));
  135.  
  136.  
  137.   /**********************************************************************/
  138.   /* Get File Handle hcom for COM port (shared read/write access)       */
  139.   /* if /Cn was specified then use com port n.  Otherwise try com ports */
  140.   /* 1-4 in turn and use the first one that opens succesfully.          */
  141.   /**********************************************************************/
  142.   if (comPort != 0) {
  143.     sprintf(comfile, "COM%1d", comPort);
  144.     if (COMOPEN(comfile)) {
  145.       throw IException(IString("Unable to open ") + comfile + " at " +
  146.                    IString(comBaud) + " baud");
  147.     }
  148.   }
  149.  
  150.   else {
  151.     for (comPort = 1; comPort <= 4; comPort++) {
  152.       sprintf(comfile, "COM%1d", comPort);
  153.       if (COMOPEN(comfile) == 0)
  154.     break;
  155.     }
  156.     if (comPort > 4) {
  157.       throw IException(IString("Unable to open any COM port 1-4 at ") +
  158.                    IString(comBaud) + " baud");
  159.     }
  160.   }
  161.         
  162. #ifdef CRAP
  163.   // Call Category 1 Function 42H   Set Line Characteristics
  164.   lnctlBuf.bDataBits  = 8;
  165.   lnctlBuf.bParity    = 0;
  166.   lnctlBuf.bStopBits  = 1;    /* IDD_ONESTOP = 20 */
  167.   ulParmLen = sizeof(LINECONTROL);
  168.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETLINECTRL, &lnctlBuf, sizeof(LINECONTROL), &ulParmLen, NULL, 0, (PULONG)NULL);
  169.   ITRACE_DEVELOP("line characteristics rc="+IString(rc));
  170. #endif
  171.  
  172.   // Call Category 1 Function 73H   Query Device Control Block
  173.   ulParmLen = 0;
  174.   crap = sizeof(DCBINFO);
  175.  
  176.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_GETDCBINFO, NULL, 0, &ulParmLen, &dcbinfo, sizeof(DCBINFO), &crap);
  177.  
  178.   sprintf(msgbuf,"query dcb rc=%d crap=%d\n"
  179.       "  WriteTimeout %4x\n"
  180.       "  ReadTimeout  %4x\n"
  181.       "  flags1 %2x flags2 %x flags3 %x\n",
  182.       rc, crap,
  183.       dcbinfo.usWriteTimeout,
  184.       dcbinfo.usReadTimeout,
  185.       dcbinfo.fbCtlHndShake,
  186.       dcbinfo.fbFlowReplace,
  187.       dcbinfo.fbTimeout);
  188.   ITRACE_DEVELOP(msgbuf);
  189.   
  190.   // Call Category 1 Function 41H   Set Baud Rate
  191.   ulParmLen = 4;
  192.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETBAUDRATE, &comBaud, 
  193.            sizeof(comBaud), &ulParmLen, NULL, 0, (PULONG)NULL);
  194.   ITRACE_DEVELOP("baud rate set rc=" + IString(rc));
  195.   
  196.   /**********************************************************************/
  197.   /* Use wait-for-input mode so the COM thread can do blocking reads    */
  198.   /* against hcom until any data is available.                          */
  199.   /**********************************************************************/
  200.   dcbinfo.fbTimeout           &= ~(0x06);     /* Clear bits, then set */
  201.   dcbinfo.fbTimeout           |= MODE_WAIT_READ_TIMEOUT;
  202.   dcbinfo.usReadTimeout       = (USHORT)(-1);           /* Never! */
  203.  
  204.   // Call Category 1 Function 53H   Set Device Control Block
  205.   ulParmLen = sizeof(DCBINFO);
  206.   rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcbinfo, sizeof(DCBINFO), &ulParmLen, NULL, 0, (PULONG)NULL);
  207.   ITRACE_DEVELOP("set dcb rc = "+IString(rc)+" ulParmLen="+IString(ulParmLen));
  208.   
  209.   write(dialString);
  210.   write (stringOption("cr") == "lf" ? "\n" : "\r");
  211.  
  212.   /**********************************************************************/
  213.   /* Spawn a task to listen to the port                                 */
  214.   /**********************************************************************/
  215.   listenThread = new IThread(&ComListen, (ULONG)hcom);
  216.   isActive = true;
  217. }
  218.  
  219. AComSession::~AComSession()
  220. {
  221.   IFUNCTRACE_DEVELOP();
  222.   if (listenThread) delete listenThread;
  223. }
  224.