home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES2.ZIP / UUCICO / ulibwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-12  |  27.4 KB  |  774 lines

  1. /*--------------------------------------------------------------------*/
  2. /*       u l i b w i n . C                                            */
  3. /*                                                                    */
  4. /*       UUPC/extended serial port communications for Windows 3.1     */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*       Changes copyright (c) 1993, by Robert Denny                  */
  9. /*--------------------------------------------------------------------*/
  10.  
  11. /*--------------------------------------------------------------------*/
  12. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  13. /*       Wonderworks.                                                 */
  14. /*                                                                    */
  15. /*       All rights reserved except those explicitly granted by       */
  16. /*       the UUPC/extended license agreement.                         */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*--------------------------------------------------------------------*/
  20. /*                          RCS Information                           */
  21. /*--------------------------------------------------------------------*/
  22.  
  23. /*
  24.  *    $Id: ulibwin.c 1.8 1993/10/12 01:33:23 ahd Exp $
  25.  *
  26.  *    Revision history:
  27.  *    $Log: ulibwin.c $
  28.  * Revision 1.8  1993/10/12  01:33:23  ahd
  29.  * Normalize comments to PL/I style
  30.  *
  31.  * Revision 1.7  1993/10/03  22:09:09  ahd
  32.  * Use unsigned long to display speed
  33.  *
  34.  * Revision 1.6  1993/10/01  02:36:45  dmwatt
  35.  * Suppress odd debugging messages in normal compile
  36.  * Reformat source
  37.  *
  38.  * Revision 1.5  1993/09/29  13:18:06  ahd
  39.  * Use new dummy setprty function
  40.  *
  41.  * Revision 1.4  1993/09/27  00:48:43  ahd
  42.  * Add dummy set and reset priority functions
  43.  *
  44.  * Revision 1.3  1993/08/02  03:24:59  ahd
  45.  * Further changes in support of Robert Denny's Windows 3.x support
  46.  *
  47.  * Revision 1.2  1993/07/31  16:27:49  ahd
  48.  * Changes in support of Robert Denny's Windows support
  49.  *
  50.  * Revision 1.1  1993/07/22  23:24:23  ahd
  51.  * Initial revision
  52.  *
  53.  */
  54.  
  55. /*--------------------------------------------------------------------*/
  56. /*       Services provided by ulib.c:                                 */
  57. /*                                                                    */
  58. /*          - serial I/O                                              */
  59. /*--------------------------------------------------------------------*/
  60.  
  61. /*--------------------------------------------------------------------*/
  62. /*                        System include files                        */
  63. /*--------------------------------------------------------------------*/
  64.  
  65. #include <stdlib.h>
  66. #include <stdio.h>
  67. #include <string.h>
  68. #include <fcntl.h>
  69. #include <io.h>
  70. #include <time.h>
  71.  
  72. /*--------------------------------------------------------------------*/
  73. /*                    MS Windows 3.1 include files                    */
  74. /*--------------------------------------------------------------------*/
  75.  
  76. #include <windows.h>
  77.  
  78. /*--------------------------------------------------------------------*/
  79. /*                    UUPC/extended include files                     */
  80. /*--------------------------------------------------------------------*/
  81.  
  82. #include "lib.h"
  83. #include "ulib.h"
  84. #include "ssleep.h"
  85. #include "commlib.h"
  86.  
  87. //
  88. // Finally, Microsoft has documented a way to see the Modem Status
  89. // Register bits for modem control lines. This was a real bizarre
  90. // mess with SetCommEventMask() and GetCommEventMask(). The document
  91. // is in the Developer's Knowledge Base:
  92. //
  93. // Title: INF: Accessing the Modem Status Register (MSR) in Windows
  94. // Document Number: Q101417           Publ Date: 15-JUL-1993
  95. // Product Name: Microsoft Windows Software Development Kit
  96. // Product Version:  3.10
  97. // Operating System: WINDOWS
  98. //
  99.  
  100. #define COMM_MSRSHADOW 35          /* Offset in DEB of MSR shadow     */
  101. #define MSR_CTS              0x10  /* absolute CTS state in MSR        */
  102. #define MSR_DSR              0x20  /* absolute DSR state in MSR        */
  103. #define MSR_RI               0x40  /* absolute RI state in MSR        */
  104. #define MSR_RLSD             0x80  /* absolute RLSD state in MSR      */
  105.  
  106. currentfile();
  107.  
  108. static boolean   carrierdetect = FALSE;  /* Modem is not connected    */
  109.  
  110. static boolean hangupNeeded = FALSE;
  111. static UINT currentSpeed = 0;
  112. static LPBYTE lpbModemBits;       /* --> Modem Status Register bits   */
  113.  
  114. #define FAR_NULL ((PVOID) 0L)
  115.  
  116. #define IN_QUEUE_SIZE   2048
  117. #define OUT_QUEUE_SIZE  2048
  118. #define IN_XOFF_LIM     256
  119. #define IN_XON_LIM      256
  120.  
  121. /*--------------------------------------------------------------------*/
  122. /*         Definitions of control structures for Win 3.1 API          */
  123. /*--------------------------------------------------------------------*/
  124.  
  125. static int nCid;
  126. static DCB dcb;
  127.  
  128. /*--------------------------------------------------------------------*/
  129. /*                        Internal prototypes                         */
  130. /*--------------------------------------------------------------------*/
  131.  
  132. static void ShowModem( void );
  133. static void ShowError( int status );
  134.  
  135. /*--------------------------------------------------------------------*/
  136. /*    n o p e n l i n e                                               */
  137. /*                                                                    */
  138. /*    Open the serial port for I/O                                    */
  139. /*--------------------------------------------------------------------*/
  140.  
  141. #ifdef __TURBOC__
  142. #pragma argsused
  143. #endif
  144.  
  145. int nopenline(char *name, BPS baud, const boolean direct )
  146. {
  147.    int rc;
  148.  
  149.    if (portActive)               /* Was the port already active?     ahd  */
  150.       closeline();               /* Yes --> Shutdown it before open  ahd  */
  151.  
  152. #ifdef UDEBUG
  153.    printmsg(15, "openline: %s, %ul", name, (unsigned long) baud);
  154. #endif
  155.  
  156.    if (!equaln(name, "COM", 3 ))
  157.    {
  158.       printmsg(0,
  159.          "openline: Communications port must be format COMx, was %s",
  160.          name);
  161.       return TRUE;
  162.    }
  163.  
  164.    if((nCid = OpenComm(name, IN_QUEUE_SIZE, OUT_QUEUE_SIZE)) < 0)
  165.    {
  166.       printmsg(0, "openline: Failed to open port %s.", name);
  167.       printmsg(0, "nopenline: %s: OpenComm returned %#04X (%d)",
  168.                    name,
  169.                    nCid,
  170.                    nCid);
  171.       return TRUE;
  172.    }
  173.  
  174. /*--------------------------------------------------------------------*/
  175. /*        Get the pointer to the MSR shadow in COMM.DRV's DEB         */
  176. /*--------------------------------------------------------------------*/
  177.  
  178.    lpbModemBits = (LPBYTE)SetCommEventMask(nCid, 0) + COMM_MSRSHADOW;
  179.  
  180. /*--------------------------------------------------------------------*/
  181. /*            Reset any errors on the communications port             */
  182. /*--------------------------------------------------------------------*/
  183.  
  184.    if ((rc = GetCommError (nCid, NULL)) != 0)
  185.    {
  186.       printmsg(0, "openline: Error condition reset on port %s.", name);
  187.       ShowError(rc);
  188.    }
  189.  
  190. /*--------------------------------------------------------------------*/
  191. /*                           Set baud rate                            */
  192. /*--------------------------------------------------------------------*/
  193.  
  194.    nSIOSpeed(baud);
  195.  
  196. /*--------------------------------------------------------------------*/
  197. /*                        Set line attributes                         */
  198. /*--------------------------------------------------------------------*/
  199.  
  200.    printmsg(15,"openline: Getting attributes");
  201.    if ((rc = GetCommState(nCid, &dcb)) != 0)
  202.    {
  203.       printmsg(0,"nopenline: %s: GetCommState was %#04x (%d)",
  204.                   name,
  205.                   rc,
  206.                   rc);
  207.       panic();
  208.    }
  209.  
  210.    dcb.StopBits = ONESTOPBIT;
  211.    dcb.Parity = NOPARITY;
  212.    dcb.ByteSize = 8;
  213.  
  214. /*--------------------------------------------------------------------*/
  215. /*                      Set up for Flow Control                       */
  216. /*--------------------------------------------------------------------*/
  217.  
  218.    printmsg(15,"openline: Disabling XON/XOFF flow control");
  219.  
  220.    dcb.fOutX = 0;
  221.    dcb.fInX = 0;
  222.    if(!direct)                 /* nodirect means RTS/CTS flow OK      */
  223.    {
  224. #ifdef UDEBUG
  225.       printmsg(15, "openline: Enabling RTS/CTS flow control");
  226. #endif
  227.       dcb.fOutxCtsFlow = 1;
  228.       dcb.fRtsflow = 1;
  229.       dcb.XoffLim = IN_XOFF_LIM;
  230.       dcb.XonLim = IN_XON_LIM;
  231.    }
  232.    else {
  233. #ifdef UDEBUG
  234.       printmsg(4, "openline: Disabling RTS/CTS flow control");
  235. #endif
  236.       dcb.fOutxCtsFlow = 0;
  237.       dcb.fRtsflow = 0;
  238.    }
  239.  
  240. /*--------------------------------------------------------------------*/
  241. /*                Set up for Modem Control as needed                  */
  242. /*--------------------------------------------------------------------*/
  243.  
  244.    dcb.fDtrDisable = 0;
  245.    dcb.fRtsDisable = 0;
  246.  
  247. /*--------------------------------------------------------------------*/
  248. /*              Modify the DCB with the new attributes                */
  249. /*--------------------------------------------------------------------*/
  250.  
  251. #ifdef UDEBUG
  252.    printmsg(15,"openline: Setting attributes");
  253. #endif
  254.  
  255.    if ((rc = SetCommState(&dcb)) != 0)
  256.    {
  257.       printmsg(0,"nopenline: %s: return code from SetCommState was %#04X (%d)",
  258.                  name,
  259.                  rc,
  260.                  rc);
  261.       panic();
  262.    }
  263.  
  264. /*--------------------------------------------------------------------*/
  265. /*                 Assure RTS and DTR are asserted                    */
  266. /*--------------------------------------------------------------------*/
  267.  
  268.  
  269. #ifdef UDEBUG
  270.    printmsg(15,"openline: Raising RTS/DTR");
  271. #endif
  272.  
  273.    if (EscapeCommFunction(nCid, SETRTS) != 0)
  274.    {
  275.       printmsg(0, "openline: Failed to raise RTS for %s", name);
  276.       panic();
  277.    }
  278.    if (EscapeCommFunction(nCid, SETDTR) != 0)
  279.    {
  280.       printmsg(0, "openline: Unable to raise DTR for %s", name);
  281.       panic();
  282.    }
  283.  
  284.    ShowModem();
  285.  
  286. /*--------------------------------------------------------------------*/
  287. /*        Log serial line data only if log file already exists        */
  288. /*--------------------------------------------------------------------*/
  289.  
  290.    traceStart( name );
  291.  
  292.    portActive = TRUE;     /* record status for error handler */
  293.  
  294. /*--------------------------------------------------------------------*/
  295. /*                     Wait for port to stablize                      */
  296. /*--------------------------------------------------------------------*/
  297.  
  298.    ssleep(2);              /* Allow port to stabilize per V.24  */
  299.  
  300.    return 0;
  301.  
  302. } /* nopenline */
  303.  
  304. /*--------------------------------------------------------------------*/
  305. /*    s r e a d                                                       */
  306. /*                                                                    */
  307. /*    Read from the serial port                                       */
  308. /*                                                                    */
  309. /*   Non-blocking read essential to "g" protocol. The rather cryptic  */
  310. /*   "description" in dcpgpkt.c is:                                   */
  311. /*                                                                    */
  312. /*   sread(buf, n, timeout)                                           */
  313. /*      while(TRUE)                                                   */
  314. /*         if # of chars available >= n (w/o dec internal counter)    */
  315. /*            read n chars into buf (dec internal counter)            */
  316. /*            break                                                   */
  317. /*         else                                                       */
  318. /*            if time > timeout                                       */
  319. /*               break                                                */
  320. /*                                                                    */
  321. /*   NOTE: Timeout of 0 returns right away, indicating the number of  */
  322. /*         bytes in our local receive buffer. There's GOTTA be a      */
  323. /*         better way...                                              */
  324. /*                                                                    */
  325. /*   This all changes in a multi-tasking system.  Requests for I/O    */
  326. /*   should get queued and an event flag given.  Then the             */
  327. /*   requesting process (e.g. gmachine()) waits for the event flag    */
  328. /*   to fire processing either a read or a write.  Could be           */
  329. /*   implemented on VAX/VMS or DG but not MS-DOS.                     */
  330. /*                                                                    */
  331. /*--------------------------------------------------------------------*/
  332.  
  333. unsigned int nsread(char *output, unsigned int wanted, unsigned int timeout)
  334.  
  335. {
  336.    int rc, received;
  337.    time_t stop_time;
  338.    time_t now;
  339.    COMSTAT stat;
  340.  
  341.    //
  342.    // This catches a fencepost condition later...
  343.    //
  344.  
  345.    if (wanted == 0)
  346.    {
  347.       ddelay(0);
  348.       return(0);
  349.    }
  350.  
  351. /*--------------------------------------------------------------------*/
  352. /*                      Report our modem status                       */
  353. /*--------------------------------------------------------------------*/
  354.  
  355.   ShowModem();
  356.  
  357. /*--------------------------------------------------------------------*/
  358. /*                 Determine when to stop processing                  */
  359. /*--------------------------------------------------------------------*/
  360.  
  361.    if ( timeout == 0 )        /* 0 = don't wait around.               */
  362.    {
  363.       stop_time = 0;
  364.       now = 1;                /* Any number greater than stop time    */
  365.    }
  366.    else {
  367.       time( & now );
  368.       stop_time = now + timeout;
  369.    }
  370.  
  371. /*--------------------------------------------------------------------*/
  372. /*       Watch RX Queue till wanted bytes available or timeout        */
  373. /*--------------------------------------------------------------------*/
  374.  
  375.    while(TRUE)
  376.    {
  377.  
  378.       //
  379.       // Check & clear the comm port. This gets the #chars in the
  380.       // receive queue as well, in the COMSTAT structure.
  381.       //
  382.  
  383.       if ((rc = GetCommError(nCid, &stat)) != 0)
  384.       {
  385.          printmsg(0,"sread: Read of %d bytes failed.", wanted);
  386.          printmsg(0,"       return code from GetCommError was %#04x (%d)",
  387.                                                 rc , rc);
  388.          ShowError(rc);
  389.          return 0;
  390.       }
  391.  
  392.       //
  393.       // If wanted # bytes are available, break out and read 'em.
  394.       //
  395.  
  396.       if (stat.cbInQue >= wanted)
  397.          break;               /* We have enough, break out!           */
  398.  
  399.       //
  400.       // Be friendly to Windows' cooperative multitasking...
  401.       //
  402.  
  403.       ddelay(0);
  404.  
  405.       //
  406.       // If timeout is zero, return immediately.
  407.       //
  408.  
  409.       if (stop_time == 0)
  410.          return(stat.cbInQue);
  411.  
  412.       //
  413.       // Check for timeout. If timed out, return.
  414.       //
  415.  
  416.       time( &now );
  417.       if(stop_time <= now)
  418.       {
  419.          printmsg(15, "sread: timeout(%d) - %d chars avail",
  420.                          timeout, stat.cbInQue);
  421.          return(stat.cbInQue);
  422.       }
  423.  
  424.    } // end of while(TRUE)
  425.  
  426.    //
  427.    // We have enough in the RX queue. Grab 'em right into the
  428.    // caller's buffer.
  429.    //
  430.  
  431.    received = ReadComm(nCid, output, wanted);
  432.  
  433.    printmsg(15, "sread: Got %d characters, %d still in RX queue.",
  434.                    (int)received, (int)(stat.cbInQue - received));
  435.  
  436. /*--------------------------------------------------------------------*/
  437. /*                    Log the newly received data                     */
  438. /*--------------------------------------------------------------------*/
  439.  
  440.    traceData( output, wanted, FALSE );
  441.  
  442.    return(received);
  443.  
  444. } /* nsread */
  445.  
  446. /*--------------------------------------------------------------------*/
  447. /*    n s w r i t e                                                   */
  448. /*                                                                    */
  449. /*    Write to the serial port                                        */
  450. /*--------------------------------------------------------------------*/
  451.  
  452. int nswrite(const char *data, unsigned int len)
  453. {
  454.    int bytes;
  455.    int rc;
  456.  
  457.    hangupNeeded = TRUE;      /* Flag that the port is now dirty  */
  458.  
  459. /*--------------------------------------------------------------------*/
  460. /*                      Report our modem status                       */
  461. /*--------------------------------------------------------------------*/
  462.  
  463.    ShowModem();
  464.  
  465. /*--------------------------------------------------------------------*/
  466. /*         Write the data out as the queue becomes available          */
  467. /*--------------------------------------------------------------------*/
  468.  
  469.    bytes = WriteComm(nCid, data, len);
  470.  
  471.    rc = GetCommError(nCid, NULL);
  472.    if (rc)
  473.    {
  474.       printmsg(0,"nswrite: WriteComm failed, "
  475.                  "return code from GetCommError was %#04x (%d)",
  476.                         rc , rc);
  477.       ShowError(rc);
  478.       return bytes;
  479.    }
  480.  
  481. /*--------------------------------------------------------------------*/
  482. /*                        Log the data written                        */
  483. /*--------------------------------------------------------------------*/
  484.  
  485.    traceData( data, len, TRUE );
  486.  
  487. /*--------------------------------------------------------------------*/
  488. /*            Return bytes written to the port to the caller          */
  489. /*--------------------------------------------------------------------*/
  490.  
  491.    return len;
  492.  
  493. } /* nswrite */
  494.  
  495. /*--------------------------------------------------------------------*/
  496. /*    n s s e n d b r k                                               */
  497. /*                                                                    */
  498. /*    send a break signal out the serial port                         */
  499. /*--------------------------------------------------------------------*/
  500.  
  501. void nssendbrk(unsigned int duration)
  502. {
  503.  
  504.  
  505. #ifdef UDEBUG
  506.    printmsg(12, "ssendbrk: %d", duration);
  507. #endif
  508.  
  509.    SetCommBreak(nCid);
  510.    ddelay(duration == 0 ? 200 : duration);
  511.    ClearCommBreak(nCid);
  512.  
  513. } /*ssendbrk*/
  514.  
  515. /*--------------------------------------------------------------------*/
  516. /*    n c l o s e l i n e                                             */
  517. /*                                                                    */
  518. /*    Close the serial port down                                      */
  519. /*--------------------------------------------------------------------*/
  520.  
  521. void ncloseline(void)
  522. {
  523.  
  524.    if ( ! portActive )
  525.       panic();
  526.  
  527.    portActive = FALSE;     /* flag port closed for error handler  */
  528.    hangupNeeded = FALSE;  /* Don't fiddle with port any more     */
  529.  
  530. /*--------------------------------------------------------------------*/
  531. /*                             Lower DTR                              */
  532. /*--------------------------------------------------------------------*/
  533.  
  534.     if (EscapeCommFunction(nCid, CLRDTR | CLRRTS) != 0)
  535.         printmsg(0,"closeline: Unable to lower DTR/RTS");
  536.  
  537. /*--------------------------------------------------------------------*/
  538. /*                      Actually close the port                       */
  539. /*--------------------------------------------------------------------*/
  540.  
  541.    if(CloseComm(nCid) != 0)
  542.       printmsg(0, "closeline: close of serial port failed");
  543.  
  544. /*--------------------------------------------------------------------*/
  545. /*                   Stop logging the data to disk                    */
  546. /*--------------------------------------------------------------------*/
  547.  
  548.    traceStop();
  549.  
  550.    printmsg(3,"Serial port closed");
  551.  
  552. } /* ncloseline */
  553.  
  554. /*--------------------------------------------------------------------*/
  555. /*    n h a n g u p                                                   */
  556. /*                                                                    */
  557. /*    Hangup the telephone by dropping DTR.  Works with HAYES and     */
  558. /*    many compatibles.                                               */
  559. /*    14 May 89 Drew Derbyshire                                       */
  560. /*--------------------------------------------------------------------*/
  561.  
  562. void nhangup( void )
  563. {
  564.    hangupNeeded = FALSE;
  565.  
  566. /*--------------------------------------------------------------------*/
  567. /*                              Drop DTR                              */
  568. /*--------------------------------------------------------------------*/
  569.  
  570.    if (EscapeCommFunction(nCid, CLRDTR) != 0)
  571.    {
  572.       printmsg(0, "hangup: Unable to lower DTR for comm port");
  573.       panic();
  574.    }
  575.  
  576. /*--------------------------------------------------------------------*/
  577. /*                  Wait for the telephone to hangup                  */
  578. /*--------------------------------------------------------------------*/
  579.  
  580.    printmsg(3,"hangup: Dropped DTR");
  581.    ddelay(1000);            /* Really only need 250 milliseconds (HA) */
  582.  
  583. /*--------------------------------------------------------------------*/
  584. /*                          Bring DTR backup                          */
  585. /*--------------------------------------------------------------------*/
  586.  
  587.    if (EscapeCommFunction(nCid, SETDTR) != 0)
  588.    {
  589.       printmsg(0, "hangup: Unable to raise DTR for comm port");
  590.       panic();
  591.    }
  592.    ddelay(500);         /* Now wait for the poor thing to recover    */
  593.  
  594. } /* nhangup */
  595.  
  596. /*--------------------------------------------------------------------*/
  597. /*       S I O S p e e d                                              */
  598. /*                                                                    */
  599. /*       Re-specify the speed of an opened serial port                */
  600. /*--------------------------------------------------------------------*/
  601.  
  602. void nSIOSpeed(BPS baud)
  603. {
  604.    WORD rc;
  605.  
  606.    currentSpeed = (UINT) baud;
  607.    printmsg(15,"SIOSpeed: Setting baud rate to %lu",
  608.                (unsigned long) currentSpeed);
  609.  
  610.    ShowModem();
  611.    GetCommState (nCid, &dcb);
  612.  
  613.    dcb.BaudRate = currentSpeed;
  614.    rc = SetCommState (&dcb);
  615.  
  616.    if (rc)
  617.    {
  618.       printmsg(0,"SIOSPeed: Unable to set baud rate for port to %lu",
  619.                  (unsigned long) currentSpeed);
  620.       panic();
  621.    }
  622.  
  623. } /* nSIOSpeed */
  624.  
  625. /*--------------------------------------------------------------------*/
  626. /*    n f l o w c o n t r o l                                         */
  627. /*                                                                    */
  628. /*    Enable/Disable in band (XON/XOFF) flow control                  */
  629. /*--------------------------------------------------------------------*/
  630.  
  631. void nflowcontrol( boolean flow )
  632. {
  633.    int rc;
  634.    DCB dcb;
  635.  
  636.    GetCommState(nCid, &dcb);
  637.  
  638.    if (flow)
  639.    {
  640.       dcb.fOutX = TRUE;
  641.       dcb.fInX = TRUE;
  642.       dcb.fRtsflow = FALSE;
  643.       dcb.fOutxCtsFlow = FALSE;
  644.    }
  645.    else {
  646.       dcb.fOutX = FALSE;
  647.       dcb.fInX = FALSE;
  648.       dcb.fRtsflow = TRUE;
  649.       dcb.fOutxCtsFlow = TRUE;
  650.    }
  651.  
  652.    if ((rc = SetCommState(&dcb)) != 0)
  653.    {
  654.       printmsg(0,"flowcontrol: Unable to set flow control");
  655.       printmsg(0,"Return code fromSetCommState was %#04x (%d)",
  656.                   (int) rc,
  657.                   (int) rc);
  658.       panic();
  659.    } /*if */
  660.  
  661. } /* nflowcontrol */
  662.  
  663. /*--------------------------------------------------------------------*/
  664. /*    n G e t S p e e d                                               */
  665. /*                                                                    */
  666. /*    Report current speed of communications connection               */
  667. /*--------------------------------------------------------------------*/
  668.  
  669. BPS nGetSpeed( void )
  670. {
  671.    return currentSpeed;
  672. } /* GetSpeed */
  673.  
  674. /*--------------------------------------------------------------------*/
  675. /*   n C D                                                            */
  676. /*                                                                    */
  677. /*   Return status of carrier detect                                  */
  678. /*--------------------------------------------------------------------*/
  679.  
  680. boolean nCD( void )
  681. {
  682.    boolean online = carrierdetect;
  683.    boolean modem_present;
  684.  
  685.    carrierdetect = ((*lpbModemBits & MSR_RLSD) != 0);
  686.    modem_present = ((*lpbModemBits & MSR_DSR) != 0);
  687.  
  688. /*--------------------------------------------------------------------*/
  689. /*    If we previously had carrier detect but have lost it, we        */
  690. /*    report it was lost.  If we do not yet have carrier detect,      */
  691. /*    we return success because we may not have connected yet.        */
  692. /*    If DSR is not present, we always report no carrier, as there    */
  693. /*    is either no modem at all(!) or it's not turned on.             */
  694. /*--------------------------------------------------------------------*/
  695.  
  696.    if (online)
  697.       return (modem_present && carrierdetect);
  698.    else
  699.       return (modem_present);
  700.  
  701. } /* nCD */
  702.  
  703. /*--------------------------------------------------------------------*/
  704. /*    S h o w M o d e m                                               */
  705. /*                                                                    */
  706. /*    Report current modem status when changed from last call         */
  707. /*--------------------------------------------------------------------*/
  708.  
  709. #define mannounce(flag, bits, text ) (((flag & bits) != 0) ? text : "" )
  710.  
  711. static void ShowModem( void )
  712. {
  713.    BYTE modem_bits = *lpbModemBits;
  714.    static BYTE old_bits = 0xFF;
  715.  
  716.    if ( debuglevel < 4 )
  717.       return;
  718.  
  719.    if ( (debuglevel < 4) ||            /* Silent at lower debuglevels  */
  720.       (modem_bits == old_bits))        /* Show only changes in modem signals  */
  721.       return;
  722.  
  723.    printmsg(0, "ShowModem: %#02x %s %s %s",
  724.                 modem_bits,
  725.                 mannounce(MSR_RLSD,  modem_bits, "DCD"),
  726.                 mannounce(MSR_DSR,   modem_bits, "DSR"),
  727.                 mannounce(MSR_CTS,   modem_bits, "CTS"));
  728.    old_bits = modem_bits;
  729.  
  730. } /* ShowModem */
  731.  
  732. /*--------------------------------------------------------------------*/
  733. /*    S h o w E r r o r                                               */
  734. /*                                                                    */
  735. /*    Report modem error bits in English (more or less)               */
  736. /*--------------------------------------------------------------------*/
  737.  
  738. static void ShowError( int status )
  739. {
  740.    printmsg(2, "Port Error: %#04x%s%s%s%s%s",
  741.       status,
  742.       mannounce(CE_RXOVER,   status, " Recv Queue Ovfl"),
  743.       mannounce(CE_OVERRUN,  status, " Hardware Overrun"),
  744.       mannounce(CE_RXPARITY, status, " Parity Error"),
  745.                 mannounce(CE_FRAME,    status, " Framing Error"),
  746.                 mannounce(CE_TXFULL,   status, " Xmit Queue Full"));
  747.  
  748. } /* ShowError */
  749.  
  750. /*--------------------------------------------------------------------*/
  751. /*       s e t P r t y                                                */
  752. /*                                                                    */
  753. /*       No operation under Windows                                   */
  754. /*--------------------------------------------------------------------*/
  755.  
  756. #ifdef __TURBOC__
  757. #pragma argsused
  758. #endif
  759.  
  760. void setPrty( const KEWSHORT priorityIn, const KEWSHORT prioritydeltaIn )
  761. {
  762.  
  763. } /* setPrty */
  764.  
  765. /*--------------------------------------------------------------------*/
  766. /*       r e s e t P r t y                                            */
  767. /*                                                                    */
  768. /*       No operation under Windows                                   */
  769. /*--------------------------------------------------------------------*/
  770.  
  771. void resetPrty( void )
  772. {
  773. } /* resetPrty */
  774.