/* * Channel configuration utility for Cronyx serial adapters. * * Copyright (C) 1997-2002 Cronyx Engineering. * Author: Serge Vakulenko, * * Copyright (C) 1999-2005 Cronyx Engineering. * Author: Roman Kurakin, * * This software is distributed with NO WARRANTIES, not even the implied * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Authors grant any other persons or organisations permission to use * or modify this software as long as this message is kept with the software, * all derivative works or modified versions. * * Cronyx Id: sconfig.c,v 1.4.2.2 2005/11/09 13:01:35 rik Exp $ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAXCHAN 128 int vflag, eflag, sflag, mflag, cflag, fflag, iflag, aflag, xflag; int tflag, uflag; char mask[64]; int adapter_type; /* 0-sigma, 1-tau, 2-taupci, 3-tau32 */ char chan_name[16]; static void usage (void) { printf( "Serial Adapter Configuration Utility\n" "Copyright (C) 1998-2005 Cronyx Engineering.\n" "See also man sconfig (8)\n" "Usage:\n" "\tsconfig [-aimsxeftuc] [device [parameters ...]]\n" "\n" "Options:\n" "\t\t\t -- print channel options\n" "\t-a\t\t\t -- print all settings of the channel\n" "\t-i\t\t\t -- print network interface status\n" "\t-m\t\t\t -- print modem signal status\n" "\t-s\t\t\t -- print channel statistics\n" "\t-x\t\t\t -- print extended channel statistics\n" "\t-e\t\t\t -- print short E1/G703 statistics\n" "\t-f\t\t\t -- print full E1/G703 statistics\n" "\t-t\t\t\t -- print short E3/T3/STS-1 statistics\n" "\t-u\t\t\t -- print full E3/T3/STS-1 statistics\n" "\t-c\t\t\t -- clear statistics\n" "\nParameters:\n" "\t\t\t -- baud rate, internal clock\n" "\textclock\t\t -- external clock (default)\n" "\nProtocol options:\n" "\tasync\t\t\t -- asynchronous protocol\n" #ifdef __linux__ "\tsync\t\t\t -- synchronous protocol\n" #endif "\tcisco\t\t\t -- Cisco/HDLC protocol\n" "\tfr\t\t\t -- Frame Relay protocol\n" #ifdef __linux__ "\t dlci\t -- Add new DLCI\n" #endif "\tppp\t\t\t -- PPP protocol\n" #ifdef __linux__ "\trbrg\t\t\t -- Remote bridge\n" "\traw\t\t\t -- raw HDLC protocol\n" "\tpacket\t\t\t -- packetized HDLC protocol\n" "\tidle\t\t\t -- no protocol\n" #else "\t keepalive={on,of}\t -- Enable/disable keepalive\n" #endif "\nInterface options:\n" "\tport={rs232,v35,rs449}\t -- port type (for old models of Sigma)\n" "\tcfg={A,B,C}\t\t -- adapter configuration\n" "\tloop={on,off}\t\t -- internal loopback\n" "\trloop={on,off}\t\t -- remote loopback\n" "\tdpll={on,off}\t\t -- DPLL mode\n" "\tnrzi={on,off}\t\t -- NRZI encoding\n" "\tinvclk={on,off}\t\t -- invert receive and transmit clock\n" "\tinvrclk={on,off}\t -- invert receive clock\n" "\tinvtclk={on,off}\t -- invert transmit clock\n" "\thigain={on,off}\t\t -- E1 high non linear input sensitivity \n\t\t\t\t (long line)\n" "\tmonitor={on,off}\t -- E1 high linear input sensitivity \n\t\t\t\t (interception mode)\n" "\tphony={on,off}\t\t -- E1 telepnony mode\n" "\tunfram={on,off}\t\t -- E1 unframed mode\n" "\tscrambler={on,off}\t -- G.703 scrambling mode\n" "\tuse16={on,off}\t\t -- E1 timeslot 16 usage\n" "\tcrc4={on,off}\t\t -- E1 CRC4 mode\n" #ifdef __linux__ "\tami={on,off}\t\t -- E1 AMI or HDB3 line code\n" "\tmtu={size}\t\t -- set MTU in bytes\n" #endif "\tsyn={int,rcv,rcvX}\t -- G.703 transmit clock\n" "\tts=...\t\t\t -- E1 timeslots\n" "\tpass=...\t\t -- E1 subchannel timeslots\n" "\tdir=\t\t -- connect channel to link\n" /*"\trqken={size}\t\t -- set receive queue length in packets\n"*/ /*"\tcablen={on,off}\t\t -- T3/STS-1 high transmitter output for long cable\n"*/ "\tdebug={0,1,2}\t\t -- enable/disable debug messages\n" ); exit (0); } static unsigned long scan_timeslots (char *s) { char *e; long v; int i; unsigned long ts, lastv; ts = lastv = 0; for (;;) { v = strtol (s, &e, 10); if (e == s) break; if (*e == '-') { lastv = v; s = e+1; continue; } if (*e == ',') ++e; if (lastv) for (i=lastv; i= 0) { /* Ok. */ close (s); return 1; } close (s); /* open pseudo-tty and try to set PPP discipline */ sprintf (pttyname, "/dev/ptyXX"); p1 = &pttyname[8]; p2 = &pttyname[9]; for (i=0; i<16; i++) { struct stat stb; *p1 = "pqrstuvwxyzabcde"[i]; *p2 = '0'; if (stat (pttyname, &stb) < 0) continue; for (j=0; j<16; j++) { *p2 = "0123456789abcdef"[j]; p = open (pttyname, 2); if (p > 0) { if (ioctl (p, TIOCSETD, &ppp_disc) < 0) { fprintf (stderr, "No PPP discipline in kernel.\n"); close (p); return 0; } close (p); return 1; } } } fprintf (stderr, "Cannot get pseudo-tty.\n"); return 0; #else return 1; #endif } static char * format_timeslots (unsigned long s) { static char buf [100]; char *p = buf; int i; for (i=1; i<32; ++i) if ((s >> i) & 1) { int prev = (i > 1) & (s >> (i-1)); int next = (i < 31) & (s >> (i+1)); if (prev) { if (next) continue; *p++ = '-'; } else if (p > buf) *p++ = ','; if (i >= 10) *p++ = '0' + i / 10; *p++ = '0' + i % 10; } *p = 0; return buf; } static void print_modems (int fd, int need_header) { int status; if (ioctl (fd, TIOCMGET, &status) < 0) { perror ("getting modem status"); return; } if (need_header) printf ("Channel\tLE\tDTR\tDSR\tRTS\tCTS\tCD\n"); printf ("%s\t%s\t%s\t%s\t%s\t%s\t%s\n", chan_name, status & TIOCM_LE ? "On" : "-", status & TIOCM_DTR ? "On" : "-", status & TIOCM_DSR ? "On" : "-", status & TIOCM_RTS ? "On" : "-", status & TIOCM_CTS ? "On" : "-", status & TIOCM_CD ? "On" : "-"); } static void #ifdef __linux__ print_ifconfig (int fd) #else print_ifconfig (int fd __unused) #endif { char buf [64]; #ifdef __linux__ char protocol [8]; if (ioctl (fd, SERIAL_GETPROTO, &protocol) >= 0 && strcmp (protocol, "fr") == 0) sprintf (buf, "ifconfig %sd16 2>/dev/null", chan_name); else #endif sprintf (buf, "ifconfig %s 2>/dev/null", chan_name); system (buf); } static void set_debug_ifconfig (int on) { char buf [64]; sprintf (buf, "ifconfig %s %sdebug 2>/dev/null", chan_name, on ? "" : "-"); system (buf); } static char * format_long (unsigned long val) { static char s[32]; int l; l = sprintf (s, "%lu", val); if (l>7 && !sflag) { s[3] = s[2]; s[2] = s[1]; s[1] = '.'; s[4] = 'e'; sprintf (s + 5, "%02d", l-1); } return s; } static void print_stats (int fd, int need_header) { struct serial_statistics st; unsigned long sarr [9]; int i; if (ioctl (fd, SERIAL_GETSTAT, &st) < 0) { perror ("getting statistics"); return; } if (need_header) { if (sflag) { printf (" ------------Receive----------- " "------------Transmit----------\n"); printf ("Channel Interrupts Packets Errors " "Interrupts Packets Errors\n"); } else { printf (" --------Receive--------------- " "--------Transmit-------------- Modem\n"); printf ("Channel Intrs Bytes Packets Errors " "Intrs Bytes Packets Errors Intrs\n"); } } sarr [0] = st.rintr; sarr [1] = st.ibytes; sarr [2] = st.ipkts; sarr [3] = st.ierrs; sarr [4] = st.tintr; sarr [5] = st.obytes; sarr [6] = st.opkts; sarr [7] = st.oerrs; sarr [8] = st.mintr; printf ("%s", chan_name); if (sflag) { printf ("\t%-12lu%-12lu%-12lu%-12lu%-12lu%-12lu", sarr[0], sarr[2], sarr[3], sarr[4], sarr[6], sarr[7]); } else { for (i = 0; i < 9; i++) printf ("\t%s", format_long (sarr [i])); printf ("\n"); } } static void clear_stats (int fd) { if (ioctl (fd, SERIAL_CLRSTAT, 0) < 0) { perror ("clearing statistics"); exit (-1); } } static char * format_e1_status (unsigned long status) { static char buf [80]; if (status == 0) return "n/a"; if (status & E1_NOALARM) return "Ok"; buf[0] = 0; if (status & E1_LOS) strcat (buf, ",LOS"); if (status & E1_AIS) strcat (buf, ",AIS"); if (status & E1_LOF) strcat (buf, ",LOF"); if (status & E1_LOMF) strcat (buf, ",LOMF"); if (status & E1_CRC4E) strcat (buf, ",CRC4E"); if (status & E1_FARLOF) strcat (buf, ",FARLOF"); if (status & E1_AIS16) strcat (buf, ",AIS16"); if (status & E1_FARLOMF) strcat (buf, ",FARLOMF"); /* if (status & E1_TSTREQ) strcat (buf, ",TSTREQ");*/ /* if (status & E1_TSTERR) strcat (buf, ",TSTERR");*/ if (buf[0] == ',') return buf+1; return "Unknown"; } static void print_frac (int leftalign, unsigned long numerator, unsigned long divider) { int n; if (numerator < 1 || divider < 1) { printf (leftalign ? "/- " : " -"); return; } n = (int) (0.5 + 1000.0 * numerator / divider); if (n < 1000) { printf (leftalign ? "/.%-3d" : " .%03d", n); return; } putchar (leftalign ? '/' : ' '); if (n >= 1000000) n = (n+500) / 1000 * 1000; else if (n >= 100000) n = (n+50) / 100 * 100; else if (n >= 10000) n = (n+5) / 10 * 10; switch (n) { case 1000: printf (".999"); return; case 10000: n = 9990; break; case 100000: n = 99900; break; case 1000000: n = 999000; break; } if (n < 10000) printf ("%d.%d", n/1000, n/10%100); else if (n < 100000) printf ("%d.%d", n/1000, n/100%10); else if (n < 1000000) printf ("%d.", n/1000); else printf ("%d", n/1000); } static void print_e1_stats (int fd, int need_header) { struct e1_statistics st; int i, maxi; if (need_header) printf ("Chan\t Unav/Degr Bpv/Fsyn CRC/RCRC Err/Lerr Sev/Bur Oof/Slp Status\n"); if (ioctl (fd, SERIAL_GETESTAT, &st) < 0) return; printf ("%s\t", chan_name); /* Unavailable seconds, degraded minutes */ print_frac (0, st.currnt.uas, st.cursec); print_frac (1, 60 * st.currnt.dm, st.cursec); /* Bipolar violations, frame sync errors */ print_frac (0, st.currnt.bpv, st.cursec); print_frac (1, st.currnt.fse, st.cursec); /* CRC errors, remote CRC errors (E-bit) */ print_frac (0, st.currnt.crce, st.cursec); print_frac (1, st.currnt.rcrce, st.cursec); /* Errored seconds, line errored seconds */ print_frac (0, st.currnt.es, st.cursec); print_frac (1, st.currnt.les, st.cursec); /* Severely errored seconds, bursty errored seconds */ print_frac (0, st.currnt.ses, st.cursec); print_frac (1, st.currnt.bes, st.cursec); /* Out of frame seconds, controlled slip seconds */ print_frac (0, st.currnt.oofs, st.cursec); print_frac (1, st.currnt.css, st.cursec); printf (" %s\n", format_e1_status (st.status)); if (fflag) { /* Print total statistics. */ printf ("\t"); print_frac (0, st.total.uas, st.totsec); print_frac (1, 60 * st.total.dm, st.totsec); print_frac (0, st.total.bpv, st.totsec); print_frac (1, st.total.fse, st.totsec); print_frac (0, st.total.crce, st.totsec); print_frac (1, st.total.rcrce, st.totsec); print_frac (0, st.total.es, st.totsec); print_frac (1, st.total.les, st.totsec); print_frac (0, st.total.ses, st.totsec); print_frac (1, st.total.bes, st.totsec); print_frac (0, st.total.oofs, st.totsec); print_frac (1, st.total.css, st.totsec); printf (" -- Total\n"); /* Print 24-hour history. */ maxi = (st.totsec - st.cursec) / 900; if (maxi > 48) maxi = 48; for (i=0; i 48) maxi = 48; for (i=0; i= 0; cfg_valid = ioctl (fd, SERIAL_GETCFG, &cfg) >= 0; baud_valid = ioctl (fd, SERIAL_GETBAUD, &baud) >= 0; loop_valid = ioctl (fd, SERIAL_GETLOOP, &loop) >= 0; dpll_valid = ioctl (fd, SERIAL_GETDPLL, &dpll) >= 0; nrzi_valid = ioctl (fd, SERIAL_GETNRZI, &nrzi) >= 0; invclk_valid = ioctl (fd, SERIAL_GETINVCLK, &invclk) >= 0; invrclk_valid = ioctl (fd, SERIAL_GETINVRCLK, &invrclk) >= 0; invtclk_valid = ioctl (fd, SERIAL_GETINVTCLK, &invtclk) >= 0; clk_valid = ioctl (fd, SERIAL_GETCLK, &clk) >= 0; timeslots_valid = ioctl (fd, SERIAL_GETTIMESLOTS, ×lots) >= 0; subchan_valid = ioctl (fd, SERIAL_GETSUBCHAN, &subchan) >= 0; higain_valid = ioctl (fd, SERIAL_GETHIGAIN, &higain) >= 0; phony_valid = ioctl (fd, SERIAL_GETPHONY, &phony) >= 0; unfram_valid = ioctl (fd, SERIAL_GETUNFRAM, &unfram) >= 0; monitor_valid = ioctl (fd, SERIAL_GETMONITOR, &monitor) >= 0; use16_valid = ioctl (fd, SERIAL_GETUSE16, &use16) >= 0; crc4_valid = ioctl (fd, SERIAL_GETCRC4, &crc4) >= 0; ami_valid = ioctl (fd, SERIAL_GETLCODE, &ami) >= 0; level_valid = ioctl (fd, SERIAL_GETLEVEL, &level) >= 0; keepalive_valid = ioctl (fd, SERIAL_GETKEEPALIVE, &keepalive) >= 0; debug_valid = ioctl (fd, SERIAL_GETDEBUG, &debug) >= 0; port_valid = ioctl (fd, SERIAL_GETPORT, &port) >= 0; cable_valid = ioctl (fd, SERIAL_GETCABLE, &cable) >= 0; dir_valid = ioctl (fd, SERIAL_GETDIR, &dir) >= 0; scrambler_valid = ioctl (fd, SERIAL_GETSCRAMBLER, &scrambler) >= 0; cablen_valid = ioctl (fd, SERIAL_GETCABLEN, &cablen) >= 0; rloop_valid = ioctl (fd, SERIAL_GETRLOOP, &rloop) >= 0; mtu_valid = ioctl (fd, SERIAL_GETMTU, &mtu) >= 0; rqlen_valid = ioctl (fd, SERIAL_GETRQLEN, &rqlen) >= 0; printf ("%s", chan_name); if (port_valid) switch (port) { case 0: printf (" (rs232)"); break; case 1: printf (" (v35)"); break; case 2: printf (" (rs530)"); break; } else if (cable_valid) switch (cable) { case 0: printf (" (rs232)"); break; case 1: printf (" (v35)"); break; case 2: printf (" (rs530)"); break; case 3: printf (" (x21)"); break; case 4: printf (" (rs485)"); break; case 9: printf (" (no cable)"); break; } if (debug_valid && debug) printf (" debug=%d", debug); if (protocol_valid && *protocol) printf (" %.8s", protocol); else printf (" idle"); if (cablen_valid) printf (" cablen=%s", cablen ? "on" : "off"); if (keepalive_valid) printf (" keepalive=%s", keepalive ? "on" : "off"); if (cfg_valid) switch (cfg) { case 'a' : printf (" cfg=A"); break; case 'b' : printf (" cfg=B"); break; case 'c' : printf (" cfg=C"); break; case 'd' : printf (" cfg=D"); break; default : printf (" cfg=unknown"); } if (dir_valid) printf (" dir=%d", dir); if (baud_valid) { if (baud) printf (" %ld", baud); else printf (" extclock"); } if (mtu_valid) printf (" mtu=%d", mtu); if (aflag && rqlen_valid) printf (" rqlen=%d", rqlen); if (clk_valid) switch (clk) { case E1CLK_INTERNAL: printf (" syn=int"); break; case E1CLK_RECEIVE: printf (" syn=rcv"); break; case E1CLK_RECEIVE_CHAN0: printf (" syn=rcv0"); break; case E1CLK_RECEIVE_CHAN1: printf (" syn=rcv1"); break; case E1CLK_RECEIVE_CHAN2: printf (" syn=rcv2"); break; case E1CLK_RECEIVE_CHAN3: printf (" syn=rcv3"); break; default: printf (" syn=%d", clk); break; } if (dpll_valid) printf (" dpll=%s", dpll ? "on" : "off"); if (nrzi_valid) printf (" nrzi=%s", nrzi ? "on" : "off"); if (invclk_valid) printf (" invclk=%s", invclk ? "on" : "off"); if (invrclk_valid) printf (" invrclk=%s", invrclk ? "on" : "off"); if (invtclk_valid) printf (" invtclk=%s", invtclk ? "on" : "off"); if (unfram_valid) printf (" unfram=%s", unfram ? "on" : "off"); if (use16_valid) printf (" use16=%s", use16 ? "on" : "off"); if (aflag) { if (crc4_valid) printf (" crc4=%s", crc4 ? "on" : "off"); if (higain_valid) printf (" higain=%s", higain ? "on" : "off"); if (monitor_valid) printf (" monitor=%s", monitor ? "on" : "off"); if (phony_valid) printf (" phony=%s", phony ? "on" : "off"); if (scrambler_valid) printf (" scrambler=%s", scrambler ? "on" : "off"); if (loop_valid) printf (" loop=%s", loop ? "on" : "off"); if (rloop_valid) printf (" rloop=%s", rloop ? "on" : "off"); if (ami_valid) printf (" ami=%s", ami ? "on" : "off"); } if (timeslots_valid) printf (" ts=%s", format_timeslots (timeslots)); if (subchan_valid) printf (" pass=%s", format_timeslots (subchan)); if (level_valid) printf (" (level=-%.1fdB)", level / 10.0); printf ("\n"); } static void setup_chan (int fd, int argc, char **argv) { int i, mode, loop, nrzi, dpll, invclk, phony, use16, crc4, unfram, ami; int higain, clk, keepalive, debug, port, dlci, invrclk, invtclk; int monitor, dir, scrambler, rloop, cablen; int mode_valid; long baud, timeslots, mtu, rqlen; for (i=0; i= '0' && argv[i][0] <= '9') { baud = strtol (argv[i], 0, 10); ioctl (fd, SERIAL_SETBAUD, &baud); } else if (strcasecmp ("extclock", argv[i]) == 0) { baud = 0; ioctl (fd, SERIAL_SETBAUD, &baud); } else if (strncasecmp ("cfg=", argv[i], 4) == 0) { if (strncasecmp ("a", argv[i]+4, 1) == 0) ioctl (fd, SERIAL_SETCFG, "a"); else if (strncasecmp ("b", argv[i]+4, 1) == 0) ioctl (fd, SERIAL_SETCFG, "b"); else if (strncasecmp ("c", argv[i]+4, 1) == 0) ioctl (fd, SERIAL_SETCFG, "c"); else if (strncasecmp ("d", argv[i]+4, 1) == 0) ioctl (fd, SERIAL_SETCFG, "d"); else { fprintf (stderr, "invalid cfg\n"); exit (-1); } } else if (strcasecmp ("idle", argv[i]) == 0) ioctl (fd, SERIAL_SETPROTO, "\0\0\0\0\0\0\0"); else if (strcasecmp ("async", argv[i]) == 0) { mode = SERIAL_ASYNC; if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0) ioctl (fd, SERIAL_SETPROTO, "async\0\0"); } else if (strcasecmp ("sync", argv[i]) == 0) { mode = SERIAL_HDLC; if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0) ioctl (fd, SERIAL_SETPROTO, "sync\0\0\0"); } else if (strcasecmp ("cisco", argv[i]) == 0) { mode = SERIAL_HDLC; ioctl (fd, SERIAL_SETMODE, &mode); ioctl (fd, SERIAL_SETPROTO, "cisco\0\0"); } else if (strcasecmp ("rbrg", argv[i]) == 0) { mode = SERIAL_HDLC; ioctl (fd, SERIAL_SETMODE, &mode); ioctl (fd, SERIAL_SETPROTO, "rbrg\0\0\0"); } else if (strcasecmp ("raw", argv[i]) == 0) { mode = SERIAL_HDLC; ioctl (fd, SERIAL_SETMODE, &mode); ioctl (fd, SERIAL_SETPROTO, "raw\0\0\0\0"); } else if (strcasecmp ("packet", argv[i]) == 0) { mode = SERIAL_HDLC; ioctl (fd, SERIAL_SETMODE, &mode); ioctl (fd, SERIAL_SETPROTO, "packet\0"); } else if (strcasecmp ("ppp", argv[i]) == 0) { /* check that ppp line discipline is present */ if (ppp_ok ()) { mode = SERIAL_HDLC; ioctl (fd, SERIAL_SETMODE, &mode); ioctl (fd, SERIAL_SETPROTO, "ppp\0\0\0\0"); } } else if (strncasecmp ("keepalive=", argv[i], 10) == 0) { keepalive = (strcasecmp ("on", argv[i] + 10) == 0); ioctl (fd, SERIAL_SETKEEPALIVE, &keepalive); } else if (strcasecmp ("fr", argv[i]) == 0) { mode = SERIAL_HDLC; ioctl (fd, SERIAL_SETMODE, &mode); ioctl (fd, SERIAL_SETPROTO, "fr\0\0\0\0\0"); } else if (strcasecmp ("zaptel", argv[i]) == 0) { mode = SERIAL_HDLC; ioctl (fd, SERIAL_SETMODE, &mode); ioctl (fd, SERIAL_SETPROTO, "zaptel\0"); } else if (strncasecmp ("debug=", argv[i], 6) == 0) { debug = strtol (argv[i]+6, 0, 10); mode_valid = ioctl (fd, SERIAL_GETMODE, &mode) >= 0; if (!mode_valid || mode != SERIAL_ASYNC) { if (debug == 0) { set_debug_ifconfig(0); } else { ioctl (fd, SERIAL_SETDEBUG, &debug); set_debug_ifconfig(1); } } else { ioctl (fd, SERIAL_SETDEBUG, &debug); } } else if (strncasecmp ("loop=", argv[i], 5) == 0) { loop = (strcasecmp ("on", argv[i] + 5) == 0); ioctl (fd, SERIAL_SETLOOP, &loop); } else if (strncasecmp ("rloop=", argv[i], 6) == 0) { rloop = (strcasecmp ("on", argv[i] + 6) == 0); ioctl (fd, SERIAL_SETRLOOP, &rloop); } else if (strncasecmp ("dpll=", argv[i], 5) == 0) { dpll = (strcasecmp ("on", argv[i] + 5) == 0); ioctl (fd, SERIAL_SETDPLL, &dpll); } else if (strncasecmp ("nrzi=", argv[i], 5) == 0) { nrzi = (strcasecmp ("on", argv[i] + 5) == 0); ioctl (fd, SERIAL_SETNRZI, &nrzi); } else if (strncasecmp ("invclk=", argv[i], 7) == 0) { invclk = (strcasecmp ("on", argv[i] + 7) == 0); ioctl (fd, SERIAL_SETINVCLK, &invclk); } else if (strncasecmp ("invrclk=", argv[i], 8) == 0) { invrclk = (strcasecmp ("on", argv[i] + 8) == 0); ioctl (fd, SERIAL_SETINVRCLK, &invrclk); } else if (strncasecmp ("invtclk=", argv[i], 8) == 0) { invtclk = (strcasecmp ("on", argv[i] + 8) == 0); ioctl (fd, SERIAL_SETINVTCLK, &invtclk); } else if (strncasecmp ("higain=", argv[i], 7) == 0) { higain = (strcasecmp ("on", argv[i] + 7) == 0); ioctl (fd, SERIAL_SETHIGAIN, &higain); } else if (strncasecmp ("phony=", argv[i], 6) == 0) { phony = (strcasecmp ("on", argv[i] + 6) == 0); ioctl (fd, SERIAL_SETPHONY, &phony); } else if (strncasecmp ("unfram=", argv[i], 7) == 0) { unfram = (strcasecmp ("on", argv[i] + 7) == 0); ioctl (fd, SERIAL_SETUNFRAM, &unfram); } else if (strncasecmp ("scrambler=", argv[i], 10) == 0) { scrambler = (strcasecmp ("on", argv[i] + 10) == 0); ioctl (fd, SERIAL_SETSCRAMBLER, &scrambler); } else if (strncasecmp ("monitor=", argv[i], 8) == 0) { monitor = (strcasecmp ("on", argv[i] + 8) == 0); ioctl (fd, SERIAL_SETMONITOR, &monitor); } else if (strncasecmp ("use16=", argv[i], 6) == 0) { use16 = (strcasecmp ("on", argv[i] + 6) == 0); ioctl (fd, SERIAL_SETUSE16, &use16); } else if (strncasecmp ("crc4=", argv[i], 5) == 0) { crc4 = (strcasecmp ("on", argv[i] + 5) == 0); ioctl (fd, SERIAL_SETCRC4, &crc4); } else if (strncasecmp ("ami=", argv[i], 4) == 0) { ami = (strcasecmp ("on", argv[i] + 4) == 0); ioctl (fd, SERIAL_SETLCODE, &ami); } else if (strncasecmp ("mtu=", argv[i], 4) == 0) { mtu = strtol (argv[i] + 4, 0, 10); ioctl (fd, SERIAL_SETMTU, &mtu); } else if (strncasecmp ("rqlen=", argv[i], 6) == 0) { rqlen = strtol (argv[i] + 6, 0, 10); ioctl (fd, SERIAL_SETRQLEN, &rqlen); } else if (strcasecmp ("syn=int", argv[i]) == 0) { clk = E1CLK_INTERNAL; ioctl (fd, SERIAL_SETCLK, &clk); } else if (strcasecmp ("syn=rcv", argv[i]) == 0) { clk = E1CLK_RECEIVE; ioctl (fd, SERIAL_SETCLK, &clk); } else if (strcasecmp ("syn=rcv0", argv[i]) == 0) { clk = E1CLK_RECEIVE_CHAN0; ioctl (fd, SERIAL_SETCLK, &clk); } else if (strcasecmp ("syn=rcv1", argv[i]) == 0) { clk = E1CLK_RECEIVE_CHAN1; ioctl (fd, SERIAL_SETCLK, &clk); } else if (strcasecmp ("syn=rcv2", argv[i]) == 0) { clk = E1CLK_RECEIVE_CHAN2; ioctl (fd, SERIAL_SETCLK, &clk); } else if (strcasecmp ("syn=rcv3", argv[i]) == 0) { clk = E1CLK_RECEIVE_CHAN3; ioctl (fd, SERIAL_SETCLK, &clk); } else if (strncasecmp ("ts=", argv[i], 3) == 0) { timeslots = scan_timeslots (argv[i] + 3); ioctl (fd, SERIAL_SETTIMESLOTS, ×lots); } else if (strncasecmp ("pass=", argv[i], 5) == 0) { timeslots = scan_timeslots (argv[i] + 5); ioctl (fd, SERIAL_SETSUBCHAN, ×lots); } else if (strncasecmp ("dlci", argv[i], 4) == 0) { dlci = strtol (argv[i]+4, 0, 10); ioctl (fd, SERIAL_ADDDLCI, &dlci); } else if (strncasecmp ("dir=", argv[i], 4) == 0) { dir = strtol (argv[i]+4, 0, 10); ioctl (fd, SERIAL_SETDIR, &dir); } else if (strncasecmp ("port=", argv[i], 5) == 0) { if (strncasecmp ("rs232", argv[i]+5, 5) == 0) { port = 0; ioctl (fd, SERIAL_SETPORT, &port); } else if (strncasecmp ("v35", argv[i]+5, 3) == 0) { port = 1; ioctl (fd, SERIAL_SETPORT, &port); } else if (strncasecmp ("rs449", argv[i]+5, 5) == 0) { port = 2; ioctl (fd, SERIAL_SETPORT, &port); } else { fprintf (stderr, "invalid port type\n"); exit (-1); } #if 1 } else if (strcasecmp ("reset", argv[i]) == 0) { ioctl (fd, SERIAL_RESET, 0); } else if (strcasecmp ("hwreset", argv[i]) == 0) { ioctl (fd, SERIAL_HARDRESET, 0); #endif } else if (strncasecmp ("cablen=", argv[i], 7) == 0) { loop = (strcasecmp ("on", argv[i] + 7) == 0); ioctl (fd, SERIAL_SETCABLEN, &cablen); } } } static void get_mask (void) { #ifdef __linux__ int fd; fd = open ("/dev/serial/ctl0", 0); if (fd < 0) { perror ("/dev/serial/ctl0"); exit (-1); } if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) { perror ("getting list of channels"); exit (-1); } close (fd); #else int fd, fd1, fd2, fd3, i; char buf [80]; for (i=0, fd=-1; i<12 && fd<0; i++) { sprintf (buf, "/dev/cx%d", i*4); fd = open (buf, 0); } for (i=0, fd1=-1; i<3 && fd1<0; i++) { sprintf (buf, "/dev/ct%d", i*2); fd1 = open (buf, 0); } for (i=0, fd2=-1; i<3 && fd2<0; i++) { sprintf (buf, "/dev/cp%d", i*4); fd2 = open (buf, 0); } /* Try only one */ for (i=0, fd3=-1; i<1 && fd3<0; i++) { sprintf (buf, "/dev/ce%d", i*4); fd3 = open (buf, 0); } if ((fd < 0) && (fd1 < 0) && (fd2 < 0) && (fd3 < 0)) { fprintf (stderr, "No Cronyx adapters installed\n"); exit (-1); } if (fd >= 0) { if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) { perror ("getting list of channels"); exit (-1); } close (fd); } if (fd1 >= 0) { if (ioctl (fd1, SERIAL_GETREGISTERED, (mask+16)) < 0) { perror ("getting list of channels"); exit (-1); } close (fd1); } if (fd2 >= 0) { if (ioctl (fd2, SERIAL_GETREGISTERED, (mask+32)) < 0) { perror ("getting list of channels"); exit (-1); } close (fd2); } if (fd3 >= 0) { if (ioctl (fd3, SERIAL_GETREGISTERED, (mask+48)) < 0) { perror ("getting list of channels"); exit (-1); } close (fd3); } #endif } static int open_chan_ctl (int num) { char device [80]; int fd; #ifdef __linux__ sprintf (device, "/dev/serial/ctl%d", num); #else switch (adapter_type) { case 0: sprintf (device, "/dev/cx%d", num); break; case 1: sprintf (device, "/dev/ct%d", num); break; case 2: sprintf (device, "/dev/cp%d", num); break; case 3: sprintf (device, "/dev/ce%d", num); break; } #endif fd = open (device, 0); if (fd < 0) { if (errno == ENODEV) fprintf (stderr, "chan%d: not configured\n", num); else perror (device); exit (-1); } #ifdef __linux__ if (ioctl (fd, SERIAL_GETNAME, &chan_name) < 0) sprintf (chan_name, "chan%d", num); #else switch (adapter_type) { case 0: sprintf (chan_name, "cx%d", num); break; case 1: sprintf (chan_name, "ct%d", num); break; case 2: sprintf (chan_name, "cp%d", num); break; case 3: sprintf (chan_name, "ce%d", num); break; } #endif return fd; } int main (int argc, char **argv) { char *p; int fd, need_header, chan_num; if (argc > 1 && strcmp(argv[1], "help") == 0) usage(); for (;;) { switch (getopt (argc, argv, "mseftucviax")) { case -1: break; case 'a': ++aflag; continue; case 'm': ++mflag; continue; case 's': ++sflag; continue; case 'e': ++eflag; continue; case 'f': ++eflag; ++fflag; continue; case 't': ++tflag; continue; case 'u': ++tflag; ++uflag; continue; case 'c': ++cflag; continue; case 'v': ++vflag; continue; case 'i': ++iflag; continue; case 'x': ++xflag; continue; default: usage(); } break; } argc -= optind; argv += optind; if (argc <= 0) { get_mask (); need_header = 1; adapter_type = 0; #ifndef __linux__ for (; adapter_type < 4; ++adapter_type) #endif { for (chan_num=0; chan_num= 0) { printf ("Version: %s\n", buf); close (fd); return (0); } #endif } if (iflag) { print_chan (fd); print_ifconfig (fd); } else if (sflag||xflag) print_stats (fd, need_header); else if (mflag) print_modems (fd, need_header); else if (eflag) print_e1_stats (fd, need_header); else if (tflag) print_e3_stats (fd, need_header); else if (cflag) clear_stats (fd); else print_chan (fd); close (fd); need_header = 0; } } return (0); } p = argv[0] + strlen (argv[0]); while (p > argv[0] && p[-1] >= '0' && p[-1] <= '9') --p; chan_num = strtol (p, 0, 10); #ifndef __linux__ if (strncasecmp ("cx", argv[0], 2)==0) adapter_type = 0; else if (strncasecmp ("ct", argv[0], 2)==0) adapter_type = 1; else if (strncasecmp ("cp", argv[0], 2)==0) adapter_type = 2; else if (strncasecmp ("ce", argv[0], 2)==0) adapter_type = 3; else { fprintf (stderr, "Wrong channel name\n"); exit (-1); } #endif argc--; argv++; fd = open_chan_ctl (chan_num); if (vflag) { #ifdef __linux__ char buf[256]; if (ioctl (fd, SERIAL_GETVERSIONSTRING, &buf) >= 0) printf ("Version: %s\n", buf); #endif } if (iflag) { print_chan (fd); print_ifconfig (fd); close (fd); return (0); } if (sflag||xflag) { print_stats (fd, 1); close (fd); return (0); } if (mflag) { print_modems (fd, 1); close (fd); return (0); } if (eflag) { print_e1_stats (fd, 1); close (fd); return (0); } if (tflag) { print_e3_stats (fd, 1); close (fd); return (0); } if (cflag) { clear_stats (fd); close (fd); return (0); } if (argc > 0) setup_chan (fd, argc, argv); else print_chan (fd); close (fd); return (0); }