home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 4 Drivers / 04-Drivers.zip / 594p.zip / DMODE.C < prev    next >
C/C++ Source or Header  |  1994-12-19  |  15KB  |  575 lines

  1.  
  2. static char CRevInfo[] =
  3. "@(#) $Header: c:/os2drv/xall/RCS/dmode.c 1.23 1994/12/19 13:28:20 JPM ENHANCEMENT $";
  4. #ifdef COPYRIGHT_NOTICE
  5.  
  6.   (c) Copyright 1990-1943 Digi International Inc. ALl Rights Reserved.
  7.  
  8.   This software contains proprietary and confidential information of Digi
  9.   International, Inc.  By accepting transfer of this copy, recipient agrees
  10.   to retain this software in confidence, to prevent disclosure to others,
  11.   and to make no use of this software other than that for which it was
  12.   delivered.  This is an unpublished copyrighted work of Digi International
  13.   Inc.  Except as permitted by  federal law, 17 USC 117, copying is strictly
  14.   prohibited.
  15.  
  16.   Use, duplication, or disclosure by the Government is subject to restrictions
  17.   set forth in sub-paragraph (c)(1)(ii) of the Rights in Technical Data
  18.   and Computer Software clause of FDARS 52.227-7013.
  19.   Digi International Inc. 6400 Flying Cloud Dr. Eden Prairie, MN 55344
  20.  
  21. #endif
  22. //
  23. // DMODE.C
  24. // A 'mode' that is more forgiving about device names but otherwise
  25. // compatible with the standard OS/2 utility.
  26. //
  27. // assume MSC6.0; 'CL /c /Zp1 /Lp DMODE.C'
  28. //                 link /NOD dmode.obj,,,slibcep OS2,dmode
  29.  
  30. /*
  31.  
  32. V1.4.4  - Changed DTS to DTR so that command line params worked     06-17-93
  33. V1.4.5  - Added support for 230k baud.                  DBU         07-12-94
  34. V1.4.6  - Added support for XON=BOTH to add rx flow control         10-07-94
  35. V1.4.7  - Added support for QW=ON, QW=OFF to permit adjustment of
  36.       quick write mode.                                         11/18/94
  37.  
  38. */
  39.  
  40. #define VERSION "V1.4.7"
  41. #define INCL_BASE
  42. #define INCL_DOSDEVICES 1
  43. #include <os2def.h>
  44. #include <bsedos.h>
  45. #include <bsedev.h>
  46. #include <stdio.h>
  47.  
  48. #include <string.h>
  49. #include <ctype.h>
  50.  
  51. #define NDCBS   7
  52. #define NBAUDS  21
  53. #define DAW_CHR         0x8000   // 1=char, 0=block
  54. #define DAW_IOCTL2      0x0100   // 1=IOCtl2 supported
  55. #define DAW_GIO         0x0040   // 1=generic IOCtl supported
  56.  
  57. #define IOCTL_CATEGORY_DIGI     0xd1
  58.  
  59. #define DIGI_ALTPIN             0x07
  60. #define ALTPIN_DUMMY            0x00
  61. #define ALTPIN_ENABLE           0x01
  62. #define ALTPIN_DISABLE          0x02
  63. unsigned  Alt;
  64.  
  65. #define SPACE   ' '
  66. #define COLON   ':'
  67. #define COMMA   ','
  68. #define EQUAL   '='
  69.  
  70. #define ERR_DEVICE_NAME 1
  71. #define ERR_SYNTAX      2
  72.  
  73. struct {
  74.     long    cur_rate;
  75.     char    cur_fraction;
  76.     long    min_rate;
  77.     char    min_fraction;
  78.     long    max_rate;
  79.     char    max_fraction;
  80. } XBaud ;
  81. unsigned                Baud;
  82. DCBINFO                 DCB_in, DCB_out;
  83. LINECONTROL     LCNTL_in, LCNTL_out;
  84. long                    Baud_out, New_settings;
  85. char                    Name[9], Argbuff[128], Ioctl2=0;
  86. char                    *Dcbs[] = {
  87.     "TO=OFF",       "TO=ON",                                //0,1
  88.     "XON=OFF",      "XON=ON",                               //2,3
  89.     "IDSR=OFF",     "IDSR=ON",                              //4,5
  90.     "ODSR=OFF",     "ODSR=ON",                              //6,7
  91.     "OCTS=OFF",     "OCTS=ON",                              //8,9
  92.     "RTS=OFF",      "RTS=ON",       "RTS=HS", "RTS=TOG",    //10,11,12,13
  93.     "DTR=OFF",      "DTR=ON",       "DTR=HS",               //14,15,16
  94.     "ALT=ON",       "ALT=OFF",                              //17,18
  95.     "XON=BOTH",     "QW=OFF",       "QW=ON"                 //19,20,21
  96.     };
  97. struct {
  98.     char            *str;
  99.     long            val;
  100. }DBauds[] = {
  101.     { "00", 0L },
  102.     { "50", 50L },
  103.     { "75", 75L },
  104.     { "110", 110L },
  105.     { "13", 134L },
  106.     { "15", 150L },
  107.     { "20", 200L },
  108.     { "30", 300L },
  109.     { "60", 600L },
  110.     { "12", 1200L },
  111.     { "18", 1800L },
  112.     { "24", 2400L },
  113.     { "48", 4800L },
  114.     { "96", 9600L },
  115.     { "19", 19200L },
  116.     { "38", 38400L },
  117.     { "00", 0 },
  118.     { "57", 57600L },
  119.     { "76", 76800L },
  120.     { "115", 115200L },
  121.     { "230", 230000L }
  122. };
  123. char    *Stops[]={"1", "1.5", "2" };
  124. char    *Datas[]={"5","6","7","8" };
  125. char    *Parities[] = { "N", "O","E","M","S" };
  126. char    Stuff[] = "NOEMS0123456789TXIORDA";     // start letter of some arg.
  127.  
  128. main ( argc, argv )
  129. int argc;
  130. char *argv[];
  131. {
  132. int     err, i, j, k;
  133.  
  134. /***
  135. If No arguments or '?', just give a USAGE message
  136. ***/
  137.     if ((argc == 1 ) || (*argv[1] == '?'))
  138.     {
  139.         help (0);
  140.         exit (0);
  141.     }
  142. /***
  143. Copy the args to a local buffer; force to upper case
  144. ***/
  145.     for ( i = 0, j = 1; j <= argc ; j++ )
  146.     {
  147.         for ( k=0 ; (Argbuff[i] = toupper (*(argv[j] + k))); k++,i++ );
  148.         Argbuff[i++] = ' ';             /* make sure args remain separated */
  149.     }
  150. /***
  151. Parses args, verifies device-name, fills in DCB_in,_out,Bauddata stuff _in,_out
  152. ***/
  153.     if ( err = parse () )
  154.     {
  155.         help ( err );
  156.         exit (1);
  157.     }
  158. /***
  159. If no args beyond the device name, simply show current settings.
  160. ***/
  161.     if ( New_settings )
  162.         if ( set_mode () )
  163.             exit (1); 
  164.         else
  165.             printf ("Async. Communications Mode Set.\n"); 
  166.     show_device ();
  167.     exit (0);
  168.     
  169. }
  170.  
  171. parse ( )
  172. {
  173. char    *parg, *tmp, thisone[15] ;
  174. int             i, parsed ;
  175.  
  176. // First argument MUST be valid dev. name, ending with either SPACE,COLON,NULL
  177.     for (   i = 0, parg = Argbuff;
  178.         (*parg != SPACE && *parg != COLON && *parg != ',' && *parg ); 
  179.         Name[i++] = *parg++ 
  180.     );
  181.     Name[i] = '\0';
  182.  
  183.     for ( tmp=++parg; *tmp; tmp++)
  184.         if ( *tmp == ',')
  185.             *tmp = ' ';
  186.  
  187. // Verify openability, and that it is a device, not a disk file
  188.     if ( chk_name ()  < 0 )
  189.         return ( ERR_DEVICE_NAME );
  190.  
  191. // parse out any remaining arguments.
  192.  
  193.     for ( strpbrk(parg,Stuff); parg; parg=strpbrk(++parg," ,") )
  194.     {
  195.         if (sscanf(parg, "%s", thisone)==0 || strpbrk(thisone,Stuff)==NULL)
  196.             break;
  197.         parsed = 0;
  198. // Baudrate
  199.         for (i=0; i < NBAUDS; i++)
  200.             if (! strncmp (thisone, DBauds[i].str, strlen(DBauds[i].str) ) )
  201.             {
  202.                 Baud_out = DBauds[i].val;
  203.                 if ( XBaud.max_rate )
  204.                     if ( XBaud.max_rate < Baud_out )
  205.                     {
  206.                         printf ("Maximimum Baud for this device= %ld\n",
  207.                                 XBaud.max_rate );
  208.                         return (-1);
  209.                     }
  210.                 parsed = New_settings = 1;
  211.                 break;
  212.             }
  213.         if (parsed)
  214.             continue;
  215.  
  216. // Parity
  217.         for (i=0; i < 5; i++)
  218.             if (! strcmp (thisone, Parities[i]) )
  219.             {
  220.                 LCNTL_out.bParity = i;
  221.                 parsed = New_settings = 1;
  222.                 break;
  223.             }
  224.         if (parsed)
  225.             continue;
  226. // Databits
  227.         for (i=0; i < 5; i++)
  228.             if (! strcmp (thisone, Datas[i]) )
  229.             {
  230.                 LCNTL_out.bDataBits = i+5;
  231.                 parsed = New_settings = 1;
  232.                 break;
  233.             }
  234.         if (parsed)
  235.             continue;
  236. // Stopbit
  237.         for (i=0; i < 3; i++)
  238.             if (! strcmp (thisone, Stops[i]) )
  239.             {
  240.                 LCNTL_out.bStopBits = i;
  241.                 parsed = New_settings = 1;
  242.                 break;
  243.             }
  244.         if (parsed)
  245.             continue;
  246. // the verbose text
  247.         for (i=0; i < 22; i++)
  248.             if (! strcmp (thisone, Dcbs[i]) )
  249.                 break;
  250.         if ( i > 21 )
  251.         {
  252.             printf ("unkown argument <%s>\n", parg );
  253.             return (-1);
  254.         }
  255.         parsed = New_settings = 1;
  256.         switch ( i )
  257.         {
  258.             case 0 :
  259.                 DCB_out.fbTimeout &= ~MODE_NO_WRITE_TIMEOUT;
  260.                 break;
  261.             case 1 :
  262.                 DCB_out.fbTimeout |= MODE_NO_WRITE_TIMEOUT;
  263.                 break;
  264.             case 2 :
  265.                 DCB_out.fbFlowReplace &= ~(MODE_AUTO_TRANSMIT|MODE_AUTO_RECEIVE);
  266.                 break;
  267.             case 3 :
  268.                 DCB_out.fbFlowReplace &= ~(MODE_AUTO_RECEIVE);
  269.                 DCB_out.fbFlowReplace |= MODE_AUTO_TRANSMIT;
  270.                 break;
  271.             case 4 :
  272.                 DCB_out.fbCtlHndShake &= ~MODE_DSR_SENSITIVITY;
  273.                 break;
  274.             case 5 :
  275.                 DCB_out.fbCtlHndShake |= MODE_DSR_SENSITIVITY;
  276.                 break;
  277.             case 6 :
  278.                 DCB_out.fbCtlHndShake &= ~MODE_DSR_HANDSHAKE;
  279.                 break;
  280.             case 7 :
  281.                 DCB_out.fbCtlHndShake |= MODE_DSR_HANDSHAKE;
  282.                 break;
  283.             case 8 :
  284.                 DCB_out.fbCtlHndShake &= ~MODE_CTS_HANDSHAKE;
  285.                 break;
  286.             case 9 :
  287.                 DCB_out.fbCtlHndShake |= MODE_CTS_HANDSHAKE;
  288.                 break;
  289.             case 10 :
  290.                 DCB_out.fbFlowReplace &= ~MODE_TRANSMIT_TOGGLE;
  291.                 break;
  292.             case 11 :
  293.                 DCB_out.fbFlowReplace &= ~MODE_TRANSMIT_TOGGLE;
  294.                 DCB_out.fbFlowReplace |= MODE_RTS_CONTROL;
  295.                 break;
  296.             case 12 :
  297.                 DCB_out.fbFlowReplace &= ~MODE_TRANSMIT_TOGGLE;
  298.                 DCB_out.fbFlowReplace |= MODE_RTS_HANDSHAKE;
  299.                 break;
  300.             case 13 :
  301.                 DCB_out.fbFlowReplace |= MODE_TRANSMIT_TOGGLE;
  302.                 break;
  303.             case 14 :
  304.                 DCB_out.fbCtlHndShake &= ~(MODE_DTR_CONTROL|MODE_DTR_HANDSHAKE);
  305.                 break;
  306.             case 15 :
  307.                 DCB_out.fbCtlHndShake &= ~(MODE_DTR_CONTROL|MODE_DTR_HANDSHAKE);
  308.                 DCB_out.fbCtlHndShake |= MODE_DTR_CONTROL;
  309.                 break;
  310.             case 16 :
  311.                 DCB_out.fbCtlHndShake &= ~(MODE_DTR_CONTROL|MODE_DTR_HANDSHAKE);
  312.                 DCB_out.fbCtlHndShake |= MODE_DTR_HANDSHAKE;
  313.                 break;
  314.             case 17 :
  315.                 Alt = (Alt & 0x10) | 0x01;
  316.                 break;
  317.             case 18 :
  318.                 Alt = (Alt & 0x10) | 0x02;
  319.                 break;
  320.             case 19 :
  321.                 DCB_out.fbFlowReplace |= (MODE_AUTO_TRANSMIT|MODE_AUTO_RECEIVE);
  322.                 break;
  323.             case 20 :
  324.         Alt &= 0xef;      // no quick writes
  325.         break;
  326.             case 21 :
  327.         Alt |= 0x10;      // quick writes
  328.         break;
  329.             default:
  330.                 parsed = 0;
  331.                 printf ("unkown argument <%s>\n", parg );
  332.                 return (-1);
  333.         }
  334.     }
  335.     return (0);
  336. }
  337.  
  338.  
  339. /*
  340.  * CHK_NAME
  341.  * Verify device name.  In so doing, get the DCB_in and all other _in values.
  342.  * Return:
  343.  *              0 if IS device, and IS openable for R/W and allows IOCTL
  344.  *              -1 otherwise.
  345.  */
  346. chk_name ( )
  347. {
  348. HFILE           handle;
  349. USHORT          result, type, attrib;
  350.  
  351.     if ( DosOpen (  Name,
  352.             &handle,
  353.             &result,
  354.             100L,
  355.             FILE_NORMAL,
  356.             FILE_OPEN,
  357.             (OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE),
  358.             0L ) )
  359.     {
  360.         printf ("Failed to open Device <%s>\n", Name);
  361.         return -1;
  362.     }
  363.     if ( DosQHandType (handle, &type, &attrib ) )
  364.     {
  365.         printf ("System call <DosQHandType> failed on device <%s>!\n", Name);
  366.         return -1;
  367.     }
  368.     if ( (type & HANDTYPE_DEVICE) == 0 )    /** verify non-file device **/
  369.     {
  370.         printf ("<%s> is not a DEVICE!\n", Name);
  371.         return -1;
  372.     }
  373.     if ( ( attrib & DAW_CHR ) == 0 )        /** verify CHARACTER device **/
  374.     {
  375.         printf ("<%s> is not a CHARACTER DEVICE!\n", Name);
  376.         return -1;
  377.     }
  378.     if ( ( attrib & DAW_GIO ) == 0 )        /** verify Generic IOCTL Ok **/
  379.     {
  380.         printf ("<%s> does not accept GENERIC IOCtl DEVICE calls !\n", Name);
  381.         return -1;
  382.     }
  383.     if ( attrib & DAW_IOCTL2 )
  384.         Ioctl2 = 1;
  385.  
  386.     if ( Ioctl2 )
  387.     {
  388.         if (DosDevIOCtl2(&XBaud,sizeof(XBaud),0L,0,0x63,IOCTL_ASYNC,handle))
  389.         {
  390.             printf ("<%s> failed IOCtl <ASYNC_GETXBAUDRATE>\n", Name);
  391.             return -1;
  392.         }
  393.         Baud_out = XBaud.cur_rate;
  394.     printf ("Maximimum Baud for this device= %ld\n", XBaud.max_rate );
  395.     }
  396.     else
  397.     {
  398.         if ( DosDevIOCtl (&Baud,0L,ASYNC_GETBAUDRATE,IOCTL_ASYNC,handle ) )
  399.         {
  400.             printf ("<%s> failed IOCtl <ASYNC_GETBAUDRATE>\n", Name);
  401.             return -1;
  402.         }
  403.         Baud_out = Baud;
  404.     }
  405.  
  406.  
  407.     if ( DosDevIOCtl (&DCB_in,0L,ASYNC_GETDCBINFO,IOCTL_ASYNC,handle ) )
  408.     {
  409.         printf ("<%s> failed IOCtl <ASYNC_GETDCBINFO>\n", Name);
  410.         return -1;
  411.     }
  412.     DCB_out = DCB_in;
  413.     if ( DosDevIOCtl (&LCNTL_in,0L,ASYNC_GETLINECTRL,IOCTL_ASYNC,handle ) )
  414.     {
  415.         printf ("<%s> failed IOCtl <ASYNC_GETLINECTRL>\n", Name);
  416.         return -1;
  417.     }
  418.     LCNTL_out = LCNTL_in;
  419.  
  420.     Alt = 0;                    // causes return of current alt-pin setting
  421.     if  (DosDevIOCtl(&Alt,&Alt,DIGI_ALTPIN,IOCTL_CATEGORY_DIGI,handle))
  422.         Alt = 0;
  423.  
  424.     DosClose ( handle );
  425.  
  426.     return 0;
  427. }
  428.  
  429. help (flag)
  430. {
  431.     printf (
  432. "DMODE %s.  DigiBoard OS/2 asynchronous serial device configuration utility.\n\n",
  433.     VERSION);
  434.     printf ("Usage:\n\
  435. DMODE devname[:]baud[,parity,databits,stopbits][,TO=state][,XON=state]\n\
  436.      [,IDSR=state][,ODSR=state][,OCTS=state][,DTR=dtrstate][,RTS=rtsstate]\
  437.      \n");
  438.     printf ("Aditional DigiCHANNEL options: ..[,ALT=state][,QW=state]\n\n");
  439. }
  440.  
  441. show_device()
  442. {
  443. char    string[128];
  444.  
  445.     sprintf ( string, "%s %ld %s,%d,%s ", Name, Baud_out,
  446.         Parities [LCNTL_out.bParity],
  447.         LCNTL_out.bDataBits, 
  448.         Stops[LCNTL_out.bStopBits] );
  449.  
  450.     if ( DCB_out.fbTimeout & MODE_NO_WRITE_TIMEOUT )
  451.         strcat (string, "TO=ON," );
  452.     else
  453.         strcat (string, "TO=OFF," );
  454.  
  455.     if ( DCB_out.fbFlowReplace & MODE_AUTO_TRANSMIT )
  456.     if ( DCB_out.fbFlowReplace & MODE_AUTO_RECEIVE )
  457.         strcat (string, "XON=BOTH," );
  458.     else
  459.         strcat (string, "XON=ON," );
  460.     else
  461.         strcat (string, "XON=OFF," );
  462.  
  463.  
  464.     #if 0
  465.     if ( DCB_out.fbFlowReplace & MODE_AUTO_TRANSMIT )
  466.         strcat (string, "XON=ON," );
  467.     else
  468.         strcat (string, "XON=OFF," );
  469.     #endif
  470.  
  471.  
  472.     if ( DCB_out.fbCtlHndShake & MODE_DSR_SENSITIVITY )
  473.         strcat (string, "IDSR=ON," );
  474.     else
  475.         strcat (string, "IDSR=OFF," );
  476.  
  477.     if ( DCB_out.fbCtlHndShake & MODE_DSR_HANDSHAKE )
  478.         strcat (string, "ODSR=ON," );
  479.     else
  480.         strcat (string, "ODSR=OFF," );
  481.  
  482.     if ( DCB_out.fbCtlHndShake & MODE_CTS_HANDSHAKE )
  483.         strcat (string, "OCTS=ON," );
  484.     else
  485.         strcat (string, "OCTS=OFF," );
  486.  
  487.     if ((DCB_out.fbFlowReplace & MODE_TRANSMIT_TOGGLE) == MODE_TRANSMIT_TOGGLE)
  488.         strcat (string, "RTS=TOG," );
  489.     else if ((DCB_out.fbFlowReplace&MODE_TRANSMIT_TOGGLE) == MODE_RTS_HANDSHAKE)
  490.         strcat (string, "RTS=HS," );
  491.     else if ((DCB_out.fbFlowReplace&MODE_TRANSMIT_TOGGLE) == MODE_RTS_CONTROL)
  492.         strcat (string, "RTS=ON," );
  493.     else
  494.         strcat (string, "RTS=OFF," );
  495.  
  496.     if ( DCB_out.fbCtlHndShake & MODE_DTR_CONTROL )
  497.         strcat (string, "DTR=ON" );
  498.     else if ( DCB_out.fbCtlHndShake & MODE_DTR_HANDSHAKE )
  499.         strcat (string, "DTR=HS" );
  500.     else
  501.         strcat (string, "DTR=OFF" );
  502.  
  503.     if ( Alt )
  504.     {
  505.         if ( Alt & 0x1 )
  506.             strcat (string, ", ALT=ON" );
  507.         else
  508.             strcat (string, ", ALT=OFF" );
  509.  
  510.         if ( Alt & 0x10 )
  511.             strcat (string, ", QW=ON" );
  512.         else
  513.             strcat (string, ", QW=OFF" );
  514.  
  515.     }
  516.  
  517.     printf ("%s\n", string);
  518.     return 0;
  519.  
  520. }
  521.  
  522.  
  523. set_mode ()
  524. {
  525. HFILE   handle;
  526. USHORT  result, type, attrib;
  527.  
  528.     if ( DosOpen (  Name,
  529.             &handle,
  530.             &result,
  531.             100L,
  532.             FILE_NORMAL,
  533.             FILE_OPEN,
  534.             (OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE),
  535.             0L ) )
  536.         return -1;
  537.  
  538.     if ( Ioctl2 )
  539.     {
  540.         if (DosDevIOCtl2(0L,0,&Baud_out,4,0x43,IOCTL_ASYNC,handle))
  541.         {
  542.             printf ("Failed to <ASYNC_SETXBAUDRATE>\n");
  543.             return -1;
  544.         }
  545.     }
  546.     else
  547.     {
  548.         if ( DosDevIOCtl (0L,&Baud_out,ASYNC_SETBAUDRATE,IOCTL_ASYNC,handle ) )
  549.         {
  550.             printf ("Failed to <ASYNC_SETBAUDRATE>\n");
  551.             return -1;
  552.         }
  553.     }
  554.     if ( DosDevIOCtl (0L,&LCNTL_out,ASYNC_SETLINECTRL,IOCTL_ASYNC,handle ) )
  555.     {
  556.         printf ("Failed to <ASYNC_SETLINECTRL>\n");
  557.         return -1;
  558.     }
  559.     if ( DosDevIOCtl (0L,&DCB_out,ASYNC_SETDCBINFO,IOCTL_ASYNC,handle ) )
  560.     {
  561.         printf ("Failed to <ASYNC_SETDCBINFO>\n");
  562.         return -1;
  563.     }
  564.     if ( Alt )
  565.         if  (DosDevIOCtl(&Alt,&Alt,DIGI_ALTPIN,IOCTL_CATEGORY_DIGI,handle))
  566.     {
  567.         printf ("Failed to <DIGI_ALTPIN>\n");
  568.         return -1;
  569.     }
  570.  
  571.     DosClose ( handle );
  572.  
  573.     return 0;
  574. }
  575.