/*--------------------------------------------------------------------------*/ /* */ /* */ /* ------------ Bit-Bucket Software, Co. */ /* \ 10001101 / Writers and Distributors of */ /* \ 011110 / Freely Available Software. */ /* \ 1011 / */ /* ------ */ /* */ /* (C) Copyright 1987-96, Bit Bucket Software Co. */ /* */ /* This module was written by Peter Fitzsimmons */ /* */ /* BinkleyTerm OS/2 Async Comm I/O Routines */ /* */ /* */ /* For complete details of the licensing restrictions, please refer */ /* to the License agreement, which is published in its entirety in */ /* the MAKEFILE and BT.C, and also contained in the file LICENSE.260. */ /* */ /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */ /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */ /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */ /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */ /* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */ /* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */ /* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */ /* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */ /* */ /* */ /* You can contact Bit Bucket Software Co. at any one of the following */ /* addresses: */ /* */ /* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */ /* P.O. Box 460398 AlterNet 7:42/1491 */ /* Aurora, CO 80046 BBS-Net 86:2030/1 */ /* Internet f491.n343.z1.fidonet.org */ /* */ /* Please feel free to contact us at any time to share your comments about */ /* our software and/or licensing policies. */ /* */ /*--------------------------------------------------------------------------*/ /* Include this file before any other includes or defines! */ #include "includes.h" #ifndef OS_2 #pragma message("This Module For OS/2") #else /* These must be in "includes.h" for C7 precompiled headers to work (as if we'll ever get any MS support for OS/2-targetted C7!!!) #define INCL_DOS #define INCL_DOSERRORS #define INCL_DOSDEVIOCTL #include "includes.h" (And this I put up top to avoid confusion) */ /* This module by Peter Fitzsimmons */ /* Modified 6/13/92 for exit (3) WRA */ HCOMM hcModem = 0; /* comm.dll handle */ #define RBSIZE 8200 /* MB */ #define TBSIZE 8200 /* MB */ USHORT rBufsize = RBSIZE; USHORT tBufsize = TBSIZE; void com_DTR_on (void) { DCBINFO sDCB; USHORT rc; if (!(rc = ComGetDCB (hcModem, &sDCB))) { sDCB.fbCtlHndShake |= MODE_DTR_CONTROL; /* raise DTR */ ComSetDCB (hcModem, &sDCB); } else { status_line ("!SYS%04hu: ComGetDCB()", rc); exit (3); } } void com_DTR_off (void) { DCBINFO sDCB; USHORT rc; if (!(rc = ComGetDCB (hcModem, &sDCB))) { sDCB.fbCtlHndShake &= ~MODE_DTR_CONTROL; /* lower DTR */ ComSetDCB (hcModem, &sDCB); com_kick (); } else { status_line ("!SYS%04hu: ComGetDCB()", rc); exit (3); } } void com_XON_disable (void) { DCBINFO sDCB; USHORT rc; if (!(rc = ComGetDCB (hcModem, &sDCB))) { /* disable auto Xmit and recv flow control */ sDCB.fbFlowReplace &= ~(MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE); ComSetDCB (hcModem, &sDCB); com_kick (); } else { status_line ("!SYS%04hu: ComGetDCB()", rc); exit (3); } } void com_XON_enable (void) { DCBINFO sDCB; USHORT rc; if (!(rc = ComGetDCB (hcModem, &sDCB))) { /* enable auto Xmit and recv flow control */ sDCB.fbFlowReplace |= MODE_AUTO_TRANSMIT; /*PLF Wed 04-04-1990 02:35:41 */ ComSetDCB (hcModem, &sDCB); } else { status_line ("!SYS%04hu: ComGetDCB()", rc); exit (3); } } int com_getc (int t) { if (t) ComRxWait (hcModem, t * 1000L); return ComGetc (hcModem); } /* com_break() : start break if on==TRUE, stop break if on==FALSE */ void com_break (int on) { #ifndef __32BIT__ int cmd; USHORT comerr, rc; HFILE hf; cmd = (on) ? ASYNC_SETBREAKON : ASYNC_SETBREAKOFF; hf = ComGetFH (hcModem); if (hf) { rc = DosDevIOCtl (&comerr, NULL, (USHORT) cmd, IOCTL_ASYNC, hf); if (rc) { status_line ("!SYS%04hu: ASYNC_SETBREAK", rc); exit (3); } } #else ULONG cmd; HFILE hf; PVOID ParmList; ULONG ParmLengthMax; ULONG ParmLengthInOut; UCHAR DataArea[2]; ULONG DataLengthMax; ULONG DataLengthInOut; APIRET rc; ParmList = 0; ParmLengthInOut = 0; ParmLengthMax = 0; DataLengthInOut = 0; DataLengthMax = 2; cmd = (on) ? ASYNC_SETBREAKON : ASYNC_SETBREAKOFF; hf = ComGetFH (hcModem); if (hf) { /* rc = DosDevIOCtl(&comerr, 0L, cmd, IOCTL_ASYNC, hf); */ rc = DosDevIOCtl (hf, IOCTL_ASYNC, cmd, ParmList, ParmLengthMax, &ParmLengthInOut, DataArea, DataLengthMax, &DataLengthInOut); if (rc) status_line ("!SYS%04ld: ASYNC_SETBREAK", rc); } #endif } void MDM_ENABLE (unsigned long rate) { char _parity; short databits; short stopbits; if (!hcModem) return; if (lock_baud && rate != max_baud.rate_value) { status_line (">Pretending baud is %lu (locked at %lu)", rate, max_baud.rate_value); rate = max_baud.rate_value; } databits = 7 + (comm_bits == BITS_8); stopbits = 1 + (stop_bits == STOP_2); switch (parity) { case NO_PARITY: _parity = 'N'; break; case ODD_PARITY: _parity = 'O'; break; case EVEN_PARITY: _parity = 'E'; break; default: _parity = 'N'; status_line ("!Invalid parity"); } ComSetBaudRate (hcModem, (long) rate, _parity, (USHORT) databits, (USHORT) stopbits); } void MDM_DISABLE (void) { if (hcModem) { ComClose (hcModem); hcModem = 0; } } void ShowMdmSettings (void) { DCBINFO dcb; USHORT rc; char *On = "On"; char *Off = "Off"; char *dtr; char *rts; char *buffer; short Rx = 0, Tx; if (!(rc = ComGetDCB (hcModem, &dcb))) { status_line (">Modem: TO=%s,XON(Rx)=%s,XON(Tx)=%s", (dcb.fbTimeout & MODE_NO_WRITE_TIMEOUT) ? On : Off, (dcb.fbFlowReplace & MODE_AUTO_RECEIVE) ? On : Off, (dcb.fbFlowReplace & MODE_AUTO_TRANSMIT) ? On : Off); status_line (">Modem: IDSR=%s,ODSR=%s,OCTS=%s", (dcb.fbCtlHndShake & MODE_DSR_SENSITIVITY) ? On : Off, (dcb.fbCtlHndShake & MODE_DSR_HANDSHAKE) ? On : Off, (dcb.fbCtlHndShake & MODE_CTS_HANDSHAKE) ? On : Off); switch (dcb.fbCtlHndShake & (MODE_DTR_CONTROL | MODE_DTR_HANDSHAKE)) { case 0: dtr = Off; break; case MODE_DTR_CONTROL: dtr = On; break; case MODE_DTR_HANDSHAKE: dtr = "IHS"; break; /* input handshaking */ default: dtr = "??"; break; } switch (dcb.fbFlowReplace & (MODE_RTS_CONTROL | MODE_RTS_HANDSHAKE | MODE_TRANSMIT_TOGGLE)) { case 0: rts = Off; break; case MODE_RTS_CONTROL: rts = On; break; case MODE_RTS_HANDSHAKE: rts = "IHS"; break; case MODE_TRANSMIT_TOGGLE: rts = "TOG"; break; default: rts = "??"; break; } switch (dcb.fbTimeout & 0x18) { case 0x08: buffer = Off; break; case 0x10: buffer = On; break; case 0x18: buffer = "Auto"; break; default: buffer = "??"; break; } switch (dcb.fbTimeout & 0x60) { case 0: Rx = 1; break; case 0x20: Rx = 4; break; case 0x40: Rx = 8; break; case 0x60: Rx = 14; break; } Tx = (dcb.fbTimeout & 0x80) ? 16 : 1; status_line (">Modem: DTR=%s,RTS=%s,BUFFER=%s (Rx=%hd, Tx=%hd)", dtr, rts, buffer, Rx, Tx); status_line(">Modem: Buffers R: %hu T: %hu", rBufsize, tBufsize); /* MB 94-01-02 */ } else { status_line ("!SYS%04hu: ComGetDCB()", rc); exit (3); } } unsigned Cominit (int port, int failsafe) { char tmp[5]; USHORT rc; char *s; failsafe = failsafe; if (!hcModem) { s = getenv("RBUF"); /* MB 94-01-02 */ if (s) rBufsize = (USHORT)min( 32000, atoi(s)); else rBufsize = RBSIZE; s = getenv("TBUF"); if (s) tBufsize = (USHORT)min( 32000, atoi(s)); else tBufsize = TBSIZE; sprintf (tmp, "com%1u", port + 1); /*DosSetPrty(PRTYS_PROCESS, PRTYC_FOREGROUNDSERVER, 0, 0);*/ rc = ComOpen ((PSZ) tmp, &hcModem, rBufsize, tBufsize); if (rc) { status_line ("!SYS%04hu: ComOpen(%s)", rc, tmp); /* return(0); */ exit (3); } else ShowMdmSettings (); } else ComResume (hcModem); return (0x1954); } /* force transmitter to go */ void com_kick (void) { #ifndef __32BIT__ USHORT rc; HFILE hf; if (hcModem) { hf = ComGetFH (hcModem); if (hf) { rc = DosDevIOCtl ((PVOID) 0L, (PVOID) 0L, ASYNC_STARTTRANSMIT, IOCTL_ASYNC, (HFILE) hfComHandle); if (rc) { status_line ("!SYS%04hu: ASYNC_STARTTRANSMIT", rc); /* exit (3); */ } } } #else HFILE hf; PVOID ParmList; ULONG ParmLengthMax; ULONG ParmLengthInOut; PVOID DataArea; ULONG DataLengthMax; ULONG DataLengthInOut; APIRET rc; ParmList = 0; ParmLengthInOut = 0; ParmLengthMax = 0; DataArea = 0; DataLengthInOut = 0; DataLengthMax = 0; if (hcModem) { hf = ComGetFH (hcModem); if (hf) { rc = DosDevIOCtl (hf, IOCTL_ASYNC, ASYNC_STARTTRANSMIT, ParmList, ParmLengthMax, &ParmLengthInOut, DataArea, DataLengthMax, &DataLengthInOut); if (rc && rc != 31) { status_line ("!SYS%04ld: ASYNC_STARTTRANSMIT", rc); /* exit (3); */ } } } #endif } /* Currently only used by HYDRA */ /* * This is a lot like ComWrite, but will return the sent-character * count if either a timeout occurs or carrier is lost. The timer * is specified by passing in a time_t for end-of-time. If zero is * passed for the timer, we'll just check for carrier loss. * */ USHORT ComTXBlockTimeout (BYTE *lpBuf, USHORT cbBuf, ULONG ulTimer) { USHORT cbRemaining = cbBuf; USHORT cbToSend; BOOL fTimedOut; fTimedOut = (ulTimer != 0) ? (ulTimer < (ULONG)time (NULL)) : FALSE; while (!fTimedOut && CARRIER && cbRemaining) { cbToSend = ComOutSpace (hcModem); if ((--cbToSend) > 0) { if (cbToSend > cbRemaining) cbToSend = cbRemaining; ComWrite (hcModem, lpBuf, cbToSend); lpBuf += cbToSend; cbRemaining -= cbToSend; } else time_release (); fTimedOut = (ulTimer != 0) ? (ulTimer < (ULONG)time (NULL)) : FALSE; } return (cbBuf - cbRemaining); } USHORT ComTXRemain (void) /* MB 93-12-03 */ { return (tBufsize - ComOutSpace (hcModem)); } #endif /* OS_2 */