static char CRevInfo[] = "@(#) $Header: c:/os2drv/xall/RCS/dmode.c 1.14 1993/06/17 00:04:10 dave Exp $"; #ifdef COPYRIGHT_NOTICE (c) Copyright 1990-1993 Digi International Inc. ALl Rights Reserved. This software contains proprietary and confidential information of Digi International, Inc. By accepting transfer of this copy, recipient agrees to retain this software in confidence, to prevent disclosure to others, and to make no use of this software other than that for which it was delivered. This is an unpublished copyrighted work of Digi International Inc. Except as permitted by federal law, 17 USC 117, copying is strictly prohibited. Use, duplication, or disclosure by the Government is subject to restrictions set forth in sub-paragraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause of FDARS 52.227-7013. Digi International Inc. 6400 Flying Cloud Dr. Eden Prairie, MN 55344 #endif // // DMODE.C // A 'mode' that is more forgiving about device names but otherwise // compatible with the standard OS/2 utility. // // assume MSC6.0; 'CL /Zp1 /Lp DMODE.C' // /* V1.4.4 - Changed DTS to DTR so that command line params worked 06-17-93 */ #define VERSION "V1.4.4" #define INCL_BASE #define INCL_DOSDEVICES 1 #include #include #include #include #include #include #define NDCBS 7 #define NBAUDS 20 #define DAW_CHR 0x8000 // 1=char, 0=block #define DAW_IOCTL2 0x0100 // 1=IOCtl2 supported #define DAW_GIO 0x0040 // 1=generic IOCtl supported #define IOCTL_CATEGORY_DIGI 0xd1 #define DIGI_ALTPIN 0x07 #define ALTPIN_DUMMY 0x00 #define ALTPIN_ENABLE 0x01 #define ALTPIN_DISABLE 0x02 unsigned Alt; #define SPACE ' ' #define COLON ':' #define COMMA ',' #define EQUAL '=' #define ERR_DEVICE_NAME 1 #define ERR_SYNTAX 2 struct { long cur_rate; char cur_fraction; long min_rate; char min_fraction; long max_rate; char max_fraction; } XBaud ; unsigned Baud; DCBINFO DCB_in, DCB_out; LINECONTROL LCNTL_in, LCNTL_out; long Baud_out, New_settings; char Name[9], Argbuff[128], Ioctl2=0; char *Dcbs[] = { "TO=OFF", "TO=ON", //0,1 "XON=OFF", "XON=ON", //2,3 "IDSR=OFF", "IDSR=ON", //4,5 "ODSR=OFF", "ODSR=ON", //6,7 "OCTS=OFF", "OCTS=ON", //8,9 "RTS=OFF", "RTS=ON", "RTS=HS", "RTS=TOG", //10,11,12,13 "DTR=OFF", "DTR=ON", "DTR=HS", //14,15,16 "ALT=ON", "ALT=OFF" //17,18 }; struct { char *str; long val; }DBauds[] = { { "00", 0L }, { "50", 50L }, { "75", 75L }, { "110", 110L }, { "13", 134L }, { "15", 150L }, { "20", 200L }, { "30", 300L }, { "60", 600L }, { "12", 1200L }, { "18", 1800L }, { "24", 2400L }, { "48", 4800L }, { "96", 9600L }, { "19", 19200L }, { "38", 38400L }, { "00", 0 }, { "57", 57600L }, { "76", 76800L }, { "115", 115200L } }; char *Stops[]={"1", "1.5", "2" }; char *Datas[]={"5","6","7","8" }; char *Parities[] = { "N", "O","E","M","S" }; char Stuff[] = "NOEMS0123456789TXIORDA"; // start letter of some arg. main ( argc, argv ) int argc; char *argv[]; { int err, i, j, k; /*** If No arguments or '?', just give a USAGE message ***/ if ((argc == 1 ) || (*argv[1] == '?')) { help (0); exit (0); } /*** Copy the args to a local buffer; force to upper case ***/ for ( i = 0, j = 1; j <= argc ; j++ ) { for ( k=0 ; (Argbuff[i] = toupper (*(argv[j] + k))); k++,i++ ); Argbuff[i++] = ' '; /* make sure args remain separated */ } /*** Parses args, verifies device-name, fills in DCB_in,_out,Bauddata stuff _in,_out ***/ if ( err = parse () ) { help ( err ); exit (1); } /*** If no args beyond the device name, simply show current settings. ***/ if ( New_settings ) if ( set_mode () ) exit (1); else printf ("Async. Communications Mode Set.\n"); show_device (); exit (0); } parse ( ) { char *parg, *tmp, thisone[15] ; int i, parsed ; // First argument MUST be valid dev. name, ending with either SPACE,COLON,NULL for ( i = 0, parg = Argbuff; (*parg != SPACE && *parg != COLON && *parg != ',' && *parg ); Name[i++] = *parg++ ); Name[i] = '\0'; for ( tmp=++parg; *tmp; tmp++) if ( *tmp == ',') *tmp = ' '; // Verify openability, and that it is a device, not a disk file if ( chk_name () < 0 ) return ( ERR_DEVICE_NAME ); // parse out any remaining arguments. for ( strpbrk(parg,Stuff); parg; parg=strpbrk(++parg," ,") ) { if (sscanf(parg, "%s", thisone)==0 || strpbrk(thisone,Stuff)==NULL) break; parsed = 0; // Baudrate for (i=0; i < NBAUDS; i++) if (! strncmp (thisone, DBauds[i].str, strlen(DBauds[i].str) ) ) { Baud_out = DBauds[i].val; if ( XBaud.max_rate ) if ( XBaud.max_rate < Baud_out ) { printf ("Maximimum Baud for this device= %ld\n", XBaud.max_rate ); return (-1); } parsed = New_settings = 1; break; } if (parsed) continue; // Parity for (i=0; i < 5; i++) if (! strcmp (thisone, Parities[i]) ) { LCNTL_out.bParity = i; parsed = New_settings = 1; break; } if (parsed) continue; // Databits for (i=0; i < 5; i++) if (! strcmp (thisone, Datas[i]) ) { LCNTL_out.bDataBits = i+5; parsed = New_settings = 1; break; } if (parsed) continue; // Stopbit for (i=0; i < 3; i++) if (! strcmp (thisone, Stops[i]) ) { LCNTL_out.bStopBits = i; parsed = New_settings = 1; break; } if (parsed) continue; // the verbose text for (i=0; i < 19; i++) if (! strcmp (thisone, Dcbs[i]) ) break; if ( i > 18 ) { printf ("unkown argument <%s>\n", parg ); return (-1); } parsed = New_settings = 1; switch ( i ) { case 0 : DCB_out.fbTimeout &= ~MODE_NO_WRITE_TIMEOUT; break; case 1 : DCB_out.fbTimeout |= MODE_NO_WRITE_TIMEOUT; break; case 2 : DCB_out.fbFlowReplace &= ~MODE_AUTO_TRANSMIT; break; case 3 : DCB_out.fbFlowReplace |= MODE_AUTO_TRANSMIT; break; case 4 : DCB_out.fbCtlHndShake &= ~MODE_DSR_SENSITIVITY; break; case 5 : DCB_out.fbCtlHndShake |= MODE_DSR_SENSITIVITY; break; case 6 : DCB_out.fbCtlHndShake &= ~MODE_DSR_HANDSHAKE; break; case 7 : DCB_out.fbCtlHndShake |= MODE_DSR_HANDSHAKE; break; case 8 : DCB_out.fbCtlHndShake &= ~MODE_CTS_HANDSHAKE; break; case 9 : DCB_out.fbCtlHndShake |= MODE_CTS_HANDSHAKE; break; case 10 : DCB_out.fbFlowReplace &= ~MODE_TRANSMIT_TOGGLE; break; case 11 : DCB_out.fbFlowReplace &= ~MODE_TRANSMIT_TOGGLE; DCB_out.fbFlowReplace |= MODE_RTS_CONTROL; break; case 12 : DCB_out.fbFlowReplace &= ~MODE_TRANSMIT_TOGGLE; DCB_out.fbFlowReplace |= MODE_RTS_HANDSHAKE; break; case 13 : DCB_out.fbFlowReplace |= MODE_TRANSMIT_TOGGLE; break; case 14 : DCB_out.fbCtlHndShake &= ~(MODE_DTR_CONTROL|MODE_DTR_HANDSHAKE); break; case 15 : DCB_out.fbCtlHndShake &= ~(MODE_DTR_CONTROL|MODE_DTR_HANDSHAKE); DCB_out.fbCtlHndShake |= MODE_DTR_CONTROL; break; case 16 : DCB_out.fbCtlHndShake &= ~(MODE_DTR_CONTROL|MODE_DTR_HANDSHAKE); DCB_out.fbCtlHndShake |= MODE_DTR_HANDSHAKE; break; case 17 : Alt = (Alt & 0x10) | 0x01; break; case 18 : Alt = (Alt & 0x10) | 0x02; break; default: parsed = 0; printf ("unkown argument <%s>\n", parg ); return (-1); } } return (0); } /* * CHK_NAME * Verify device name. In so doing, get the DCB_in and all other _in values. * Return: * 0 if IS device, and IS openable for R/W and allows IOCTL * -1 otherwise. */ chk_name ( ) { HFILE handle; USHORT result, type, attrib; if ( DosOpen ( Name, &handle, &result, 100L, FILE_NORMAL, FILE_OPEN, (OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE), 0L ) ) { printf ("Failed to open Device <%s>\n", Name); return -1; } if ( DosQHandType (handle, &type, &attrib ) ) { printf ("System call failed on device <%s>!\n", Name); return -1; } if ( (type & HANDTYPE_DEVICE) == 0 ) /** verify non-file device **/ { printf ("<%s> is not a DEVICE!\n", Name); return -1; } if ( ( attrib & DAW_CHR ) == 0 ) /** verify CHARACTER device **/ { printf ("<%s> is not a CHARACTER DEVICE!\n", Name); return -1; } if ( ( attrib & DAW_GIO ) == 0 ) /** verify Generic IOCTL Ok **/ { printf ("<%s> does not accept GENERIC IOCtl DEVICE calls !\n", Name); return -1; } if ( attrib & DAW_IOCTL2 ) Ioctl2 = 1; if ( Ioctl2 ) { if (DosDevIOCtl2(&XBaud,sizeof(XBaud),0L,0,0x63,IOCTL_ASYNC,handle)) { printf ("<%s> failed IOCtl \n", Name); return -1; } Baud_out = XBaud.cur_rate; } else { if ( DosDevIOCtl (&Baud,0L,ASYNC_GETBAUDRATE,IOCTL_ASYNC,handle ) ) { printf ("<%s> failed IOCtl \n", Name); return -1; } Baud_out = Baud; } if ( DosDevIOCtl (&DCB_in,0L,ASYNC_GETDCBINFO,IOCTL_ASYNC,handle ) ) { printf ("<%s> failed IOCtl \n", Name); return -1; } DCB_out = DCB_in; if ( DosDevIOCtl (&LCNTL_in,0L,ASYNC_GETLINECTRL,IOCTL_ASYNC,handle ) ) { printf ("<%s> failed IOCtl \n", Name); return -1; } LCNTL_out = LCNTL_in; Alt = 0; if (DosDevIOCtl(&Alt,&Alt,DIGI_ALTPIN,IOCTL_CATEGORY_DIGI,handle)) Alt = 0; DosClose ( handle ); return 0; } help (flag) { printf ( "DMODE %s. DigiBoard OS/2 asynchronous serial device configuration utility.\n\n", VERSION); printf ("Usage:\n\ DMODE devname[:]baud[,parity,databits,stopbits][,TO=state][,XON=state]\n\ [,IDSR=state][,ODSR=state][,OCTS=state][,DTR=dtrstate][,RTS=rtsstate]\ \n"); printf ("Aditional DigiCHANNEL options: ..[,ALT=state]\n\n"); } show_device() { char string[128]; sprintf ( string, "%s %ld %s,%d,%s ", Name, Baud_out, Parities [LCNTL_out.bParity], LCNTL_out.bDataBits, Stops[LCNTL_out.bStopBits] ); if ( DCB_out.fbTimeout & MODE_NO_WRITE_TIMEOUT ) strcat (string, "TO=ON," ); else strcat (string, "TO=OFF," ); if ( DCB_out.fbFlowReplace & MODE_AUTO_TRANSMIT ) strcat (string, "XON=ON," ); else strcat (string, "XON=OFF," ); if ( DCB_out.fbCtlHndShake & MODE_DSR_SENSITIVITY ) strcat (string, "IDSR=ON," ); else strcat (string, "IDSR=OFF," ); if ( DCB_out.fbCtlHndShake & MODE_DSR_HANDSHAKE ) strcat (string, "ODSR=ON," ); else strcat (string, "ODSR=OFF," ); if ( DCB_out.fbCtlHndShake & MODE_CTS_HANDSHAKE ) strcat (string, "OCTS=ON," ); else strcat (string, "OCTS=OFF," ); if ((DCB_out.fbFlowReplace & MODE_TRANSMIT_TOGGLE) == MODE_TRANSMIT_TOGGLE) strcat (string, "RTS=TOG," ); else if ((DCB_out.fbFlowReplace&MODE_TRANSMIT_TOGGLE) == MODE_RTS_HANDSHAKE) strcat (string, "RTS=HS," ); else if ((DCB_out.fbFlowReplace&MODE_TRANSMIT_TOGGLE) == MODE_RTS_CONTROL) strcat (string, "RTS=ON," ); else strcat (string, "RTS=OFF," ); if ( DCB_out.fbCtlHndShake & MODE_DTR_CONTROL ) strcat (string, "DTR=ON" ); else if ( DCB_out.fbCtlHndShake & MODE_DTR_HANDSHAKE ) strcat (string, "DTR=HS" ); else strcat (string, "DTR=OFF" ); if ( Alt ) if ( Alt & 0x1 ) strcat (string, ", ALT=ON" ); else strcat (string, ", ALT=OFF" ); printf ("%s\n", string); return 0; } set_mode () { HFILE handle; USHORT result, type, attrib; if ( DosOpen ( Name, &handle, &result, 100L, FILE_NORMAL, FILE_OPEN, (OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE), 0L ) ) return -1; if ( Ioctl2 ) { if (DosDevIOCtl2(0L,0,&Baud_out,4,0x43,IOCTL_ASYNC,handle)) { printf ("Failed to \n"); return -1; } } else { if ( DosDevIOCtl (0L,&Baud_out,ASYNC_SETBAUDRATE,IOCTL_ASYNC,handle ) ) { printf ("Failed to \n"); return -1; } } if ( DosDevIOCtl (0L,&LCNTL_out,ASYNC_SETLINECTRL,IOCTL_ASYNC,handle ) ) { printf ("Failed to \n"); return -1; } if ( DosDevIOCtl (0L,&DCB_out,ASYNC_SETDCBINFO,IOCTL_ASYNC,handle ) ) { printf ("Failed to \n"); return -1; } if ( Alt ) if (DosDevIOCtl(&Alt,&Alt,DIGI_ALTPIN,IOCTL_CATEGORY_DIGI,handle)) { printf ("Failed to \n"); return -1; } DosClose ( handle ); return 0; }