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 >
Wrap
C/C++ Source or Header
|
1994-12-10
|
8KB
|
223 lines
/*
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);
// 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("\015");
/**********************************************************************/
/* Spawn a task to listen to the port */
/**********************************************************************/
listenThread = new IThread(&ComListen, (ULONG)hcom);
isActive = true;
}
AComSession::~AComSession()
{
IFUNCTRACE_DEVELOP();
if (listenThread) delete listenThread;
}