home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1996 October / PCO_10.ISO / filesbbs / bsrc_260.arj / SRC.ZIP / async.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-20  |  12.0 KB  |  495 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*               This module was written by Peter Fitzsimmons               */
  13. /*                                                                          */
  14. /*                 BinkleyTerm OS/2 Async Comm I/O Routines                 */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. #ifndef OS_2
  49. #pragma message("This Module For OS/2")
  50. #else
  51.  
  52. /* These must be in "includes.h" for C7 precompiled headers to work (as if
  53.    we'll ever get any MS support for OS/2-targetted C7!!!)
  54.  
  55.    #define INCL_DOS
  56.    #define INCL_DOSERRORS
  57.    #define INCL_DOSDEVIOCTL
  58.    #include "includes.h"   (And this I put up top to avoid confusion) */
  59.  
  60. /* This module by Peter Fitzsimmons */
  61. /* Modified 6/13/92 for exit (3) WRA */
  62.  
  63. HCOMM hcModem = 0;                /* comm.dll handle */
  64.  
  65. #define RBSIZE    8200            /* MB */
  66. #define TBSIZE    8200            /* MB */
  67.  
  68. USHORT rBufsize = RBSIZE;
  69. USHORT tBufsize = TBSIZE;
  70.  
  71. void
  72. com_DTR_on (void)
  73. {
  74.     DCBINFO sDCB;
  75.     USHORT rc;
  76.  
  77.     if (!(rc = ComGetDCB (hcModem, &sDCB)))
  78.     {
  79.         sDCB.fbCtlHndShake |= MODE_DTR_CONTROL;        /* raise DTR */
  80.         ComSetDCB (hcModem, &sDCB);
  81.     }
  82.     else
  83.     {
  84.         status_line ("!SYS%04hu: ComGetDCB()", rc);
  85.         exit (3);
  86.     }
  87. }
  88.  
  89. void
  90. com_DTR_off (void)
  91. {
  92.     DCBINFO sDCB;
  93.     USHORT rc;
  94.  
  95.     if (!(rc = ComGetDCB (hcModem, &sDCB)))
  96.     {
  97.         sDCB.fbCtlHndShake &= ~MODE_DTR_CONTROL;    /* lower DTR */
  98.         ComSetDCB (hcModem, &sDCB);
  99.         com_kick ();
  100.     }
  101.     else
  102.     {
  103.         status_line ("!SYS%04hu: ComGetDCB()", rc);
  104.         exit (3);
  105.     }
  106. }
  107.  
  108. void
  109. com_XON_disable (void)
  110. {
  111.     DCBINFO sDCB;
  112.     USHORT rc;
  113.  
  114.     if (!(rc = ComGetDCB (hcModem, &sDCB)))
  115.     {
  116.         /* disable auto Xmit and recv flow control */
  117.  
  118.         sDCB.fbFlowReplace &= ~(MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE);
  119.         ComSetDCB (hcModem, &sDCB);
  120.         com_kick ();
  121.     }
  122.     else
  123.     {
  124.         status_line ("!SYS%04hu: ComGetDCB()", rc);
  125.         exit (3);
  126.     }
  127. }
  128.  
  129. void
  130. com_XON_enable (void)
  131. {
  132.     DCBINFO sDCB;
  133.     USHORT rc;
  134.  
  135.     if (!(rc = ComGetDCB (hcModem, &sDCB)))
  136.     {
  137.         /* enable auto Xmit and recv flow control */
  138.  
  139.         sDCB.fbFlowReplace |= MODE_AUTO_TRANSMIT;    /*PLF Wed  04-04-1990  02:35:41 */
  140.         ComSetDCB (hcModem, &sDCB);
  141.     }
  142.     else
  143.     {
  144.         status_line ("!SYS%04hu: ComGetDCB()", rc);
  145.         exit (3);
  146.     }
  147. }
  148.  
  149. int
  150. com_getc (int t)
  151. {
  152.     if (t)
  153.         ComRxWait (hcModem, t * 1000L);
  154.     return ComGetc (hcModem);
  155. }
  156.  
  157. /* com_break() : start break if on==TRUE, stop break if on==FALSE */
  158.  
  159. void
  160. com_break (int on)
  161. {
  162. #ifndef __32BIT__
  163.     int cmd;
  164.     USHORT comerr, rc;
  165.     HFILE hf;
  166.  
  167.     cmd = (on) ? ASYNC_SETBREAKON : ASYNC_SETBREAKOFF;
  168.     hf = ComGetFH (hcModem);
  169.     if (hf)
  170.     {
  171.         rc = DosDevIOCtl (&comerr, NULL, (USHORT) cmd, IOCTL_ASYNC, hf);
  172.         if (rc)
  173.         {
  174.             status_line ("!SYS%04hu: ASYNC_SETBREAK", rc);
  175.             exit (3);
  176.         }
  177.     }
  178. #else
  179.     ULONG cmd;
  180.     HFILE hf;
  181.     PVOID ParmList;
  182.     ULONG ParmLengthMax;
  183.     ULONG ParmLengthInOut;
  184.     UCHAR DataArea[2];
  185.     ULONG DataLengthMax;
  186.     ULONG DataLengthInOut;
  187.     APIRET rc;
  188.  
  189.     ParmList = 0;
  190.     ParmLengthInOut = 0;
  191.     ParmLengthMax = 0;
  192.  
  193.     DataLengthInOut = 0;
  194.     DataLengthMax = 2;
  195.  
  196.     cmd = (on) ? ASYNC_SETBREAKON : ASYNC_SETBREAKOFF;
  197.     hf = ComGetFH (hcModem);
  198.     if (hf)
  199.     {
  200.         /*      rc = DosDevIOCtl(&comerr, 0L, cmd, IOCTL_ASYNC, hf); */
  201.         rc = DosDevIOCtl (hf, IOCTL_ASYNC, cmd, ParmList, ParmLengthMax,
  202.             &ParmLengthInOut, DataArea, DataLengthMax,
  203.             &DataLengthInOut);
  204.         if (rc)
  205.             status_line ("!SYS%04ld: ASYNC_SETBREAK", rc);
  206.     }
  207. #endif
  208. }
  209.  
  210. void
  211. MDM_ENABLE (unsigned long rate)
  212. {
  213.     char _parity;
  214.     short databits;
  215.     short stopbits;
  216.  
  217.     if (!hcModem)
  218.         return;
  219.  
  220.     if (lock_baud && rate != max_baud.rate_value)
  221.     {
  222.         status_line (">Pretending baud is %lu (locked at %lu)", rate, max_baud.rate_value);
  223.         rate = max_baud.rate_value;
  224.     }
  225.     databits = 7 + (comm_bits == BITS_8);
  226.     stopbits = 1 + (stop_bits == STOP_2);
  227.     switch (parity)
  228.     {
  229.     case NO_PARITY:
  230.         _parity = 'N';
  231.         break;
  232.     case ODD_PARITY:
  233.         _parity = 'O';
  234.         break;
  235.     case EVEN_PARITY:
  236.         _parity = 'E';
  237.         break;
  238.     default:
  239.         _parity = 'N';
  240.         status_line ("!Invalid parity");
  241.     }
  242.     ComSetBaudRate (hcModem, (long) rate, _parity, (USHORT) databits, (USHORT) stopbits);
  243. }
  244.  
  245. void
  246. MDM_DISABLE (void)
  247. {
  248.     if (hcModem)
  249.     {
  250.         ComClose (hcModem);
  251.         hcModem = 0;
  252.     }
  253. }
  254.  
  255. void
  256. ShowMdmSettings (void)
  257. {
  258.     DCBINFO dcb;
  259.     USHORT rc;
  260.     char *On = "On";
  261.     char *Off = "Off";
  262.     char *dtr;
  263.     char *rts;
  264.     char *buffer;
  265.     short Rx = 0, Tx;
  266.  
  267.     if (!(rc = ComGetDCB (hcModem, &dcb)))
  268.     {
  269.         status_line (">Modem: TO=%s,XON(Rx)=%s,XON(Tx)=%s",
  270.             (dcb.fbTimeout & MODE_NO_WRITE_TIMEOUT) ? On : Off,
  271.             (dcb.fbFlowReplace & MODE_AUTO_RECEIVE) ? On : Off,
  272.             (dcb.fbFlowReplace & MODE_AUTO_TRANSMIT) ? On : Off);
  273.         status_line (">Modem: IDSR=%s,ODSR=%s,OCTS=%s",
  274.             (dcb.fbCtlHndShake & MODE_DSR_SENSITIVITY) ? On : Off,
  275.             (dcb.fbCtlHndShake & MODE_DSR_HANDSHAKE) ? On : Off,
  276.             (dcb.fbCtlHndShake & MODE_CTS_HANDSHAKE) ? On : Off);
  277.         switch (dcb.fbCtlHndShake & (MODE_DTR_CONTROL | MODE_DTR_HANDSHAKE))
  278.         {
  279.         case 0:
  280.             dtr = Off;
  281.             break;
  282.         case MODE_DTR_CONTROL:
  283.             dtr = On;
  284.             break;
  285.         case MODE_DTR_HANDSHAKE:
  286.             dtr = "IHS";
  287.             break;                /* input handshaking */
  288.         default:
  289.             dtr = "??";
  290.             break;
  291.         }
  292.         switch (dcb.fbFlowReplace & (MODE_RTS_CONTROL | MODE_RTS_HANDSHAKE | MODE_TRANSMIT_TOGGLE))
  293.         {
  294.         case 0:
  295.             rts = Off;
  296.             break;
  297.         case MODE_RTS_CONTROL:
  298.             rts = On;
  299.             break;
  300.         case MODE_RTS_HANDSHAKE:
  301.             rts = "IHS";
  302.             break;
  303.         case MODE_TRANSMIT_TOGGLE:
  304.             rts = "TOG";
  305.             break;
  306.         default:
  307.             rts = "??";
  308.             break;
  309.         }
  310.         switch (dcb.fbTimeout & 0x18)
  311.         {
  312.         case 0x08:
  313.             buffer = Off;
  314.             break;
  315.         case 0x10:
  316.             buffer = On;
  317.             break;
  318.         case 0x18:
  319.             buffer = "Auto";
  320.             break;
  321.         default:
  322.             buffer = "??";
  323.             break;
  324.         }
  325.         switch (dcb.fbTimeout & 0x60)
  326.         {
  327.         case 0:
  328.             Rx = 1;
  329.             break;
  330.         case 0x20:
  331.             Rx = 4;
  332.             break;
  333.         case 0x40:
  334.             Rx = 8;
  335.             break;
  336.         case 0x60:
  337.             Rx = 14;
  338.             break;
  339.         }
  340.         Tx = (dcb.fbTimeout & 0x80) ? 16 : 1;
  341.         status_line (">Modem: DTR=%s,RTS=%s,BUFFER=%s (Rx=%hd, Tx=%hd)",
  342.             dtr,
  343.             rts,
  344.             buffer,
  345.             Rx, Tx);
  346.         status_line(">Modem: Buffers R: %hu T: %hu", rBufsize, tBufsize);   /* MB 94-01-02 */
  347.     }
  348.     else
  349.     {
  350.         status_line ("!SYS%04hu: ComGetDCB()", rc);
  351.         exit (3);
  352.     }
  353. }
  354.  
  355. unsigned
  356. Cominit (int port, int failsafe)
  357. {
  358.     char tmp[5];
  359.     USHORT rc;
  360.     char *s;
  361.  
  362.     failsafe = failsafe;
  363.  
  364.     if (!hcModem)
  365.     {
  366.         s = getenv("RBUF");              /* MB 94-01-02 */
  367.         if (s)
  368.             rBufsize = (USHORT)min( 32000, atoi(s));
  369.         else
  370.             rBufsize = RBSIZE;
  371.  
  372.         s = getenv("TBUF");
  373.         if (s)
  374.             tBufsize = (USHORT)min( 32000, atoi(s));
  375.         else
  376.         tBufsize = TBSIZE;
  377.  
  378.         sprintf (tmp, "com%1u", port + 1);
  379.         /*DosSetPrty(PRTYS_PROCESS, PRTYC_FOREGROUNDSERVER, 0, 0);*/
  380.         rc = ComOpen ((PSZ) tmp, &hcModem, rBufsize, tBufsize);
  381.         if (rc)
  382.         {
  383.             status_line ("!SYS%04hu:  ComOpen(%s)", rc, tmp);
  384.             /*          return(0); */
  385.             exit (3);
  386.         }
  387.         else
  388.             ShowMdmSettings ();
  389.     }
  390.     else
  391.         ComResume (hcModem);
  392.     return (0x1954);
  393. }
  394.  
  395. /* force transmitter to go */
  396. void
  397. com_kick (void)
  398. {
  399. #ifndef __32BIT__
  400.     USHORT rc;
  401.     HFILE hf;
  402.  
  403.     if (hcModem)
  404.     {
  405.         hf = ComGetFH (hcModem);
  406.         if (hf)
  407.         {
  408.             rc = DosDevIOCtl ((PVOID) 0L, (PVOID) 0L, ASYNC_STARTTRANSMIT, IOCTL_ASYNC, (HFILE) hfComHandle);
  409.             if (rc)
  410.             {
  411.                 status_line ("!SYS%04hu: ASYNC_STARTTRANSMIT", rc);
  412.                 /*                exit (3); */
  413.             }
  414.         }
  415.     }
  416. #else
  417.     HFILE hf;
  418.     PVOID ParmList;
  419.     ULONG ParmLengthMax;
  420.     ULONG ParmLengthInOut;
  421.     PVOID DataArea;
  422.     ULONG DataLengthMax;
  423.     ULONG DataLengthInOut;
  424.     APIRET rc;
  425.  
  426.     ParmList = 0;
  427.     ParmLengthInOut = 0;
  428.     ParmLengthMax = 0;
  429.  
  430.     DataArea = 0;
  431.     DataLengthInOut = 0;
  432.     DataLengthMax = 0;
  433.  
  434.     if (hcModem)
  435.     {
  436.         hf = ComGetFH (hcModem);
  437.         if (hf)
  438.         {
  439.             rc = DosDevIOCtl (hf, IOCTL_ASYNC, ASYNC_STARTTRANSMIT, ParmList, ParmLengthMax,
  440.                 &ParmLengthInOut, DataArea, DataLengthMax,
  441.                 &DataLengthInOut);
  442.             if (rc && rc != 31)
  443.             {
  444.                 status_line ("!SYS%04ld: ASYNC_STARTTRANSMIT", rc);
  445.                 /*                exit (3); */
  446.             }
  447.         }
  448.     }
  449. #endif
  450. }
  451.  
  452. /* Currently only used by HYDRA */
  453.  
  454. /*
  455.  * This is a lot like ComWrite, but will return the sent-character
  456.  * count if either a timeout occurs or carrier is lost. The timer
  457.  * is specified by passing in a time_t for end-of-time. If zero is
  458.  * passed for the timer, we'll just check for carrier loss.
  459.  *
  460.  */
  461.  
  462. USHORT
  463. ComTXBlockTimeout (BYTE *lpBuf, USHORT cbBuf, ULONG ulTimer)
  464. {
  465.     USHORT cbRemaining = cbBuf;
  466.     USHORT cbToSend;
  467.     BOOL fTimedOut;
  468.  
  469.     fTimedOut = (ulTimer != 0) ? (ulTimer < (ULONG)time (NULL)) : FALSE;
  470.     while (!fTimedOut && CARRIER && cbRemaining)
  471.     {
  472.         cbToSend = ComOutSpace (hcModem);
  473.         if ((--cbToSend) > 0)
  474.         {
  475.             if (cbToSend > cbRemaining)
  476.                 cbToSend = cbRemaining;
  477.             ComWrite (hcModem, lpBuf, cbToSend);
  478.             lpBuf += cbToSend;
  479.             cbRemaining -= cbToSend;
  480.         }
  481.         else
  482.             time_release ();
  483.         fTimedOut = (ulTimer != 0) ? (ulTimer < (ULONG)time (NULL)) : FALSE;
  484.     }
  485.     return (cbBuf - cbRemaining);
  486. }
  487.  
  488. USHORT
  489. ComTXRemain (void)                /* MB 93-12-03 */
  490. {
  491.     return (tBufsize - ComOutSpace (hcModem));
  492. }
  493.  
  494. #endif                            /* OS_2 */
  495.