home *** CD-ROM | disk | FTP | other *** search
- /*
- PMICS -- PM interface for playing chess on internet chess server
- Copyright (C) 1994 Kevin Nomura
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Author can be reached at email: chow@netcom.com
- */
- #define INCL_DOSPROCESS
- #define INCL_DOSFILEMGR
- #define INCL_DOSDEVIOCTL
- #define INCL_DOSDEVICES
- #define INCL_DOSDATETIME
- #define INCL_DOSQUEUES
- #define INCL_DOSEXCEPTIONS
- #include <os2.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <strstrea.h>
- #include <istring.hpp>
- #include <iexcbase.hpp>
- #include "session.hh"
- #include "pmics.hh"
-
- extern strstream commStream;
- extern int getIntOption(IString s, int def);
- extern IString getStringOption(IString s, IString def);
- extern IString stringOption(IString s);
-
- // if we put this in the class, users have to include the DOS garbage
- static HFILE hcom;
-
- /*****************************************************************************/
- /* thread does blocking reads against COM: and send data via window */
- /* messages to the parent window as data arrives */
- /*****************************************************************************/
- static VOID _System ComListen(ULONG ulhcom)
- {
- ULONG bytesRead;
- APIRET rc;
- char buf[2049];
- HFILE hcom = (HFILE)ulhcom;
-
- IFUNCTRACE_DEVELOP();
- ITRACE_DEVELOP(IString("listening to com port"));
- if (! IThread::current().isPMInitialized())
- IThread::current().initializePM();
-
- while (1) {
- rc = DosRead(hcom, (BYTE *)buf, 2048, &bytesRead);
- if (bytesRead == 0) continue;
- buf[bytesRead] = 0; // for debug print
- commStream.clear();
- commStream.write(buf, bytesRead);
- ITRACE_DEVELOP("sescom: bytes received: " + IString(bytesRead));
- // ITRACE_DEVELOP(IString("wrote: ") + IString(buf));
-
- while(1) {
- try {
- hComm.postEvent(MSG_COM_IN);
- break;
- }
- catch (IInvalidParameter) {
- ITRACE_DEVELOP("ComListen: exception caught, sleeping 250");
- IThread::current().sleep(250);
- }
- }
-
- if (bytesRead < 16) // avoid flooding queue
- IThread::current().sleep(100);
- }
- }
-
-
-
- /* do blocking reads against COM: and send data via windowing messages */
- /* to the parent window as data arrives */
- AComSession::write(char *s)
- {
- ULONG cbWritten;
-
- IFUNCTRACE_DEVELOP();
- ITRACE_DEVELOP(IString("<")+IString(s)+IString(">"));
- // DosGetDateTime(&keyDt);
- DosWrite(hcom, s, strlen(s), &cbWritten);
- }
-
-
-
-
-
- #define COMOPEN(s) \
- DosOpen((PSZ)(s), &hcom, &crap, 0, FILE_NORMAL, \
- FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_FLAGS_FAIL_ON_ERROR | \
- OPEN_SHARE_DENYREADWRITE, (PEAOP2) NULL)
-
- AComSession::AComSession()
- {
- APIRET rc;
- DCBINFO dcbinfo; /* Device control block for Ioctl 53H, 73H */
- LINECONTROL lnctlBuf;
- ULONG ulParmLen;
- ULONG crap;
- char comfile[5];
- IString dialString;
- char msgbuf[256];
-
- IFUNCTRACE_DEVELOP();
- isActive = false; // preset
-
- // get modem initialization string specified -dial option
- dialString = getStringOption("dial", "ATE1");
- ITRACE_DEVELOP("dialString=" + dialString);
-
- // get baud rate specified with -baud option
- comBaud = getIntOption("baud", 19200);
- ITRACE_DEVELOP("comBaud = " + IString(comBaud));
-
- // get com port (0 if not specified)
- comPort = getIntOption("port", 0);
- ITRACE_DEVELOP("comPort = " + IString(comPort));
-
-
- /**********************************************************************/
- /* Get File Handle hcom for COM port (shared read/write access) */
- /* if /Cn was specified then use com port n. Otherwise try com ports */
- /* 1-4 in turn and use the first one that opens succesfully. */
- /**********************************************************************/
- if (comPort != 0) {
- sprintf(comfile, "COM%1d", comPort);
- if (COMOPEN(comfile)) {
- throw IException(IString("Unable to open ") + comfile + " at " +
- IString(comBaud) + " baud");
- }
- }
-
- else {
- for (comPort = 1; comPort <= 4; comPort++) {
- sprintf(comfile, "COM%1d", comPort);
- if (COMOPEN(comfile) == 0)
- break;
- }
- if (comPort > 4) {
- throw IException(IString("Unable to open any COM port 1-4 at ") +
- IString(comBaud) + " baud");
- }
- }
-
- #ifdef CRAP
- // Call Category 1 Function 42H Set Line Characteristics
- lnctlBuf.bDataBits = 8;
- lnctlBuf.bParity = 0;
- lnctlBuf.bStopBits = 1; /* IDD_ONESTOP = 20 */
- ulParmLen = sizeof(LINECONTROL);
- rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETLINECTRL, &lnctlBuf, sizeof(LINECONTROL), &ulParmLen, NULL, 0, (PULONG)NULL);
- ITRACE_DEVELOP("line characteristics rc="+IString(rc));
- #endif
-
- // Call Category 1 Function 73H Query Device Control Block
- ulParmLen = 0;
- crap = sizeof(DCBINFO);
-
- rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_GETDCBINFO, NULL, 0, &ulParmLen, &dcbinfo, sizeof(DCBINFO), &crap);
-
- sprintf(msgbuf,"query dcb rc=%d crap=%d\n"
- " WriteTimeout %4x\n"
- " ReadTimeout %4x\n"
- " flags1 %2x flags2 %x flags3 %x\n",
- rc, crap,
- dcbinfo.usWriteTimeout,
- dcbinfo.usReadTimeout,
- dcbinfo.fbCtlHndShake,
- dcbinfo.fbFlowReplace,
- dcbinfo.fbTimeout);
- ITRACE_DEVELOP(msgbuf);
-
- // Call Category 1 Function 41H Set Baud Rate
- ulParmLen = 4;
- rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETBAUDRATE, &comBaud,
- sizeof(comBaud), &ulParmLen, NULL, 0, (PULONG)NULL);
- ITRACE_DEVELOP("baud rate set rc=" + IString(rc));
-
- /**********************************************************************/
- /* Use wait-for-input mode so the COM thread can do blocking reads */
- /* against hcom until any data is available. */
- /**********************************************************************/
- dcbinfo.fbTimeout &= ~(0x06); /* Clear bits, then set */
- dcbinfo.fbTimeout |= MODE_WAIT_READ_TIMEOUT;
- dcbinfo.usReadTimeout = (USHORT)(-1); /* Never! */
-
- // Call Category 1 Function 53H Set Device Control Block
- ulParmLen = sizeof(DCBINFO);
- rc = DosDevIOCtl(hcom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcbinfo, sizeof(DCBINFO), &ulParmLen, NULL, 0, (PULONG)NULL);
- ITRACE_DEVELOP("set dcb rc = "+IString(rc)+" ulParmLen="+IString(ulParmLen));
-
- write(dialString);
- write (stringOption("cr") == "lf" ? "\n" : "\r");
-
- /**********************************************************************/
- /* Spawn a task to listen to the port */
- /**********************************************************************/
- listenThread = new IThread(&ComListen, (ULONG)hcom);
- isActive = true;
- }
-
- AComSession::~AComSession()
- {
- IFUNCTRACE_DEVELOP();
- if (listenThread) delete listenThread;
- }
-