sconfig.c revision 155064
16059Samurai/* 26059Samurai * Channel configuration utility for Cronyx serial adapters. 36059Samurai * 46059Samurai * Copyright (C) 1997-2002 Cronyx Engineering. 56059Samurai * Author: Serge Vakulenko, <vak@cronyx.ru> 66059Samurai * 76059Samurai * Copyright (C) 1999-2005 Cronyx Engineering. 86059Samurai * Author: Roman Kurakin, <rik@cronyx.ru> 96059Samurai * 106059Samurai * This software is distributed with NO WARRANTIES, not even the implied 116059Samurai * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 126059Samurai * 136059Samurai * Authors grant any other persons or organisations permission to use 146059Samurai * or modify this software as long as this message is kept with the software, 156059Samurai * all derivative works or modified versions. 166059Samurai * 176059Samurai * Cronyx Id: sconfig.c,v 1.4.2.2 2005/11/09 13:01:35 rik Exp $ 186059Samurai * $FreeBSD: head/sbin/sconfig/sconfig.c 155064 2006-01-30 21:08:30Z rik $ 196059Samurai */ 2036465Sbrian#include <stdio.h> 218857Srgrimes#include <stdlib.h> 226059Samurai#include <string.h> 236059Samurai#include <unistd.h> 2436285Sbrian#include <fcntl.h> 2536452Sbrian#include <errno.h> 2630715Sbrian#include <ctype.h> 2730715Sbrian#include <sys/ioctl.h> 2830715Sbrian#include <sys/types.h> 2930715Sbrian#include <sys/stat.h> 3036285Sbrian#include <sys/socket.h> 3136285Sbrian#include <net/if.h> 3230715Sbrian#include <machine/cserial.h> 3330715Sbrian 346059Samurai#define MAXCHAN 128 3511336Samurai 3630715Sbrianint vflag, eflag, sflag, mflag, cflag, fflag, iflag, aflag, xflag; 3730715Sbrianint tflag, uflag; 3830715Sbrianchar mask[64]; 396059Samuraiint adapter_type; /* 0-sigma, 1-tau, 2-taupci, 3-tau32 */ 406059Samuraichar chan_name[16]; 4118786Sjkh 4230715Sbrianextern char *optarg; 4330715Sbrianextern int optind; 4430715Sbrian 4530715Sbrianstatic void 4631061Sbrianusage (void) 4730715Sbrian{ 4830715Sbrian printf( 4936285Sbrian"Serial Adapter Configuration Utility\n" 506059Samurai"Copyright (C) 1998-2005 Cronyx Engineering.\n" 5131514Sbrian"See also man sconfig (8)\n" 5213389Sphk"Usage:\n" 5336285Sbrian"\tsconfig [-aimsxeftuc] [device [parameters ...]]\n" 5436285Sbrian"\n" 5536285Sbrian"Options:\n" 566059Samurai"\t<no options>\t\t -- print channel options\n" 5736285Sbrian"\t-a\t\t\t -- print all settings of the channel\n" 5836285Sbrian"\t-i\t\t\t -- print network interface status\n" 5936285Sbrian"\t-m\t\t\t -- print modem signal status\n" 6036285Sbrian"\t-s\t\t\t -- print channel statistics\n" 6136285Sbrian"\t-x\t\t\t -- print extended channel statistics\n" 6226142Sbrian"\t-e\t\t\t -- print short E1/G703 statistics\n" 636735Samurai"\t-f\t\t\t -- print full E1/G703 statistics\n" 6413389Sphk"\t-t\t\t\t -- print short E3/T3/STS-1 statistics\n" 6513389Sphk"\t-u\t\t\t -- print full E3/T3/STS-1 statistics\n" 6623840Sbrian"\t-c\t\t\t -- clear statistics\n" 6730715Sbrian"\nParameters:\n" 6831195Sbrian"\t<number>\t\t -- baud rate, internal clock\n" 6936285Sbrian"\textclock\t\t -- external clock (default)\n" 7036285Sbrian"\nProtocol options:\n" 7136285Sbrian"\tasync\t\t\t -- asynchronous protocol\n" 7236285Sbrian#ifdef __linux__ 7336285Sbrian"\tsync\t\t\t -- synchronous protocol\n" 746059Samurai#endif 756735Samurai"\tcisco\t\t\t -- Cisco/HDLC protocol\n" 766735Samurai"\tfr\t\t\t -- Frame Relay protocol\n" 776735Samurai#ifdef __linux__ 786735Samurai"\t dlci<number>\t -- Add new DLCI\n" 796735Samurai#endif 806735Samurai"\tppp\t\t\t -- PPP protocol\n" 8136431Sbrian#ifdef __linux__ 8230715Sbrian"\trbrg\t\t\t -- Remote bridge\n" 8331343Sbrian"\traw\t\t\t -- raw HDLC protocol\n" 8430715Sbrian"\tpacket\t\t\t -- packetized HDLC protocol\n" 8536285Sbrian"\tidle\t\t\t -- no protocol\n" 8636285Sbrian#else 876059Samurai"\t keepalive={on,of}\t -- Enable/disable keepalive\n" 8810528Samurai#endif 8936285Sbrian"\nInterface options:\n" 906059Samurai"\tport={rs232,v35,rs449}\t -- port type (for old models of Sigma)\n" 9136285Sbrian"\tcfg={A,B,C}\t\t -- adapter configuration\n" 9236285Sbrian"\tloop={on,off}\t\t -- internal loopback\n" 9336285Sbrian"\trloop={on,off}\t\t -- remote loopback\n" 946059Samurai"\tdpll={on,off}\t\t -- DPLL mode\n" 956059Samurai"\tnrzi={on,off}\t\t -- NRZI encoding\n" 966059Samurai"\tinvclk={on,off}\t\t -- invert receive and transmit clock\n" 9736285Sbrian"\tinvrclk={on,off}\t -- invert receive clock\n" 986059Samurai"\tinvtclk={on,off}\t -- invert transmit clock\n" 9936285Sbrian"\thigain={on,off}\t\t -- E1 high non linear input sensitivity \n\t\t\t\t (long line)\n" 10036285Sbrian"\tmonitor={on,off}\t -- E1 high linear input sensitivity \n\t\t\t\t (interception mode)\n" 10136285Sbrian"\tphony={on,off}\t\t -- E1 telepnony mode\n" 10236285Sbrian"\tunfram={on,off}\t\t -- E1 unframed mode\n" 10336285Sbrian"\tscrambler={on,off}\t -- G.703 scrambling mode\n" 1046059Samurai"\tuse16={on,off}\t\t -- E1 timeslot 16 usage\n" 1056059Samurai"\tcrc4={on,off}\t\t -- E1 CRC4 mode\n" 1066059Samurai#ifdef __linux__ 1076059Samurai"\tami={on,off}\t\t -- E1 AMI or HDB3 line code\n" 10828679Sbrian"\tmtu={size}\t\t -- set MTU in bytes\n" 1096059Samurai#endif 11026858Sbrian"\tsyn={int,rcv,rcvX}\t -- G.703 transmit clock\n" 11136285Sbrian"\tts=...\t\t\t -- E1 timeslots\n" 11236285Sbrian"\tpass=...\t\t -- E1 subchannel timeslots\n" 11336285Sbrian"\tdir=<num>\t\t -- connect channel to link<num>\n" 11436285Sbrian/*"\trqken={size}\t\t -- set receive queue length in packets\n"*/ 1156059Samurai/*"\tcablen={on,off}\t\t -- T3/STS-1 high transmitter output for long cable\n"*/ 1166059Samurai"\tdebug={0,1,2}\t\t -- enable/disable debug messages\n" 1176059Samurai ); 11828679Sbrian exit (0); 1196059Samurai} 12036285Sbrian 12128679Sbrianstatic unsigned long 1226059Samuraiscan_timeslots (char *s) 1236059Samurai{ 12436285Sbrian char *e; 12536285Sbrian long v; 12610528Samurai int i; 12736285Sbrian unsigned long ts, lastv; 12810528Samurai 12936285Sbrian ts = lastv = 0; 13036285Sbrian for (;;) { 13110528Samurai v = strtol (s, &e, 10); 13210528Samurai if (e == s) 13310528Samurai break; 13436285Sbrian if (*e == '-') { 13510528Samurai lastv = v; 13636285Sbrian s = e+1; 13736285Sbrian continue; 13810528Samurai } 13910528Samurai if (*e == ',') 14026940Sbrian ++e; 14136285Sbrian 14226940Sbrian if (lastv) 14336285Sbrian for (i=lastv; i<v; ++i) 14436285Sbrian ts |= 1L << i; 14536285Sbrian ts |= 1L << v; 14626940Sbrian 14726940Sbrian lastv = 0; 14831081Sbrian s = e; 14931081Sbrian } 15031081Sbrian return ts; 15136285Sbrian} 15236285Sbrian 15331081Sbrianstatic int 15431081Sbrianppp_ok (void) 15531343Sbrian{ 15625908Sbrian#ifdef __linux__ 15725908Sbrian int s, p; 15825908Sbrian struct ifreq ifr; 15931343Sbrian char pttyname[32]; 16031343Sbrian char *p1, *p2; 16131343Sbrian int i, j; 16231343Sbrian int ppp_disc = N_PPP; 16310528Samurai 16431962Sbrian /* 16525908Sbrian * Open a socket for doing the ioctl operations. 16625908Sbrian */ 16725908Sbrian s = socket (AF_INET, SOCK_DGRAM, 0); 16825908Sbrian if (s < 0) { 16925908Sbrian fprintf (stderr, "Error opening socket.\n"); 17030715Sbrian return 0; 17131343Sbrian } 1726059Samurai strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); 17320120Snate if (ioctl (s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0) { 17431343Sbrian /* Ok. */ 17531343Sbrian close (s); 17631343Sbrian return 1; 17731343Sbrian } 17831343Sbrian close (s); 1796059Samurai 1806059Samurai /* open pseudo-tty and try to set PPP discipline */ 1816059Samurai sprintf (pttyname, "/dev/ptyXX"); 18231197Sbrian p1 = &pttyname[8]; 18336285Sbrian p2 = &pttyname[9]; 1846059Samurai for (i=0; i<16; i++) { 18536465Sbrian struct stat stb; 1866059Samurai 1876059Samurai *p1 = "pqrstuvwxyzabcde"[i]; 18836285Sbrian *p2 = '0'; 18936465Sbrian if (stat (pttyname, &stb) < 0) 1906059Samurai continue; 1916059Samurai for (j=0; j<16; j++) { 19236465Sbrian *p2 = "0123456789abcdef"[j]; 19336465Sbrian p = open (pttyname, 2); 19436465Sbrian if (p > 0) { 19536465Sbrian if (ioctl (p, TIOCSETD, &ppp_disc) < 0) { 19631343Sbrian fprintf (stderr, "No PPP discipline in kernel.\n"); 19736465Sbrian close (p); 19836285Sbrian return 0; 19936465Sbrian } 20036465Sbrian close (p); 20136465Sbrian return 1; 20236465Sbrian } 20336465Sbrian } 20436465Sbrian } 20536465Sbrian fprintf (stderr, "Cannot get pseudo-tty.\n"); 20636465Sbrian return 0; 20736465Sbrian#else 20836465Sbrian return 1; 20936465Sbrian#endif 21036465Sbrian} 21136465Sbrian 21236465Sbrianstatic char * 21336465Sbrianformat_timeslots (unsigned long s) 21436465Sbrian{ 21536465Sbrian static char buf [100]; 21636465Sbrian char *p = buf; 21736465Sbrian int i; 2186059Samurai 21928679Sbrian for (i=1; i<32; ++i) 22028679Sbrian if ((s >> i) & 1) { 2216059Samurai int prev = (i > 1) & (s >> (i-1)); 22236465Sbrian int next = (i < 31) & (s >> (i+1)); 2236059Samurai 22436285Sbrian if (prev) { 2256059Samurai if (next) 2266059Samurai continue; 2276059Samurai *p++ = '-'; 2286059Samurai } else if (p > buf) 22936285Sbrian *p++ = ','; 2306059Samurai 2316059Samurai if (i >= 10) 23231197Sbrian *p++ = '0' + i / 10; 23336285Sbrian *p++ = '0' + i % 10; 23436285Sbrian } 23536285Sbrian *p = 0; 23636285Sbrian return buf; 23736285Sbrian} 23836285Sbrian 23931197Sbrianstatic void 2406059Samuraiprint_modems (int fd, int need_header) 2416059Samurai{ 24226940Sbrian int status; 24328679Sbrian 2446059Samurai if (ioctl (fd, TIOCMGET, &status) < 0) { 24531197Sbrian perror ("getting modem status"); 24636285Sbrian return; 24736285Sbrian } 24836285Sbrian if (need_header) 24926516Sbrian printf ("Channel\tLE\tDTR\tDSR\tRTS\tCTS\tCD\n"); 25031823Sbrian printf ("%s\t%s\t%s\t%s\t%s\t%s\t%s\n", chan_name, 25131823Sbrian status & TIOCM_LE ? "On" : "-", 25231823Sbrian status & TIOCM_DTR ? "On" : "-", 25331823Sbrian status & TIOCM_DSR ? "On" : "-", 25431823Sbrian status & TIOCM_RTS ? "On" : "-", 25531823Sbrian status & TIOCM_CTS ? "On" : "-", 25631823Sbrian status & TIOCM_CD ? "On" : "-"); 25731823Sbrian} 25831823Sbrian 25931823Sbrianstatic void 26030715Sbrianprint_ifconfig (int fd) 26136285Sbrian{ 26226516Sbrian char buf [64]; 26328679Sbrian#ifdef __linux__ 26428679Sbrian char protocol [8]; 26536285Sbrian 26631121Sbrian if (ioctl (fd, SERIAL_GETPROTO, &protocol) >= 0 && 26736285Sbrian strcmp (protocol, "fr") == 0) 26836285Sbrian sprintf (buf, "ifconfig %sd16 2>/dev/null", chan_name); 26936285Sbrian else 27036285Sbrian#endif 27136285Sbrian sprintf (buf, "ifconfig %s 2>/dev/null", chan_name); 27236285Sbrian system (buf); 27336285Sbrian} 27436285Sbrian 27536465Sbrianstatic char * 27636285Sbrianformat_long (unsigned long val) 27736285Sbrian{ 27836285Sbrian static char s[32]; 27936285Sbrian int l; 28036285Sbrian l = sprintf (s, "%lu", val); 28136285Sbrian if (l>7 && !sflag) { 28236285Sbrian s[3] = s[2]; 28336285Sbrian s[2] = s[1]; 28436285Sbrian s[1] = '.'; 28536285Sbrian s[4] = 'e'; 28636285Sbrian sprintf (s + 5, "%02d", l-1); 28736285Sbrian } 28836285Sbrian return s; 28936465Sbrian} 29036285Sbrian 29136285Sbrianstatic void 29231121Sbrianprint_stats (int fd, int need_header) 29331158Sbrian{ 29431158Sbrian struct serial_statistics st; 29531158Sbrian unsigned long sarr [9]; 29631158Sbrian int i; 29731158Sbrian 29831158Sbrian if (ioctl (fd, SERIAL_GETSTAT, &st) < 0) { 29936285Sbrian perror ("getting statistics"); 30031158Sbrian return; 30131158Sbrian } 30231158Sbrian if (need_header) { 30331158Sbrian if (sflag) { 30431158Sbrian printf (" ------------Receive----------- " 30531158Sbrian "------------Transmit----------\n"); 30631158Sbrian printf ("Channel Interrupts Packets Errors " 30731158Sbrian "Interrupts Packets Errors\n"); 30836285Sbrian } 30931121Sbrian else { 31036285Sbrian printf (" --------Receive--------------- " 31131157Sbrian "--------Transmit-------------- Modem\n"); 31231197Sbrian printf ("Channel Intrs Bytes Packets Errors " 31336285Sbrian "Intrs Bytes Packets Errors Intrs\n"); 31431157Sbrian } 31536285Sbrian } 31631121Sbrian 31729083Sbrian sarr [0] = st.rintr; 31831121Sbrian sarr [1] = st.ibytes; 31936314Sbrian sarr [2] = st.ipkts; 32036285Sbrian sarr [3] = st.ierrs; 32126940Sbrian sarr [4] = st.tintr; 3226059Samurai sarr [5] = st.obytes; 32336314Sbrian sarr [6] = st.opkts; 32436314Sbrian sarr [7] = st.oerrs; 32536314Sbrian sarr [8] = st.mintr; 32636314Sbrian printf ("%s", chan_name); 32736285Sbrian if (sflag) { 32831121Sbrian printf ("\t%-12lu%-12lu%-12lu%-12lu%-12lu%-12lu", sarr[0], 32936285Sbrian sarr[2], sarr[3], sarr[4], sarr[6], sarr[7]); 33036285Sbrian } else { 33136285Sbrian for (i = 0; i < 9; i++) 33236285Sbrian printf ("\t%s", format_long (sarr [i])); 33336285Sbrian printf ("\n"); 33436285Sbrian } 33536285Sbrian} 33636285Sbrian 33724753Sachestatic void 3386059Samuraiclear_stats (int fd) 33936465Sbrian{ 34036285Sbrian if (ioctl (fd, SERIAL_CLRSTAT, 0) < 0) { 34136285Sbrian perror ("clearing statistics"); 34236285Sbrian exit (-1); 34336285Sbrian } 34431197Sbrian} 34531197Sbrian 34636285Sbrianstatic char * 34736285Sbrianformat_e1_status (unsigned long status) 34836285Sbrian{ 34936285Sbrian static char buf [80]; 35031197Sbrian 35136285Sbrian if (status == 0) 35236285Sbrian return "n/a"; 35336285Sbrian if (status & E1_NOALARM) 35436285Sbrian return "Ok"; 3556059Samurai buf[0] = 0; 35636285Sbrian if (status & E1_LOS) strcat (buf, ",LOS"); 35736465Sbrian if (status & E1_AIS) strcat (buf, ",AIS"); 35836285Sbrian if (status & E1_LOF) strcat (buf, ",LOF"); 35936285Sbrian if (status & E1_LOMF) strcat (buf, ",LOMF"); 36036285Sbrian if (status & E1_CRC4E) strcat (buf, ",CRC4E"); 36136285Sbrian if (status & E1_FARLOF) strcat (buf, ",FARLOF"); 36236285Sbrian if (status & E1_AIS16) strcat (buf, ",AIS16"); 3636059Samurai if (status & E1_FARLOMF) strcat (buf, ",FARLOMF"); 36426940Sbrian/* if (status & E1_TSTREQ) strcat (buf, ",TSTREQ");*/ 36536465Sbrian/* if (status & E1_TSTERR) strcat (buf, ",TSTERR");*/ 36636285Sbrian if (buf[0] == ',') 36736285Sbrian return buf+1; 36836285Sbrian return "Unknown"; 36936285Sbrian} 37036465Sbrian 37136285Sbrianstatic void 37236285Sbrianprint_frac (int leftalign, unsigned long numerator, unsigned long divider) 37320813Sjkh{ 3746059Samurai int n; 37528679Sbrian 37620813Sjkh if (numerator < 1 || divider < 1) { 37736285Sbrian printf (leftalign ? "/- " : " -"); 37836285Sbrian return; 37920813Sjkh } 38036285Sbrian n = (int) (0.5 + 1000.0 * numerator / divider); 38120813Sjkh if (n < 1000) { 38220813Sjkh printf (leftalign ? "/.%-3d" : " .%03d", n); 38311336Samurai return; 38436465Sbrian } 38536285Sbrian putchar (leftalign ? '/' : ' '); 38620813Sjkh 38736285Sbrian if (n >= 1000000) n = (n+500) / 1000 * 1000; 38836285Sbrian else if (n >= 100000) n = (n+50) / 100 * 100; 38936285Sbrian else if (n >= 10000) n = (n+5) / 10 * 10; 39036285Sbrian 39136285Sbrian switch (n) { 39236285Sbrian case 1000: printf (".999"); return; 39336285Sbrian case 10000: n = 9990; break; 39436285Sbrian case 100000: n = 99900; break; 39536285Sbrian case 1000000: n = 999000; break; 39636285Sbrian } 39725908Sbrian if (n < 10000) printf ("%d.%d", n/1000, n/10%100); 39836285Sbrian else if (n < 100000) printf ("%d.%d", n/1000, n/100%10); 39936285Sbrian else if (n < 1000000) printf ("%d.", n/1000); 40025908Sbrian else printf ("%d", n/1000); 40136285Sbrian} 40236285Sbrian 40328679Sbrianstatic void 40428679Sbrianprint_e1_stats (int fd, int need_header) 40536285Sbrian{ 40620813Sjkh struct e1_statistics st; 40728679Sbrian int i, maxi; 40836465Sbrian 40936285Sbrian if (need_header) 41036285Sbrian printf ("Chan\t Unav/Degr Bpv/Fsyn CRC/RCRC Err/Lerr Sev/Bur Oof/Slp Status\n"); 41136285Sbrian 41220813Sjkh if (ioctl (fd, SERIAL_GETESTAT, &st) < 0) 41336285Sbrian return; 41436285Sbrian printf ("%s\t", chan_name); 41536285Sbrian 41636285Sbrian /* Unavailable seconds, degraded minutes */ 41736285Sbrian print_frac (0, st.currnt.uas, st.cursec); 41826686Sbrian print_frac (1, 60 * st.currnt.dm, st.cursec); 41936285Sbrian 42036285Sbrian /* Bipolar violations, frame sync errors */ 42136285Sbrian print_frac (0, st.currnt.bpv, st.cursec); 42236285Sbrian print_frac (1, st.currnt.fse, st.cursec); 42336285Sbrian 42426686Sbrian /* CRC errors, remote CRC errors (E-bit) */ 4256059Samurai print_frac (0, st.currnt.crce, st.cursec); 42636285Sbrian print_frac (1, st.currnt.rcrce, st.cursec); 42732129Sbrian 42836285Sbrian /* Errored seconds, line errored seconds */ 42936285Sbrian print_frac (0, st.currnt.es, st.cursec); 43036285Sbrian print_frac (1, st.currnt.les, st.cursec); 4316059Samurai 43229696Sbrian /* Severely errored seconds, bursty errored seconds */ 43336285Sbrian print_frac (0, st.currnt.ses, st.cursec); 43436431Sbrian print_frac (1, st.currnt.bes, st.cursec); 43536285Sbrian 4366059Samurai /* Out of frame seconds, controlled slip seconds */ 43736285Sbrian print_frac (0, st.currnt.oofs, st.cursec); 4386059Samurai print_frac (1, st.currnt.css, st.cursec); 4396059Samurai 4406059Samurai printf (" %s\n", format_e1_status (st.status)); 44136431Sbrian 4426059Samurai if (fflag) { 4436059Samurai /* Print total statistics. */ 44436285Sbrian printf ("\t"); 4456059Samurai print_frac (0, st.total.uas, st.totsec); 44636285Sbrian print_frac (1, 60 * st.total.dm, st.totsec); 44723598Sache 44828679Sbrian print_frac (0, st.total.bpv, st.totsec); 44928679Sbrian print_frac (1, st.total.fse, st.totsec); 45028679Sbrian 4517001Samurai print_frac (0, st.total.crce, st.totsec); 45236314Sbrian print_frac (1, st.total.rcrce, st.totsec); 45336285Sbrian 45425067Sbrian print_frac (0, st.total.es, st.totsec); 45536314Sbrian print_frac (1, st.total.les, st.totsec); 45636314Sbrian 45736314Sbrian print_frac (0, st.total.ses, st.totsec); 45836285Sbrian print_frac (1, st.total.bes, st.totsec); 45936285Sbrian 46036285Sbrian print_frac (0, st.total.oofs, st.totsec); 46126551Sbrian print_frac (1, st.total.css, st.totsec); 46236285Sbrian 46326696Sbrian printf (" -- Total\n"); 46436345Sbrian 46536285Sbrian /* Print 24-hour history. */ 46636285Sbrian maxi = (st.totsec - st.cursec) / 900; 46736285Sbrian if (maxi > 48) 46836285Sbrian maxi = 48; 46936285Sbrian for (i=0; i<maxi; ++i) { 47036285Sbrian printf (" "); 47136285Sbrian print_frac (0, st.interval[i].uas, 15*60); 47236285Sbrian print_frac (1, 60 * st.interval[i].dm, 15*60); 47336285Sbrian 47436285Sbrian print_frac (0, st.interval[i].bpv, 15*60); 47536285Sbrian print_frac (1, st.interval[i].fse, 15*60); 47636285Sbrian 47736285Sbrian print_frac (0, st.interval[i].crce, 15*60); 47836285Sbrian print_frac (1, st.interval[i].rcrce, 15*60); 47936285Sbrian 48036285Sbrian print_frac (0, st.interval[i].es, 15*60); 48136285Sbrian print_frac (1, st.interval[i].les, 15*60); 48236285Sbrian 48336285Sbrian print_frac (0, st.interval[i].ses, 15*60); 48436285Sbrian print_frac (1, st.interval[i].bes, 15*60); 48536285Sbrian 48636285Sbrian print_frac (0, st.interval[i].oofs, 15*60); 48736285Sbrian print_frac (1, st.interval[i].css, 15*60); 48836285Sbrian 48936285Sbrian if (i < 3) 49036285Sbrian printf (" -- %dm\n", (i+1)*15); 49136285Sbrian else 49236285Sbrian printf (" -- %dh %dm\n", (i+1)/4, (i+1)%4*15); 49336285Sbrian } 49436285Sbrian } 49536285Sbrian} 49636285Sbrian 49736285Sbrianstatic char * 49828679Sbrianformat_e3_status (unsigned long status) 49928679Sbrian{ 5008857Srgrimes static char buf [80]; 5016059Samurai 50236345Sbrian buf[0] = 0; 50336345Sbrian if (status & E3_LOS) strcat (buf, ",LOS"); 50436345Sbrian if (status & E3_TXE) strcat (buf, ",XMIT"); 50536345Sbrian if (buf[0] == ',') 50636345Sbrian return buf+1; 50736285Sbrian return "Ok"; 50836285Sbrian} 50936285Sbrian 51036285Sbrianstatic char * 5116059Samuraiformat_e3_cv (unsigned long cv, unsigned long baud, unsigned long time) 51228679Sbrian{ 51336285Sbrian static char buf[80]; 51436285Sbrian 51528536Sbrian if (!cv || !baud || !time) 51636285Sbrian sprintf (buf, " - "); 51736285Sbrian else 51832039Sbrian sprintf (buf, "%10lu (%.1e)", cv, (double)cv/baud/time); 51936285Sbrian return buf; 52036285Sbrian} 52136285Sbrian 52236285Sbrianstatic void 52336285Sbrianprint_e3_stats (int fd, int need_header) 52436345Sbrian{ 52536285Sbrian struct e3_statistics st; 52636285Sbrian int i, maxi; 52736285Sbrian long baud; 5286059Samurai 529 if (need_header) 530 printf ("Chan\t--Code Violations---\t\t\t\t\t ----Status----\n"); 531 532 if (ioctl (fd, SERIAL_GETE3STAT, &st) < 0 || 533 ioctl (fd, SERIAL_GETBAUD, &baud) < 0) 534 return; 535 536 if (!st.cursec) 537 st.cursec = 1; 538 539 printf ("%s\t%s\t\t\t\t\t", chan_name, 540 format_e3_cv (st.ccv, baud, st.cursec)); 541 542 printf (" %s\n", format_e3_status (st.status)); 543 544 545 if (uflag) { 546 /* Print total statistics. */ 547 printf ("\t%s\t\t\t\t\t", 548 format_e3_cv (st.tcv, baud, st.totsec)); 549 printf (" -- Total\n"); 550 551 /* Print 24-hour history. */ 552 maxi = (st.totsec - st.cursec) / 900; 553 if (maxi > 48) 554 maxi = 48; 555 for (i=0; i<maxi; ++i) { 556 printf ("\t%s\t\t\t\t\t", 557 format_e3_cv (st.icv[i], baud, 15*60)); 558 if (i < 3) 559 printf (" -- %2dm\n", (i+1)*15); 560 else 561 printf (" -- %2dh %2dm\n", (i+1)/4, (i+1)%4*15); 562 } 563 } 564} 565 566static void 567print_chan (int fd) 568{ 569 char protocol [8]; 570 char cfg; 571 int loop, dpll, nrzi, invclk, clk, higain, phony, use16, crc4; 572 int level, keepalive, debug, port, invrclk, invtclk, unfram, monitor; 573 int cable, dir, scrambler, ami, mtu; 574 int cablen, rloop, rqlen; 575 long baud, timeslots, subchan; 576 int protocol_valid, baud_valid, loop_valid, use16_valid, crc4_valid; 577 int dpll_valid, nrzi_valid, invclk_valid, clk_valid, phony_valid; 578 int timeslots_valid, subchan_valid, higain_valid, level_valid; 579 int keepalive_valid, debug_valid, cfg_valid, port_valid; 580 int invrclk_valid, invtclk_valid, unfram_valid, monitor_valid; 581 int cable_valid, dir_valid, scrambler_valid, ami_valid, mtu_valid; 582 int cablen_valid, rloop_valid, rqlen_valid; 583 584 protocol_valid = ioctl (fd, SERIAL_GETPROTO, &protocol) >= 0; 585 cfg_valid = ioctl (fd, SERIAL_GETCFG, &cfg) >= 0; 586 baud_valid = ioctl (fd, SERIAL_GETBAUD, &baud) >= 0; 587 loop_valid = ioctl (fd, SERIAL_GETLOOP, &loop) >= 0; 588 dpll_valid = ioctl (fd, SERIAL_GETDPLL, &dpll) >= 0; 589 nrzi_valid = ioctl (fd, SERIAL_GETNRZI, &nrzi) >= 0; 590 invclk_valid = ioctl (fd, SERIAL_GETINVCLK, &invclk) >= 0; 591 invrclk_valid = ioctl (fd, SERIAL_GETINVRCLK, &invrclk) >= 0; 592 invtclk_valid = ioctl (fd, SERIAL_GETINVTCLK, &invtclk) >= 0; 593 clk_valid = ioctl (fd, SERIAL_GETCLK, &clk) >= 0; 594 timeslots_valid = ioctl (fd, SERIAL_GETTIMESLOTS, ×lots) >= 0; 595 subchan_valid = ioctl (fd, SERIAL_GETSUBCHAN, &subchan) >= 0; 596 higain_valid = ioctl (fd, SERIAL_GETHIGAIN, &higain) >= 0; 597 phony_valid = ioctl (fd, SERIAL_GETPHONY, &phony) >= 0; 598 unfram_valid = ioctl (fd, SERIAL_GETUNFRAM, &unfram) >= 0; 599 monitor_valid = ioctl (fd, SERIAL_GETMONITOR, &monitor) >= 0; 600 use16_valid = ioctl (fd, SERIAL_GETUSE16, &use16) >= 0; 601 crc4_valid = ioctl (fd, SERIAL_GETCRC4, &crc4) >= 0; 602 ami_valid = ioctl (fd, SERIAL_GETLCODE, &ami) >= 0; 603 level_valid = ioctl (fd, SERIAL_GETLEVEL, &level) >= 0; 604 keepalive_valid = ioctl (fd, SERIAL_GETKEEPALIVE, &keepalive) >= 0; 605 debug_valid = ioctl (fd, SERIAL_GETDEBUG, &debug) >= 0; 606 port_valid = ioctl (fd, SERIAL_GETPORT, &port) >= 0; 607 cable_valid = ioctl (fd, SERIAL_GETCABLE, &cable) >= 0; 608 dir_valid = ioctl (fd, SERIAL_GETDIR, &dir) >= 0; 609 scrambler_valid = ioctl (fd, SERIAL_GETSCRAMBLER, &scrambler) >= 0; 610 cablen_valid = ioctl (fd, SERIAL_GETCABLEN, &cablen) >= 0; 611 rloop_valid = ioctl (fd, SERIAL_GETRLOOP, &rloop) >= 0; 612 mtu_valid = ioctl (fd, SERIAL_GETMTU, &mtu) >= 0; 613 rqlen_valid = ioctl (fd, SERIAL_GETRQLEN, &rqlen) >= 0; 614 615 printf ("%s", chan_name); 616 if (port_valid) 617 switch (port) { 618 case 0: printf (" (rs232)"); break; 619 case 1: printf (" (v35)"); break; 620 case 2: printf (" (rs530)"); break; 621 } 622 else if (cable_valid) 623 switch (cable) { 624 case 0: printf (" (rs232)"); break; 625 case 1: printf (" (v35)"); break; 626 case 2: printf (" (rs530)"); break; 627 case 3: printf (" (x21)"); break; 628 case 4: printf (" (rs485)"); break; 629 case 9: printf (" (no cable)"); break; 630 } 631 if (debug_valid && debug) 632 printf (" debug=%d", debug); 633 if (protocol_valid && *protocol) 634 printf (" %.8s", protocol); 635 else 636 printf (" idle"); 637 if (cablen_valid) 638 printf (" cablen=%s", cablen ? "on" : "off"); 639 if (keepalive_valid) 640 printf (" keepalive=%s", keepalive ? "on" : "off"); 641 642 if (cfg_valid) 643 switch (cfg) { 644 case 'a' : printf (" cfg=A"); break; 645 case 'b' : printf (" cfg=B"); break; 646 case 'c' : printf (" cfg=C"); break; 647 case 'd' : printf (" cfg=D"); break; 648 default : printf (" cfg=unknown"); 649 } 650 if (dir_valid) 651 printf (" dir=%d", dir); 652 653 if (baud_valid) { 654 if (baud) 655 printf (" %ld", baud); 656 else 657 printf (" extclock"); 658 } 659 if (mtu_valid) 660 printf (" mtu=%d", mtu); 661 662 if (aflag && rqlen_valid) 663 printf (" rqlen=%d", rqlen); 664 665 if (clk_valid) 666 switch (clk) { 667 case E1CLK_INTERNAL: printf (" syn=int"); break; 668 case E1CLK_RECEIVE: printf (" syn=rcv"); break; 669 case E1CLK_RECEIVE_CHAN0: printf (" syn=rcv0"); break; 670 case E1CLK_RECEIVE_CHAN1: printf (" syn=rcv1"); break; 671 case E1CLK_RECEIVE_CHAN2: printf (" syn=rcv2"); break; 672 case E1CLK_RECEIVE_CHAN3: printf (" syn=rcv3"); break; 673 default: printf (" syn=%d", clk); break; 674 } 675 676 if (dpll_valid) 677 printf (" dpll=%s", dpll ? "on" : "off"); 678 if (nrzi_valid) 679 printf (" nrzi=%s", nrzi ? "on" : "off"); 680 if (invclk_valid) 681 printf (" invclk=%s", invclk ? "on" : "off"); 682 if (invrclk_valid) 683 printf (" invrclk=%s", invrclk ? "on" : "off"); 684 if (invtclk_valid) 685 printf (" invtclk=%s", invtclk ? "on" : "off"); 686 if (unfram_valid) 687 printf (" unfram=%s", unfram ? "on" : "off"); 688 if (use16_valid) 689 printf (" use16=%s", use16 ? "on" : "off"); 690 if (aflag) { 691 if (crc4_valid) 692 printf (" crc4=%s", crc4 ? "on" : "off"); 693 if (higain_valid) 694 printf (" higain=%s", higain ? "on" : "off"); 695 if (monitor_valid) 696 printf (" monitor=%s", monitor ? "on" : "off"); 697 if (phony_valid) 698 printf (" phony=%s", phony ? "on" : "off"); 699 if (scrambler_valid) 700 printf (" scrambler=%s", scrambler ? "on" : "off"); 701 if (loop_valid) 702 printf (" loop=%s", loop ? "on" : "off"); 703 if (rloop_valid) 704 printf (" rloop=%s", rloop ? "on" : "off"); 705 if (ami_valid) 706 printf (" ami=%s", ami ? "on" : "off"); 707 } 708 if (timeslots_valid) 709 printf (" ts=%s", format_timeslots (timeslots)); 710 if (subchan_valid) 711 printf (" pass=%s", format_timeslots (subchan)); 712 if (level_valid) 713 printf (" (level=-%.1fdB)", level / 10.0); 714 printf ("\n"); 715} 716 717static void 718setup_chan (int fd, int argc, char **argv) 719{ 720 int i, mode, loop, nrzi, dpll, invclk, phony, use16, crc4, unfram, ami; 721 int higain, clk, keepalive, debug, port, dlci, invrclk, invtclk; 722 int monitor, dir, scrambler, rloop, cablen; 723 long baud, timeslots, mtu, rqlen; 724 725 for (i=0; i<argc; ++i) { 726 if (argv[i][0] >= '0' && argv[i][0] <= '9') { 727 baud = strtol (argv[i], 0, 10); 728 ioctl (fd, SERIAL_SETBAUD, &baud); 729 } else if (strcasecmp ("extclock", argv[i]) == 0) { 730 baud = 0; 731 ioctl (fd, SERIAL_SETBAUD, &baud); 732 } else if (strncasecmp ("cfg=", argv[i], 4) == 0) { 733 if (strncasecmp ("a", argv[i]+4, 1) == 0) 734 ioctl (fd, SERIAL_SETCFG, "a"); 735 else if (strncasecmp ("b", argv[i]+4, 1) == 0) 736 ioctl (fd, SERIAL_SETCFG, "b"); 737 else if (strncasecmp ("c", argv[i]+4, 1) == 0) 738 ioctl (fd, SERIAL_SETCFG, "c"); 739 else if (strncasecmp ("d", argv[i]+4, 1) == 0) 740 ioctl (fd, SERIAL_SETCFG, "d"); 741 else { 742 fprintf (stderr, "invalid cfg\n"); 743 exit (-1); 744 } 745 } else if (strcasecmp ("idle", argv[i]) == 0) 746 ioctl (fd, SERIAL_SETPROTO, "\0\0\0\0\0\0\0"); 747 else if (strcasecmp ("async", argv[i]) == 0) { 748 mode = SERIAL_ASYNC; 749 if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0) 750 ioctl (fd, SERIAL_SETPROTO, "async\0\0"); 751 } else if (strcasecmp ("sync", argv[i]) == 0) { 752 mode = SERIAL_HDLC; 753 if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0) 754 ioctl (fd, SERIAL_SETPROTO, "sync\0\0\0"); 755 } else if (strcasecmp ("cisco", argv[i]) == 0) { 756 mode = SERIAL_HDLC; 757 ioctl (fd, SERIAL_SETMODE, &mode); 758 ioctl (fd, SERIAL_SETPROTO, "cisco\0\0"); 759 } else if (strcasecmp ("rbrg", argv[i]) == 0) { 760 mode = SERIAL_HDLC; 761 ioctl (fd, SERIAL_SETMODE, &mode); 762 ioctl (fd, SERIAL_SETPROTO, "rbrg\0\0\0"); 763 } else if (strcasecmp ("raw", argv[i]) == 0) { 764 mode = SERIAL_HDLC; 765 ioctl (fd, SERIAL_SETMODE, &mode); 766 ioctl (fd, SERIAL_SETPROTO, "raw\0\0\0\0"); 767 } else if (strcasecmp ("packet", argv[i]) == 0) { 768 mode = SERIAL_HDLC; 769 ioctl (fd, SERIAL_SETMODE, &mode); 770 ioctl (fd, SERIAL_SETPROTO, "packet\0"); 771 } else if (strcasecmp ("ppp", argv[i]) == 0) { 772 /* check that ppp line discipline is present */ 773 if (ppp_ok ()) { 774 mode = SERIAL_HDLC; 775 ioctl (fd, SERIAL_SETMODE, &mode); 776 ioctl (fd, SERIAL_SETPROTO, "ppp\0\0\0\0"); 777 } 778 } else if (strncasecmp ("keepalive=", argv[i], 10) == 0) { 779 keepalive = (strcasecmp ("on", argv[i] + 10) == 0); 780 ioctl (fd, SERIAL_SETKEEPALIVE, &keepalive); 781 } else if (strcasecmp ("fr", argv[i]) == 0) { 782 mode = SERIAL_HDLC; 783 ioctl (fd, SERIAL_SETMODE, &mode); 784 ioctl (fd, SERIAL_SETPROTO, "fr\0\0\0\0\0"); 785 } else if (strcasecmp ("zaptel", argv[i]) == 0) { 786 mode = SERIAL_HDLC; 787 ioctl (fd, SERIAL_SETMODE, &mode); 788 ioctl (fd, SERIAL_SETPROTO, "zaptel\0"); 789 } else if (strncasecmp ("debug=", argv[i], 6) == 0) { 790 debug = strtol (argv[i]+6, 0, 10); 791 ioctl (fd, SERIAL_SETDEBUG, &debug); 792 } else if (strncasecmp ("loop=", argv[i], 5) == 0) { 793 loop = (strcasecmp ("on", argv[i] + 5) == 0); 794 ioctl (fd, SERIAL_SETLOOP, &loop); 795 } else if (strncasecmp ("rloop=", argv[i], 6) == 0) { 796 rloop = (strcasecmp ("on", argv[i] + 6) == 0); 797 ioctl (fd, SERIAL_SETRLOOP, &rloop); 798 } else if (strncasecmp ("dpll=", argv[i], 5) == 0) { 799 dpll = (strcasecmp ("on", argv[i] + 5) == 0); 800 ioctl (fd, SERIAL_SETDPLL, &dpll); 801 } else if (strncasecmp ("nrzi=", argv[i], 5) == 0) { 802 nrzi = (strcasecmp ("on", argv[i] + 5) == 0); 803 ioctl (fd, SERIAL_SETNRZI, &nrzi); 804 } else if (strncasecmp ("invclk=", argv[i], 7) == 0) { 805 invclk = (strcasecmp ("on", argv[i] + 7) == 0); 806 ioctl (fd, SERIAL_SETINVCLK, &invclk); 807 } else if (strncasecmp ("invrclk=", argv[i], 8) == 0) { 808 invrclk = (strcasecmp ("on", argv[i] + 8) == 0); 809 ioctl (fd, SERIAL_SETINVRCLK, &invrclk); 810 } else if (strncasecmp ("invtclk=", argv[i], 8) == 0) { 811 invtclk = (strcasecmp ("on", argv[i] + 8) == 0); 812 ioctl (fd, SERIAL_SETINVTCLK, &invtclk); 813 } else if (strncasecmp ("higain=", argv[i], 7) == 0) { 814 higain = (strcasecmp ("on", argv[i] + 7) == 0); 815 ioctl (fd, SERIAL_SETHIGAIN, &higain); 816 } else if (strncasecmp ("phony=", argv[i], 6) == 0) { 817 phony = (strcasecmp ("on", argv[i] + 6) == 0); 818 ioctl (fd, SERIAL_SETPHONY, &phony); 819 } else if (strncasecmp ("unfram=", argv[i], 7) == 0) { 820 unfram = (strcasecmp ("on", argv[i] + 7) == 0); 821 ioctl (fd, SERIAL_SETUNFRAM, &unfram); 822 } else if (strncasecmp ("scrambler=", argv[i], 10) == 0) { 823 scrambler = (strcasecmp ("on", argv[i] + 10) == 0); 824 ioctl (fd, SERIAL_SETSCRAMBLER, &scrambler); 825 } else if (strncasecmp ("monitor=", argv[i], 8) == 0) { 826 monitor = (strcasecmp ("on", argv[i] + 8) == 0); 827 ioctl (fd, SERIAL_SETMONITOR, &monitor); 828 } else if (strncasecmp ("use16=", argv[i], 6) == 0) { 829 use16 = (strcasecmp ("on", argv[i] + 6) == 0); 830 ioctl (fd, SERIAL_SETUSE16, &use16); 831 } else if (strncasecmp ("crc4=", argv[i], 5) == 0) { 832 crc4 = (strcasecmp ("on", argv[i] + 5) == 0); 833 ioctl (fd, SERIAL_SETCRC4, &crc4); 834 } else if (strncasecmp ("ami=", argv[i], 4) == 0) { 835 ami = (strcasecmp ("on", argv[i] + 4) == 0); 836 ioctl (fd, SERIAL_SETLCODE, &ami); 837 } else if (strncasecmp ("mtu=", argv[i], 4) == 0) { 838 mtu = strtol (argv[i] + 4, 0, 10); 839 ioctl (fd, SERIAL_SETMTU, &mtu); 840 } else if (strncasecmp ("rqlen=", argv[i], 6) == 0) { 841 rqlen = strtol (argv[i] + 6, 0, 10); 842 ioctl (fd, SERIAL_SETRQLEN, &rqlen); 843 } else if (strcasecmp ("syn=int", argv[i]) == 0) { 844 clk = E1CLK_INTERNAL; 845 ioctl (fd, SERIAL_SETCLK, &clk); 846 } else if (strcasecmp ("syn=rcv", argv[i]) == 0) { 847 clk = E1CLK_RECEIVE; 848 ioctl (fd, SERIAL_SETCLK, &clk); 849 } else if (strcasecmp ("syn=rcv0", argv[i]) == 0) { 850 clk = E1CLK_RECEIVE_CHAN0; 851 ioctl (fd, SERIAL_SETCLK, &clk); 852 } else if (strcasecmp ("syn=rcv1", argv[i]) == 0) { 853 clk = E1CLK_RECEIVE_CHAN1; 854 ioctl (fd, SERIAL_SETCLK, &clk); 855 } else if (strcasecmp ("syn=rcv2", argv[i]) == 0) { 856 clk = E1CLK_RECEIVE_CHAN2; 857 ioctl (fd, SERIAL_SETCLK, &clk); 858 } else if (strcasecmp ("syn=rcv3", argv[i]) == 0) { 859 clk = E1CLK_RECEIVE_CHAN3; 860 ioctl (fd, SERIAL_SETCLK, &clk); 861 } else if (strncasecmp ("ts=", argv[i], 3) == 0) { 862 timeslots = scan_timeslots (argv[i] + 3); 863 ioctl (fd, SERIAL_SETTIMESLOTS, ×lots); 864 } else if (strncasecmp ("pass=", argv[i], 5) == 0) { 865 timeslots = scan_timeslots (argv[i] + 5); 866 ioctl (fd, SERIAL_SETSUBCHAN, ×lots); 867 } else if (strncasecmp ("dlci", argv[i], 4) == 0) { 868 dlci = strtol (argv[i]+4, 0, 10); 869 ioctl (fd, SERIAL_ADDDLCI, &dlci); 870 } else if (strncasecmp ("dir=", argv[i], 4) == 0) { 871 dir = strtol (argv[i]+4, 0, 10); 872 ioctl (fd, SERIAL_SETDIR, &dir); 873 } else if (strncasecmp ("port=", argv[i], 5) == 0) { 874 if (strncasecmp ("rs232", argv[i]+5, 5) == 0) { 875 port = 0; 876 ioctl (fd, SERIAL_SETPORT, &port); 877 } else if (strncasecmp ("v35", argv[i]+5, 3) == 0) { 878 port = 1; 879 ioctl (fd, SERIAL_SETPORT, &port); 880 } else if (strncasecmp ("rs449", argv[i]+5, 5) == 0) { 881 port = 2; 882 ioctl (fd, SERIAL_SETPORT, &port); 883 } else 884 fprintf (stderr, "invalid port type\n"); 885 exit (-1); 886#if 1 887 } else if (strcasecmp ("reset", argv[i]) == 0) { 888 ioctl (fd, SERIAL_RESET, 0); 889 } else if (strcasecmp ("hwreset", argv[i]) == 0) { 890 ioctl (fd, SERIAL_HARDRESET, 0); 891#endif 892 } else if (strncasecmp ("cablen=", argv[i], 7) == 0) { 893 loop = (strcasecmp ("on", argv[i] + 7) == 0); 894 ioctl (fd, SERIAL_SETCABLEN, &cablen); 895 } 896 } 897} 898 899static void 900get_mask (void) 901{ 902#ifdef __linux__ 903 int fd; 904 905 fd = open ("/dev/serial/ctl0", 0); 906 if (fd < 0) { 907 perror ("/dev/serial/ctl0"); 908 exit (-1); 909 } 910 if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) { 911 perror ("getting list of channels"); 912 exit (-1); 913 } 914 close (fd); 915#else 916 int fd, fd1, fd2, fd3, i; 917 char buf [80]; 918 919 for (i=0, fd=-1; i<12 && fd<0; i++) { 920 sprintf (buf, "/dev/cx%d", i*4); 921 fd = open (buf, 0); 922 } 923 924 for (i=0, fd1=-1; i<3 && fd1<0; i++) { 925 sprintf (buf, "/dev/ct%d", i*2); 926 fd1 = open (buf, 0); 927 } 928 929 for (i=0, fd2=-1; i<3 && fd2<0; i++) { 930 sprintf (buf, "/dev/cp%d", i*4); 931 fd2 = open (buf, 0); 932 } 933 934 /* Try only one */ 935 for (i=0, fd3=-1; i<1 && fd3<0; i++) { 936 sprintf (buf, "/dev/ce%d", i*4); 937 fd3 = open (buf, 0); 938 } 939 940 if ((fd < 0) && (fd1 < 0) && (fd2 < 0) && (fd3 < 0)) { 941 fprintf (stderr, "No Cronyx adapters installed\n"); 942 exit (-1); 943 } 944 945 if (fd >= 0) { 946 if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) { 947 perror ("getting list of channels"); 948 exit (-1); 949 } 950 close (fd); 951 } 952 953 if (fd1 >= 0) { 954 if (ioctl (fd1, SERIAL_GETREGISTERED, (mask+16)) < 0) { 955 perror ("getting list of channels"); 956 exit (-1); 957 } 958 close (fd1); 959 } 960 961 if (fd2 >= 0) { 962 if (ioctl (fd2, SERIAL_GETREGISTERED, (mask+32)) < 0) { 963 perror ("getting list of channels"); 964 exit (-1); 965 } 966 close (fd2); 967 } 968 969 if (fd3 >= 0) { 970 if (ioctl (fd3, SERIAL_GETREGISTERED, (mask+48)) < 0) { 971 perror ("getting list of channels"); 972 exit (-1); 973 } 974 close (fd3); 975 } 976#endif 977} 978 979static int 980open_chan_ctl (int num) 981{ 982 char device [80]; 983 int fd; 984 985#ifdef __linux__ 986 sprintf (device, "/dev/serial/ctl%d", num); 987#else 988 switch (adapter_type) { 989 case 0: 990 sprintf (device, "/dev/cx%d", num); 991 break; 992 case 1: 993 sprintf (device, "/dev/ct%d", num); 994 break; 995 case 2: 996 sprintf (device, "/dev/cp%d", num); 997 break; 998 case 3: 999 sprintf (device, "/dev/ce%d", num); 1000 break; 1001 } 1002#endif 1003 fd = open (device, 0); 1004 if (fd < 0) { 1005 if (errno == ENODEV) 1006 fprintf (stderr, "chan%d: not configured\n", num); 1007 else 1008 perror (device); 1009 exit (-1); 1010 } 1011#ifdef __linux__ 1012 if (ioctl (fd, SERIAL_GETNAME, &chan_name) < 0) 1013 sprintf (chan_name, "chan%d", num); 1014#else 1015 switch (adapter_type) { 1016 case 0: sprintf (chan_name, "cx%d", num); break; 1017 case 1: sprintf (chan_name, "ct%d", num); break; 1018 case 2: sprintf (chan_name, "cp%d", num); break; 1019 case 3: sprintf (chan_name, "ce%d", num); break; 1020 } 1021#endif 1022 return fd; 1023} 1024 1025int 1026main (int argc, char **argv) 1027{ 1028 char *p; 1029 int fd, need_header, chan_num; 1030 1031 if (argc > 1 && strcmp(argv[1], "help") == 0) 1032 usage(); 1033 1034 for (;;) { 1035 switch (getopt (argc, argv, "mseftucviax")) { 1036 case EOF: 1037 break; 1038 case 'a': 1039 ++aflag; 1040 continue; 1041 case 'm': 1042 ++mflag; 1043 continue; 1044 case 's': 1045 ++sflag; 1046 continue; 1047 case 'e': 1048 ++eflag; 1049 continue; 1050 case 'f': 1051 ++eflag; 1052 ++fflag; 1053 continue; 1054 case 't': 1055 ++tflag; 1056 continue; 1057 case 'u': 1058 ++tflag; 1059 ++uflag; 1060 continue; 1061 case 'c': 1062 ++cflag; 1063 continue; 1064 case 'v': 1065 ++vflag; 1066 continue; 1067 case 'i': 1068 ++iflag; 1069 continue; 1070 case 'x': 1071 ++xflag; 1072 continue; 1073 default: 1074 usage(); 1075 } 1076 break; 1077 } 1078 argc -= optind; 1079 argv += optind; 1080 1081 if (argc <= 0) { 1082 get_mask (); 1083 need_header = 1; 1084 adapter_type = 0; 1085#ifndef __linux__ 1086 for (; adapter_type < 4; ++adapter_type) 1087#endif 1088 { 1089 for (chan_num=0; chan_num<MAXCHAN; ++chan_num) 1090 if (mask[adapter_type*16+chan_num/8] & 1 << (chan_num & 7)) { 1091 fd = open_chan_ctl (chan_num); 1092 if (vflag) { 1093#ifdef __linux__ 1094 char buf[256]; 1095 if (ioctl (fd, SERIAL_GETVERSIONSTRING, &buf) >= 0) { 1096 printf ("Version: %s\n", buf); 1097 close (fd); 1098 return (0); 1099 } 1100#endif 1101 } 1102 if (iflag) { 1103 print_chan (fd); 1104 print_ifconfig (fd); 1105 } else if (sflag||xflag) 1106 print_stats (fd, need_header); 1107 else if (mflag) 1108 print_modems (fd, need_header); 1109 else if (eflag) 1110 print_e1_stats (fd, need_header); 1111 else if (tflag) 1112 print_e3_stats (fd, need_header); 1113 else if (cflag) 1114 clear_stats (fd); 1115 else 1116 print_chan (fd); 1117 close (fd); 1118 need_header = 0; 1119 } 1120 } 1121 return (0); 1122 } 1123 1124 p = argv[0] + strlen (argv[0]); 1125 while (p > argv[0] && p[-1] >= '0' && p[-1] <= '9') 1126 --p; 1127 chan_num = strtol (p, 0, 10); 1128#ifndef __linux__ 1129 if (strncasecmp ("cx", argv[0], 2)==0) 1130 adapter_type = 0; 1131 else if (strncasecmp ("ct", argv[0], 2)==0) 1132 adapter_type = 1; 1133 else if (strncasecmp ("cp", argv[0], 2)==0) 1134 adapter_type = 2; 1135 else if (strncasecmp ("ce", argv[0], 2)==0) 1136 adapter_type = 3; 1137 else { 1138 fprintf (stderr, "Wrong channel name\n"); 1139 exit (-1); 1140 } 1141#endif 1142 argc--; 1143 argv++; 1144 1145 fd = open_chan_ctl (chan_num); 1146 if (vflag) { 1147#ifdef __linux__ 1148 char buf[256]; 1149 if (ioctl (fd, SERIAL_GETVERSIONSTRING, &buf) >= 0) 1150 printf ("Version: %s\n", buf); 1151#endif 1152 } 1153 if (iflag) { 1154 print_chan (fd); 1155 print_ifconfig (fd); 1156 close (fd); 1157 return (0); 1158 } 1159 if (sflag||xflag) { 1160 print_stats (fd, 1); 1161 close (fd); 1162 return (0); 1163 } 1164 if (mflag) { 1165 print_modems (fd, 1); 1166 close (fd); 1167 return (0); 1168 } 1169 if (eflag) { 1170 print_e1_stats (fd, 1); 1171 close (fd); 1172 return (0); 1173 } 1174 if (tflag) { 1175 print_e3_stats (fd, 1); 1176 close (fd); 1177 return (0); 1178 } 1179 if (cflag) { 1180 clear_stats (fd); 1181 close (fd); 1182 return (0); 1183 } 1184 if (argc > 0) 1185 setup_chan (fd, argc, argv); 1186 else 1187 print_chan (fd); 1188 close (fd); 1189 return (0); 1190} 1191