home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / pmtermsr.lzh / async.c next >
C/C++ Source or Header  |  1995-10-13  |  6KB  |  233 lines

  1. /*
  2.  * This file contains helper functions that are specific to programming
  3.  * the serial port (OpenPort, SetRate, etc)
  4.  */
  5.  
  6. #include "pmterm.h"
  7.  
  8. #ifndef ASYNC_EXTSETBAUDRATE
  9. #define ASYNC_EXTSETBAUDRATE  0x0043
  10. #define ASYNC_EXTGETBAUDRATE  0X0063
  11. #endif
  12.  
  13. HFILE OpenPort(char *name)
  14. {
  15.     HFILE hf;
  16.     APIRET rc;
  17.     ULONG ulAction;
  18.  
  19.     rc = DosOpen(name,                   /* pointer to filename                   */
  20.          &hf,                   /* pointer to variable for file handle           */
  21.          &ulAction,               /* pointer to variable for action taken           */
  22.          0L,                   /* file size if file is created or truncated    */
  23.          FILE_NORMAL,               /* file attribute                   */
  24.          OPEN_ACTION_OPEN_IF_EXISTS,   /* action if file exists/does not exist           */
  25.          OPEN_ACCESS_READWRITE |
  26.              OPEN_SHARE_DENYREADWRITE, /* open mode of file                   */
  27.          NULL);                /* pointer to structure for extended attributes */
  28.     if(rc){
  29.     printf( "sys%04u: error from dosopen(%s)\n", rc, name);
  30.     return 0xffff;
  31.     }
  32.     return hf;
  33. }
  34.  
  35.  
  36. int SetRate(HFILE hf, USHORT rate)  // returns 0 on success
  37. {
  38.     APIRET rc;
  39.     ULONG ulPinout, ulDinout;
  40.  
  41.     ulPinout = sizeof(rate);
  42.     ulDinout = 0;
  43.  
  44.     rc = DosDevIOCtl(hf,
  45.             IOCTL_ASYNC,
  46.             ASYNC_SETBAUDRATE,
  47.             &rate, sizeof(rate), &ulPinout,    /* parms */
  48.             NULL, 0, &ulDinout);        /* data */
  49.     if(rc)
  50.     printf("sys%04u: SetRate() error\n", rc);
  51.     return (int)rc;
  52. }
  53.  
  54. typedef struct _esrp
  55. {
  56.   ULONG ulBitRate;
  57.   BYTE    bFraction;
  58. } EXTSETRATEPARMS;
  59.  
  60. int SetRate2(HFILE hf, ULONG rate)  // returns 0 on success
  61. {
  62.     EXTSETRATEPARMS esr;
  63.     APIRET rc;
  64.     ULONG ulPinout, ulDinout;
  65.  
  66.     ulPinout = sizeof(esr);
  67.     ulDinout = 0;
  68.  
  69.     esr.ulBitRate = rate;
  70.     esr.bFraction = 0;
  71.  
  72.     rc = DosDevIOCtl(hf,
  73.             IOCTL_ASYNC,
  74.                     ASYNC_EXTSETBAUDRATE,
  75.             &esr, sizeof(esr), &ulPinout,     /* parms */
  76.             NULL, 0, &ulDinout);        /* data */
  77.     if(rc)
  78.     printf("sys%04u: SetRate2() error\n", rc);
  79.     return (int)rc;
  80. }
  81.  
  82. #pragma pack(1)
  83. typedef struct _eqrd
  84. {
  85.   ULONG ulBitRate;
  86.   BYTE    bFraction;
  87.   ULONG ulMinBitRate;
  88.   BYTE    bMinFraction;
  89.   ULONG ulMaxBitRate;
  90.   BYTE    bMaxFraction;
  91. } EXTQUERYRATEDATA;
  92. #pragma pack()
  93.  
  94. ULONG QueryMaxRate(HFILE hf)
  95. {
  96.     APIRET rc;
  97.     ULONG ulPinout, ulDinout;
  98.     EXTQUERYRATEDATA qbr;
  99.  
  100.     ulPinout = 0;
  101.     ulDinout = sizeof(qbr);
  102.     rc = DosDevIOCtl(hf,
  103.             IOCTL_ASYNC,
  104.                     ASYNC_EXTGETBAUDRATE,
  105.             NULL, 0, &ulPinout,
  106.             &qbr, sizeof(qbr), &ulDinout);    /* parms */
  107.     if(rc){
  108.     printf("SYS%04u:  Couldn't query baud rate\n", rc);
  109.     if(rc == ERROR_BAD_COMMAND)
  110.         printf("(may require a newer version of com*.sys or OS/2 to run this program)\n");
  111.     return 0;
  112.     }
  113.     printf("Current Rate = %ld\n", qbr.ulBitRate);
  114.     printf("Min     Rate = %ld\n", qbr.ulMinBitRate);
  115.     printf("Max     Rate = %ld\n", qbr.ulMaxBitRate);
  116.     return qbr.ulMaxBitRate;
  117. }
  118.  
  119. /*
  120.  * SetMode():  Set the desired READ MODE (Wait For Something)
  121.  * and WRITE MODE (near infinite)
  122.  */
  123. int SetMode(PDATA *pdata)
  124. {
  125.     DCBINFO dcb;
  126.     APIRET rc;
  127.     ULONG ulPinout, ulDinout;
  128.     LINECONTROL lc;
  129.     HFILE hf = pdata->hf;
  130.  
  131.  
  132.     ulPinout = 0;
  133.     ulDinout = sizeof(dcb);
  134.     if(0 != (rc = DosDevIOCtl(hf, IOCTL_ASYNC, ASYNC_GETDCBINFO,
  135.         NULL, 0, &ulPinout, &dcb, sizeof(dcb), &ulDinout)))
  136.     return rc;
  137.  
  138.     /* normal (not-infinite) write timeout processing */
  139.     dcb.fbTimeout &= ~MODE_NO_WRITE_TIMEOUT;
  140.  
  141.     /* make sure these bits are off */
  142.     dcb.fbTimeout &= ~(MODE_READ_TIMEOUT | MODE_NOWAIT_READ_TIMEOUT);
  143.  
  144.     /* set to "wait for something" read timeout processing */
  145.     dcb.fbTimeout |= MODE_WAIT_READ_TIMEOUT;
  146.  
  147.     dcb.usReadTimeout  = 100 * 5;
  148.     dcb.usWriteTimeout = 100 * 10;    /* ten second write timeout */
  149.  
  150.     dcb.fbCtlHndShake |= MODE_DTR_CONTROL;
  151.  
  152.     if(pdata->ini.CtsRts){
  153.     dcb.fbCtlHndShake |= MODE_CTS_HANDSHAKE;
  154.     dcb.fbFlowReplace |= MODE_RTS_HANDSHAKE;
  155.         dcb.fbFlowReplace &= ~MODE_RTS_CONTROL;
  156.     }
  157.     else{
  158.     dcb.fbCtlHndShake &= ~MODE_CTS_HANDSHAKE;
  159.     dcb.fbFlowReplace &= ~MODE_RTS_HANDSHAKE;
  160.     }
  161.  
  162.     if(pdata->ini.XonXoff)
  163.     dcb.fbFlowReplace |= (MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE);
  164.     else
  165.     dcb.fbFlowReplace &= ~(MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE);
  166.  
  167.     if(dcb.fbTimeout & EHB_MASK){
  168.     dcb.fbTimeout &= ~(EHB_MASK | EHB_RTL_14 | EHB_TBLC_16);
  169.     if(pdata->ini.ExtBuf){
  170.         dcb.fbTimeout |= EHB_ENABLE | EHB_RTL_8 | EHB_TBLC_16;
  171.     }
  172.     else
  173.         dcb.fbTimeout |= EHB_DISABLE;
  174.     }
  175.     else if(pdata->ini.ExtBuf){
  176.     ErrMesg(pdata, "%s does not support extended hardware buffering.",
  177.         pdata->ini.DevName);
  178.     }
  179.  
  180.     ulPinout = sizeof(dcb);
  181.     ulDinout = 0;
  182.     if(0 != (rc = DosDevIOCtl(hf, IOCTL_ASYNC, ASYNC_SETDCBINFO,
  183.     &dcb, sizeof(dcb), &ulPinout, NULL, 0, &ulDinout))){
  184.     return(rc);
  185.     }
  186.  
  187.     lc.bDataBits = pdata->ini.databits;
  188.     lc.bParity     = pdata->ini.parity  ;
  189.     lc.bStopBits = pdata->ini.stopbits;
  190.  
  191.     ulPinout = sizeof(lc);
  192.     ulDinout = 0;
  193.     if(0 != (rc = DosDevIOCtl(hf, IOCTL_ASYNC, ASYNC_SETLINECTRL,
  194.     &lc, sizeof(lc), &ulPinout, NULL, 0, &ulDinout))){
  195.     ErrMesg(pdata, "Error %d setting Databits, Parity, Stopbits", rc);
  196.     return(rc);
  197.     }
  198.  
  199.     return 0;
  200. }
  201.  
  202. int SetupPort(PDATA *pdata)
  203. {
  204.     HFILE hf;
  205.     int rc;
  206.     ULONG htype, hflag, ul;
  207.  
  208.     if(pdata->tidReadThread){
  209.         DosClose(pdata->hf);   // this will cause an error in the read thread
  210.     DosWaitThread(&pdata->tidReadThread, 0);
  211.     pdata->tidReadThread= 0;
  212.     }
  213.     pdata->hf = hf = OpenPort(pdata->ini.DevName);
  214.     if(pdata->hf == 0xffff){
  215.     ErrMesg(pdata, "Couldn't open '%s'", pdata->ini.DevName);
  216.     return FALSE;
  217.     }
  218.     DosQueryHType(hf, &htype, &hflag);
  219.     if(htype != HANDTYPE_FILE){
  220.         if(rc=SetMode(pdata)){
  221.             ErrMesg(pdata, "SetMode() error %d\n", rc);
  222.         }
  223.         if(rc=SetRate2(hf, pdata->ini.bps)){
  224.             ErrMesg(pdata, "SetRate() error %d\n", rc);
  225.         }
  226.         DosWrite(hf, pdata->ini.InitString, strlen(pdata->ini.InitString), &ul);
  227.         DosWrite(hf, "\r", 1, &ul);
  228.     }
  229.     pdata->tidReadThread = _beginthread(AsyncReadThread, NULL, 0x2000, pdata);
  230.     return TRUE;
  231. }
  232.  
  233.