diff options
author | imp <imp@FreeBSD.org> | 2003-12-03 07:59:49 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2003-12-03 07:59:49 +0000 |
commit | e3ca591a9b130b8d9f4f5be29dc12fcdb4da84e9 (patch) | |
tree | 7cbf4cf69bf5eaacb108751ecac003db5c3c0653 /sbin/sconfig | |
parent | f9608ecffbe0e7a60bdbc3600b3093b752367925 (diff) | |
download | FreeBSD-src-e3ca591a9b130b8d9f4f5be29dc12fcdb4da84e9.zip FreeBSD-src-e3ca591a9b130b8d9f4f5be29dc12fcdb4da84e9.tar.gz |
New cx driver part 2: Commit the new userland pieces.
This is the new cronyx serial control program.
# A future commit will remove the old driver/userland pieces and connect things
# to the build.
Submitted by: Roamn Kurakin <rik@cronyx.ru>
Diffstat (limited to 'sbin/sconfig')
-rw-r--r-- | sbin/sconfig/Makefile | 13 | ||||
-rw-r--r-- | sbin/sconfig/sconfig.8 | 909 | ||||
-rw-r--r-- | sbin/sconfig/sconfig.c | 2275 |
3 files changed, 3197 insertions, 0 deletions
diff --git a/sbin/sconfig/Makefile b/sbin/sconfig/Makefile new file mode 100644 index 0000000..9643b90 --- /dev/null +++ b/sbin/sconfig/Makefile @@ -0,0 +1,13 @@ +# Cronyx Id: sbin.sconfig.Makefile,v 1.1.4.1 2003/02/17 12:51:24 rik Exp $ +# $FreeBSD$ + +PROG= sconfig +MAN= sconfig.8 + +.include <bsd.prog.mk> +# $Id: sbin.sconfig.Makefile,v 1.1.4.1 2003/02/17 12:51:24 rik Exp $ + +PROG= sconfig +MAN= sconfig.8 + +.include <bsd.prog.mk> diff --git a/sbin/sconfig/sconfig.8 b/sbin/sconfig/sconfig.8 new file mode 100644 index 0000000..9debda0 --- /dev/null +++ b/sbin/sconfig/sconfig.8 @@ -0,0 +1,909 @@ +.\" $FreeBSD$ +.Dd November 21, 2003 +.Dt SCONFIG 8 +.Os FreeBSD +.Sh NAME +.Nm sconfig +.Nd channel configuration utility for Cronyx adapters +.Sh SYNOPSIS +.Nm +.Op Fl aimsxeftuc +.Op Ar device name +.Op Ar data rate options +.Op Ar protocol options ... +.Op Ar interface options ... +.Sh DESCRIPTION +The +.Nm +utility is used for configuring the channel options of the Cronyx +adapters. In asynchronous mode all the parameters should be set by standard +.Xr stty 1 +utility, with +.Nm +you could set only few of them (see below). +.Pp +Some of the options could be set only on free channels, that is the +corresponding network interface in +.Ar down +state in the synchronous mode, and in the asynchronous mode the asynchronous +terminal device +.Pa /dev/tty* +closed. +.Pp +Other channel options could be changed +.Do on the fly +.Dc . +Generally, the channel options are set up during the operating system startup, +for example from the +.Pa /etc/rc +file. +.Pp +Note, that not all options have a sense for every particular +case, and an attempt to set some of them can hang up the channel or +the whole adapter. +.\"-------------------------------------------------------------- +.Ss "Information options" +You can specify only one of these options. If information option is specified, +sconfig will show corresponding information and will ignore all other options, +except +.Ar device name. +See also description of the +.Ar device name. +.Bl -tag -width 10n +.It <none> +This will show settings of the channel. +.It Fl a +Print all settings of the channel. +.It Fl i +Print interface settings, equal to the output of +.Xr ifconfig 1 +command. +.It Fl m +Print modem signal status. The description of all signals can be found in +any document related to the modems. Only LE signal should be described. If +this signal is On, than some what use channel. If it is Off, than channel is +free. +.It Fl s +Print brief channel statistics. This is general statistics. See also +.Fl x +, +.Fl e +, +.Fl f +, +.Fl t +and +.Fl u +options. For the description of output, see below. +.Pp +This statistics is very useful if something goes wrong. For example, if you +have no any interrupts, than you use interrupt that is not registered in BIOS +for use with ISA bus. +.It Fl x +Print full channel statistics. This options allows to see some more counters, +but with less precision than with +.Pa -s +option. +.It Fl e +Print brief E1/G703 statistics. If you select this option, you will get +statistics accumulated for period of time equal to 15 minutes. For the +description of output, see below. +.It Fl f +Print full E1/G703 statistics. This option shows all E1/G703 statistics that +shows previous option( +.Fl e +), but also total statistics for whole period of time and statistics for 24 +hours (if available). For the description of output, see below. +.It Fl t +Print brief E3/T3/STS-1 statistics. If you select this option, you will +get statistics accumulated for period of time equal to 15 minutes. For +the description of output, see below. +.It Fl u +Print full E3/T3/STS-1 statistics. This option shows all E3/T3/STS-1 +statistics that shows previous option( +.Fl t +), but also total statistics for whole period of time and statistics for 24 +hours (if available). For the description of output, see below. +.It Fl c +Cleans all kind of statistics. +.El +.\"-------------------------------------------------------------- +.Ss "Device selection" +Device is equal to the name of the interface that is used for a name of +the interface that is sees +.Nm ifconfig. +The channel number depends on the order of loading drivers by the system. +Some times people confuse channel number and adapter number because of the +same spelling. Adapter number appears in kernel context, channel number +in configuration context. +.Bl -tag -width 10n +.It <none> +You can omit device name only if you want to get information. This will cause +printing information about all available channels of Cronyx adapters. In the +case you want to make some settings you MUST specify device name. +.It cx## +This is the channel name for the Sigma family of Cronyx adapters. (ISA bus) +.It ct## +This is the channel name for the Tau family of Cronyx adapters. (ISA bus) +.It cp## +This is the channel name for the Tau-PCI family of Cronyx adapters. (PCI bus) +.It ce## +This is the channel name for the Tau32-PCI family of Cronyx adapters. (PCI bus) +.El +.\"-------------------------------------------------------------- +.Ss "Data rate options" +.Bl -tag -width 10n +.It value +If case of nonzero value it will cause setting data rate to given value and +setting the internal clock source of the synchronization (in synchronous mode). +Zero value is equal to the +.Ar extclock. +The transmitted data (TXD) are synchronized using the internal on-board timing +generator, the internally generated timing signal is driven on the TXCOUT pin, +and the signal on the TXCIN pin is ignored. This mode is used for direct +terminal-to-terminal communication, e.g. for connecting two computers together +in a synchronous mode via relatively short cable. This method should also be +used for testing channels with an external loopback connector. +.It extclock +Set the external timing clock source of synchronous channels. External clock +mode is the most common method for connecting external modem hardware. In this +mode the external timing signal is received on TXCIN pin of the connector, +and it is used as a synchronization clock for transmitting data (TXD). +.El +.\"-------------------------------------------------------------- +.Ss "Protocol options" +Note. These option could be set only if channel is free and they requires +specifying of the device name. +.Bl -tag -width 10n +.It async +Set asynchronous protocol (or mode). In this mode Cronyx adapters behave as a +usual serial devices and you may work with them using usual serial utilities. +All asynchronous settings are performed via serial configuration utilities. With +.Nm sconfig +you may set only a few of them. See also +.Xr stty 1 . +(Only for Sigma family) +.It cisco +Set the Cisco HDLC synchronous protocol. +.It fr +Set the Frame Relay synchronous protocol (ANSI T1.617 Annex D). +.It ppp +Set the PPP synchronous protocol. Parameters to the PPP could be set by the +command +.Xr spppcontrol 1 . +.It keepalive=on, keepalive=off +Turns on/off sending keepalive messages. This option is used only for +synchronous PPP. If this option is on, than PPP will periodically send +echo-request messages. If it would not receive any echo-reply messages for +some (definite) period of time it will break connection. It is used for +tracking line state. +.It idle +You are using NETGRAPH. Protocol depends on connected module. +.El +.\"-------------------------------------------------------------- +.Ss "Interface options" +Not all of these options could be set on running channel and not all of them +are suits to all kind of adapters/channels. In all dual state options off is +default value. All this options is not applicable in asynchronous mode, except +debug option. +.Bl -tag -width 10n +.It port=rs232, port=v35, port=rs449 +Set port type for old Sigma models. +.It cfg=A, cfg=B, cfg=C +Set configuration for the adapter. This option could be set only for Tau/E1 +and Tau/G703 and only if all channels are not running. +.Ar cfg=A +- Two independent E1/G703 channels. This is default setting. +.Ar cfg=B (Only for ISA models) +- For Tau/G703 this mean one G703 channel and one digital channel. +For Tau/E1 first physical channel divides on to subchannels. One of them +goes to the first logical channel and another one goes to the second physical +channel. Second (logical) channel is digital channel. +.Ar cfg=C +- This configuration is used only for E1 models. In this case first +physical channel consists of three data flows. Two of them go to two +(logical) channels. The last one goes to the second physical channel. On new +models (Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1) this configuration means single source +of synchronization and passing all unused (in both channels) timeslots from +one channel to other. For the detailed description of the configuration see +your documentation to the adapter. This option could not be set on running +channel. +.It loop=on, loop=off +Turn on/off internal loopback. This mode is useful for testing. Switch on this +option and try to send something. If you have no any interrupt, than, probably, +you forgot to switch using IRQ for PCI to ISA bus. Check your BIOS settings. +.It rloop=on, rloop=off (Only for Tau32-PCI and Tau-PCI/E3) +Turn on/off remote loopback. This mode is also useful for testing. +.It dpll=on, dpll=off +Turn on/off digital phase locked loop mode (DPLL). When enabled, the receiver +timing clock signal is derived from the received data. Must be used with NRZI +encoding, to avoid the synchronization loss. +.It nrzi=on, nrzi=off +Turn on/off nrzi encoding. In off state nrz encoding is used. NRZ - the zero +bit is transmitted by the zero signal level, the one bit - by the positive +signal level. NRZI - the bit number zero is transmitted by the change of the +signal level, the one bit - by the constant signal level. Commonly is used with +dpll=on option. +.It invclk=on, invclk=off +Invert the both transmit and receive clock signals (Tau and Tau-PCI only). +.It invrclk=on, invrclk=off +Invert the receive clock signals (Tau-PCI only). +.It invtclk=on, invtclk=off +Invert the transmit clock signals (Tau-PCI only). +.It higain=on, higain=off +Turn on/off increasing the E1 receiver non linear sensitivity to -30 dB (E1 +only). In of state the sensitivity is -12 dB. This allows increasing line +distance. +.It cablen=on, cablen=off (Only for Tau-PCI/T3 and Tau-PCI/STS-1) +Turn on/off adjusting transmit signal for long cable T3/STS-1. +.It monitor=on, monitor=off +Turn on/off increasing the E1 receiver lines sensitivity to -30 dB +(Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1 only). This could be used for interception +purposes. +.It phony=on, phony=off +Turn on/off the so-called phony mode (Tau32-PCI and Tau-PCI E1 family only). This mode allows +receiving raw CEPT frames from E1 line. Raw frames could be accessed, for +example, via raw protocol. Packets would come at rate of 500 frames per second +with length 16xN (for Tau-PCI/E1 model), where N is the number of timeslots. For +Tau-PCI/2E1 and Tau-PCI/4E1 N should be equal to 32 independently from number of +used timeslots. +.It unfram=on, unfram=off +Turn on/off unframed mode (Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1 only). +.Ar unfram=on +switches channel to unframed G.703 mode. +.Ar unfram=off +switches channel to framed E1 (G.704 mode). +.It scrambler=on, scrambler=off +Turn on/off the scrambling of G.703 data (Tau32-PCI, Tau-PCI/G.703 and Tau-PCI/2E1, +Tau-PCI/4E1 in unframed mode only). +.It use16=on, use16=off +Turn on/off the usage of 16-th timeslot for data transmission (Tau32-PCI and Tau-PCI E1 family only). +Normally 16-th timeslot is used for signaling information (multiframing CAS). +.It crc4=on, crc4=off +Turn on/off CRC4 superframe mode (E1 only). +.It syn=int, syn=rcv, syn=rcv0, syn=rcv1, syn=rcv2, sync=rcv3 +.Ar int +- use an internal clock generator for G703 transmitter +(clock master). +.Ar rcv +- use the G703 receiver data clock as the transmit clock +(clock slave). +.Ar rcv0, rcv1, rcv2, rcv3 +- use the G703 receiver clock of the other channel +(E1 models only). +.It dir=<number> +Binds logical channel to the physical channel (Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1 +only). Using this parameter you could, for example, split E1 physical channel +into several channels. +.It ts=interval +Set up the list of timeslots to use by the channel (E1 only). The +timeslots are numbered from 1 to 31, and are separated by comma or minus sign, +giving an interval. For example: "ts=1-3,5,17". +.It pass=interval +Set up the list of timeslots, translated to the E1 subchannel in cfg=B and +cfg=C configurations (Tau/E1 only). +.It debug=0, debug=1, debug=2 +Turn on/off debug messages. +.Ar 0 +- turn off debug messages. +.Ar 1 +- turn on debug +messages, equal to the +.Ar debug +option to the +.Xr ifconfig 8 +utility. +.Ar 2 +- high intensive debug message, developers only. +.El +.\"-------------------------------------------------------------- +.Sh EXAMPLES +Set up the channel 1 for use with the HDSL modem or any other +synchronous leased-line modem, and PPP/HDLC protocol (for Sigma): +.Bd -literal -offset indent +sconfig cx1 ppp extclock +ifconfig cx1 158.250.244.2 158.250.244.1 up +.Ed +.Pp +Set up the channel 0 of Tau/E1 for use with the Cisco protocol +over E1 link, with the single virtual connection. +The DLCI number is detected automatically. +Use timeslots 1-10: +.Bd -literal -offset indent +sconfig ct0 cisco ts=1-10 +ifconfig ct0 158.250.244.2 158.250.244.1 up +.Ed +.Pp +Set up the channel 0 for the synchronous null-modem link to the nearby computer, +internal clock source, 256000 bits/sec, protocol Cisco/HDLC (for Tau): +.Bd -literal -offset indent +sconfig ct0 cisco 256000 +ifconfig ct0 200.1.1.1 200.1.1.2 up +.Ed +.Pp +Set up the channel 1 for the leased line link using data-only +null-modem cable (or modems like Zelax+ M115). Synchronous DPLL mode, 128000 +bits/sec, protocol PPP/HDLC, NRZI encoding (for Sigma): +.Bd -literal -offset indent +sconfig cx1 ppp 128000 nrzi=on dpll=on +ifconfig cx1 158.250.244.2 158.250.244.1 up +.Ed +.\"-------------------------------------------------------------- +.Sh DIAGNOSTICS +This section contains description of abbreviations used by +.Nm sconfig +while displaying various statistics. For description of options connected with +statistics see above. +.\"-------------------------------------------------------------- +.Ss Statistics +When running, the driver gathers the statistics about the channels, which +could be accessed via sconfig utility or by +.Xr ioctl 2 +call +.Ar SERIAL_GETSTAT. +.Bl -tag -width 10n +.It Rintr +The total number of receive interrupts. +.It Tintr +The total number of transmit interrupts. +.It Mintr +The total number of modem interrupts. +.It Ibytes +The total bytes received. +.It Ipkts +The total packets received (for HDLC mode). +.It Ierrs +The number of receive errors. +.It Obytes +The total bytes transmitted. +.It Opkts +The total packets transmitted (for HDLC mode). +.It Oerrs The number of transmit errors. +.El +.\"-------------------------------------------------------------- +.Ss E1/G.703 Statistics +For E1 and G.703 channels the SNMP-compatible statistics data are gathered +(see RFC 1406). It could be accessed via sconfig utility or by ioctl(2) call +.Ar SERIAL_GETESTAT . +.Bl -tag -width 10n +.It Unav (uas) +Unavailable seconds - receiving all ones, or loss of carrier, or loss of +signal. +.It Degr (dm) +Degraded minutes - having error rate more than 10e-6, not counting unavailable +and severely errored seconds. +.It Bpv (bpv) +HDB3 bipolar violation errors. +.It Fsyn (fse) +Frame synchronization errors (E1 only). +.It CRC (crce) +CRC4 errors (E1). +.It RCRC (rcrce) +Remote CRC4 errors: E-bit counter (E1). +.It Err (es) +Errored seconds - any framing errors, or out of frame sync, or any slip events. +.It Lerr (les) +Line errored seconds - any BPV. +.It Sev (ses) +Severely errored seconds - 832 or more framing errors, or 2048 or more bipolar +violations. +.It Bur (bes) +Bursty errored seconds - more than 1 framing error, but not severely errored. +.It Oof (oofs) +Severely errored framing seconds - out of frame sync. +.It Slp (css) +Controlled slip second -- any slip buffer overflow or underflow. +.El +.\"-------------------------------------------------------------- +.Ss E1/G.703 Status +.Nm sconfig +utility also prints the E1/G.703 channel status. The status could have the +following values (nonexclusive): +.Bl -tag -width 10n +.It Ok +The channel is in valid state, synchronized. +.It LOS +Loss of sync. +.It AIS +Receiving unframed all ones (E1 only). +.It LOF +Loss of framing (E1 only). +.It LOMF +Loss of multiframing (E1 only). +.It FARLOF +Receiving remote alarm (E1 only). +.It AIS16 +Receiving all ones in timeslot 16 (E1 only). +.It FARLOMF +Receiving distant multiframe alarm (E1 only). +.It TSTREQ +Receiving test request code (G.703 only). +.It TSTERR +Test error (G.703 only). +.El +.\"-------------------------------------------------------------- +.Sh SEE ALSO +.Xr stty 1 +.Xr ioctl 2 +.Xr sppp 4 +.Xr spppconrol 8 +.Xr ifconfig 8 +.Xr route 8 +.\"-------------------------------------------------------------- +.Sh HISTORY +This utility is a replacement of utilities +.Nm cxconfig +and +.Nm ctconfig +that was used in past with FreeBSD drivers. Those two utilities and the present +utility are not compatible. And therefore all scripts should be rewritten. More +over, Linux and FreeBSD version of present utility not fully compatible. +.\"-------------------------------------------------------------- +.Sh BUGS +All software produced by Cronyx Engineering is thoroughly tested. But +as created by the man it can contain some +.So +BUGS +.Sc . +If you have caught one, try to localize it and send a letter with description +of this bug and all operation that you have done. We will try to reproduce +an error and fix it. +.\"-------------------------------------------------------------- +.Sh CONTACT +E-mail: info@cronyx.ru +.Pp +http://www.cronyx.ru +.Dd November 21, 2003 +.Dt SCONFIG 8 +.Os FreeBSD +.Sh NAME +.Nm sconfig +.Nd channel configuration utility for Cronyx adapters +.Sh SYNOPSIS +.Nm +.Op Fl aimsxeftuc +.Op Ar device name +.Op Ar data rate options +.Op Ar protocol options ... +.Op Ar interface options ... +.Sh DESCRIPTION +The +.Nm +utility is used for configuring the channel options of the Cronyx +adapters. In asynchronous mode all the parameters should be set by standard +.Xr stty 1 +utility, with +.Nm +you could set only few of them (see below). +.Pp +Some of the options could be set only on free channels, that is the +corresponding network interface in +.Ar down +state in the synchronous mode, and in the asynchronous mode the asynchronous +terminal device +.Pa /dev/tty* +closed. +.Pp +Other channel options could be changed +.Do on the fly +.Dc . +Generally, the channel options are set up during the operating system startup, +for example from the +.Pa /etc/rc +file. +.Pp +Note, that not all options have a sense for every particular +case, and an attempt to set some of them can hang up the channel or +the whole adapter. +.\"-------------------------------------------------------------- +.Ss "Information options" +You can specify only one of these options. If information option is specified, +sconfig will show corresponding information and will ignore all other options, +except +.Ar device name. +See also description of the +.Ar device name. +.Bl -tag -width 10n +.It <none> +This will show settings of the channel. +.It Fl a +Print all settings of the channel. +.It Fl i +Print interface settings, equal to the output of +.Xr ifconfig 1 +command. +.It Fl m +Print modem signal status. The description of all signals can be found in +any document related to the modems. Only LE signal should be described. If +this signal is On, than some what use channel. If it is Off, than channel is +free. +.It Fl s +Print brief channel statistics. This is general statistics. See also +.Fl x +, +.Fl e +, +.Fl f +, +.Fl t +and +.Fl u +options. For the description of output, see below. +.Pp +This statistics is very useful if something goes wrong. For example, if you +have no any interrupts, than you use interrupt that is not registered in BIOS +for use with ISA bus. +.It Fl x +Print full channel statistics. This options allows to see some more counters, +but with less precision than with +.Pa -s +option. +.It Fl e +Print brief E1/G703 statistics. If you select this option, you will get +statistics accumulated for period of time equal to 15 minutes. For the +description of output, see below. +.It Fl f +Print full E1/G703 statistics. This option shows all E1/G703 statistics that +shows previous option( +.Fl e +), but also total statistics for whole period of time and statistics for 24 +hours (if available). For the description of output, see below. +.It Fl t +Print brief E3/T3/STS-1 statistics. If you select this option, you will +get statistics accumulated for period of time equal to 15 minutes. For +the description of output, see below. +.It Fl u +Print full E3/T3/STS-1 statistics. This option shows all E3/T3/STS-1 +statistics that shows previous option( +.Fl t +), but also total statistics for whole period of time and statistics for 24 +hours (if available). For the description of output, see below. +.It Fl c +Cleans all kind of statistics. +.El +.\"-------------------------------------------------------------- +.Ss "Device selection" +Device is equal to the name of the interface that is used for a name of +the interface that is sees +.Nm ifconfig. +The channel number depends on the order of loading drivers by the system. +Some times people confuse channel number and adapter number because of the +same spelling. Adapter number appears in kernel context, channel number +in configuration context. +.Bl -tag -width 10n +.It <none> +You can omit device name only if you want to get information. This will cause +printing information about all available channels of Cronyx adapters. In the +case you want to make some settings you MUST specify device name. +.It cx## +This is the channel name for the Sigma family of Cronyx adapters. (ISA bus) +.It ct## +This is the channel name for the Tau family of Cronyx adapters. (ISA bus) +.It cp## +This is the channel name for the Tau-PCI family of Cronyx adapters. (PCI bus) +.It ce## +This is the channel name for the Tau32-PCI family of Cronyx adapters. (PCI bus) +.El +.\"-------------------------------------------------------------- +.Ss "Data rate options" +.Bl -tag -width 10n +.It value +If case of nonzero value it will cause setting data rate to given value and +setting the internal clock source of the synchronization (in synchronous mode). +Zero value is equal to the +.Ar extclock. +The transmitted data (TXD) are synchronized using the internal on-board timing +generator, the internally generated timing signal is driven on the TXCOUT pin, +and the signal on the TXCIN pin is ignored. This mode is used for direct +terminal-to-terminal communication, e.g. for connecting two computers together +in a synchronous mode via relatively short cable. This method should also be +used for testing channels with an external loopback connector. +.It extclock +Set the external timing clock source of synchronous channels. External clock +mode is the most common method for connecting external modem hardware. In this +mode the external timing signal is received on TXCIN pin of the connector, +and it is used as a synchronization clock for transmitting data (TXD). +.El +.\"-------------------------------------------------------------- +.Ss "Protocol options" +Note. These option could be set only if channel is free and they requires +specifying of the device name. +.Bl -tag -width 10n +.It async +Set asynchronous protocol (or mode). In this mode Cronyx adapters behave as a +usual serial devices and you may work with them using usual serial utilities. +All asynchronous settings are performed via serial configuration utilities. With +.Nm sconfig +you may set only a few of them. See also +.Xr stty 1 . +(Only for Sigma family) +.It cisco +Set the Cisco HDLC synchronous protocol. +.It fr +Set the Frame Relay synchronous protocol (ANSI T1.617 Annex D). +.It ppp +Set the PPP synchronous protocol. Parameters to the PPP could be set by the +command +.Xr spppcontrol 1 . +.It keepalive=on, keepalive=off +Turns on/off sending keepalive messages. This option is used only for +synchronous PPP. If this option is on, than PPP will periodically send +echo-request messages. If it would not receive any echo-reply messages for +some (definite) period of time it will break connection. It is used for +tracking line state. +.It idle +You are using NETGRAPH. Protocol depends on connected module. +.El +.\"-------------------------------------------------------------- +.Ss "Interface options" +Not all of these options could be set on running channel and not all of them +are suits to all kind of adapters/channels. In all dual state options off is +default value. All this options is not applicable in asynchronous mode, except +debug option. +.Bl -tag -width 10n +.It port=rs232, port=v35, port=rs449 +Set port type for old Sigma models. +.It cfg=A, cfg=B, cfg=C +Set configuration for the adapter. This option could be set only for Tau/E1 +and Tau/G703 and only if all channels are not running. +.Ar cfg=A +- Two independent E1/G703 channels. This is default setting. +.Ar cfg=B (Only for ISA models) +- For Tau/G703 this mean one G703 channel and one digital channel. +For Tau/E1 first physical channel divides on to subchannels. One of them +goes to the first logical channel and another one goes to the second physical +channel. Second (logical) channel is digital channel. +.Ar cfg=C +- This configuration is used only for E1 models. In this case first +physical channel consists of three data flows. Two of them go to two +(logical) channels. The last one goes to the second physical channel. On new +models (Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1) this configuration means single source +of synchronization and passing all unused (in both channels) timeslots from +one channel to other. For the detailed description of the configuration see +your documentation to the adapter. This option could not be set on running +channel. +.It loop=on, loop=off +Turn on/off internal loopback. This mode is useful for testing. Switch on this +option and try to send something. If you have no any interrupt, than, probably, +you forgot to switch using IRQ for PCI to ISA bus. Check your BIOS settings. +.It rloop=on, rloop=off (Only for Tau32-PCI and Tau-PCI/E3) +Turn on/off remote loopback. This mode is also useful for testing. +.It dpll=on, dpll=off +Turn on/off digital phase locked loop mode (DPLL). When enabled, the receiver +timing clock signal is derived from the received data. Must be used with NRZI +encoding, to avoid the synchronization loss. +.It nrzi=on, nrzi=off +Turn on/off nrzi encoding. In off state nrz encoding is used. NRZ - the zero +bit is transmitted by the zero signal level, the one bit - by the positive +signal level. NRZI - the bit number zero is transmitted by the change of the +signal level, the one bit - by the constant signal level. Commonly is used with +dpll=on option. +.It invclk=on, invclk=off +Invert the both transmit and receive clock signals (Tau and Tau-PCI only). +.It invrclk=on, invrclk=off +Invert the receive clock signals (Tau-PCI only). +.It invtclk=on, invtclk=off +Invert the transmit clock signals (Tau-PCI only). +.It higain=on, higain=off +Turn on/off increasing the E1 receiver non linear sensitivity to -30 dB (E1 +only). In of state the sensitivity is -12 dB. This allows increasing line +distance. +.It cablen=on, cablen=off (Only for Tau-PCI/T3 and Tau-PCI/STS-1) +Turn on/off adjusting transmit signal for long cable T3/STS-1. +.It monitor=on, monitor=off +Turn on/off increasing the E1 receiver lines sensitivity to -30 dB +(Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1 only). This could be used for interception +purposes. +.It phony=on, phony=off +Turn on/off the so-called phony mode (Tau32-PCI and Tau-PCI E1 family only). This mode allows +receiving raw CEPT frames from E1 line. Raw frames could be accessed, for +example, via raw protocol. Packets would come at rate of 500 frames per second +with length 16xN (for Tau-PCI/E1 model), where N is the number of timeslots. For +Tau-PCI/2E1 and Tau-PCI/4E1 N should be equal to 32 independently from number of +used timeslots. +.It unfram=on, unfram=off +Turn on/off unframed mode (Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1 only). +.Ar unfram=on +switches channel to unframed G.703 mode. +.Ar unfram=off +switches channel to framed E1 (G.704 mode). +.It scrambler=on, scrambler=off +Turn on/off the scrambling of G.703 data (Tau32-PCI, Tau-PCI/G.703 and Tau-PCI/2E1, +Tau-PCI/4E1 in unframed mode only). +.It use16=on, use16=off +Turn on/off the usage of 16-th timeslot for data transmission (Tau32-PCI and Tau-PCI E1 family only). +Normally 16-th timeslot is used for signaling information (multiframing CAS). +.It crc4=on, crc4=off +Turn on/off CRC4 superframe mode (E1 only). +.It syn=int, syn=rcv, syn=rcv0, syn=rcv1, syn=rcv2, sync=rcv3 +.Ar int +- use an internal clock generator for G703 transmitter +(clock master). +.Ar rcv +- use the G703 receiver data clock as the transmit clock +(clock slave). +.Ar rcv0, rcv1, rcv2, rcv3 +- use the G703 receiver clock of the other channel +(E1 models only). +.It dir=<number> +Binds logical channel to the physical channel (Tau32-PCI, Tau-PCI/2E1 and Tau-PCI/4E1 +only). Using this parameter you could, for example, split E1 physical channel +into several channels. +.It ts=interval +Set up the list of timeslots to use by the channel (E1 only). The +timeslots are numbered from 1 to 31, and are separated by comma or minus sign, +giving an interval. For example: "ts=1-3,5,17". +.It pass=interval +Set up the list of timeslots, translated to the E1 subchannel in cfg=B and +cfg=C configurations (Tau/E1 only). +.It debug=0, debug=1, debug=2 +Turn on/off debug messages. +.Ar 0 +- turn off debug messages. +.Ar 1 +- turn on debug +messages, equal to the +.Ar debug +option to the +.Xr ifconfig 8 +utility. +.Ar 2 +- high intensive debug message, developers only. +.El +.\"-------------------------------------------------------------- +.Sh EXAMPLES +Set up the channel 1 for use with the HDSL modem or any other +synchronous leased-line modem, and PPP/HDLC protocol (for Sigma): +.Bd -literal -offset indent +sconfig cx1 ppp extclock +ifconfig cx1 158.250.244.2 158.250.244.1 up +.Ed +.Pp +Set up the channel 0 of Tau/E1 for use with the Cisco protocol +over E1 link, with the single virtual connection. +The DLCI number is detected automatically. +Use timeslots 1-10: +.Bd -literal -offset indent +sconfig ct0 cisco ts=1-10 +ifconfig ct0 158.250.244.2 158.250.244.1 up +.Ed +.Pp +Set up the channel 0 for the synchronous null-modem link to the nearby computer, +internal clock source, 256000 bits/sec, protocol Cisco/HDLC (for Tau): +.Bd -literal -offset indent +sconfig ct0 cisco 256000 +ifconfig ct0 200.1.1.1 200.1.1.2 up +.Ed +.Pp +Set up the channel 1 for the leased line link using data-only +null-modem cable (or modems like Zelax+ M115). Synchronous DPLL mode, 128000 +bits/sec, protocol PPP/HDLC, NRZI encoding (for Sigma): +.Bd -literal -offset indent +sconfig cx1 ppp 128000 nrzi=on dpll=on +ifconfig cx1 158.250.244.2 158.250.244.1 up +.Ed +.\"-------------------------------------------------------------- +.Sh DIAGNOSTICS +This section contains description of abbreviations used by +.Nm sconfig +while displaying various statistics. For description of options connected with +statistics see above. +.\"-------------------------------------------------------------- +.Ss Statistics +When running, the driver gathers the statistics about the channels, which +could be accessed via sconfig utility or by +.Xr ioctl 2 +call +.Ar SERIAL_GETSTAT. +.Bl -tag -width 10n +.It Rintr +The total number of receive interrupts. +.It Tintr +The total number of transmit interrupts. +.It Mintr +The total number of modem interrupts. +.It Ibytes +The total bytes received. +.It Ipkts +The total packets received (for HDLC mode). +.It Ierrs +The number of receive errors. +.It Obytes +The total bytes transmitted. +.It Opkts +The total packets transmitted (for HDLC mode). +.It Oerrs The number of transmit errors. +.El +.\"-------------------------------------------------------------- +.Ss E1/G.703 Statistics +For E1 and G.703 channels the SNMP-compatible statistics data are gathered +(see RFC 1406). It could be accessed via sconfig utility or by ioctl(2) call +.Ar SERIAL_GETESTAT . +.Bl -tag -width 10n +.It Unav (uas) +Unavailable seconds - receiving all ones, or loss of carrier, or loss of +signal. +.It Degr (dm) +Degraded minutes - having error rate more than 10e-6, not counting unavailable +and severely errored seconds. +.It Bpv (bpv) +HDB3 bipolar violation errors. +.It Fsyn (fse) +Frame synchronization errors (E1 only). +.It CRC (crce) +CRC4 errors (E1). +.It RCRC (rcrce) +Remote CRC4 errors: E-bit counter (E1). +.It Err (es) +Errored seconds - any framing errors, or out of frame sync, or any slip events. +.It Lerr (les) +Line errored seconds - any BPV. +.It Sev (ses) +Severely errored seconds - 832 or more framing errors, or 2048 or more bipolar +violations. +.It Bur (bes) +Bursty errored seconds - more than 1 framing error, but not severely errored. +.It Oof (oofs) +Severely errored framing seconds - out of frame sync. +.It Slp (css) +Controlled slip second -- any slip buffer overflow or underflow. +.El +.\"-------------------------------------------------------------- +.Ss E1/G.703 Status +.Nm sconfig +utility also prints the E1/G.703 channel status. The status could have the +following values (nonexclusive): +.Bl -tag -width 10n +.It Ok +The channel is in valid state, synchronized. +.It LOS +Loss of sync. +.It AIS +Receiving unframed all ones (E1 only). +.It LOF +Loss of framing (E1 only). +.It LOMF +Loss of multiframing (E1 only). +.It FARLOF +Receiving remote alarm (E1 only). +.It AIS16 +Receiving all ones in timeslot 16 (E1 only). +.It FARLOMF +Receiving distant multiframe alarm (E1 only). +.It TSTREQ +Receiving test request code (G.703 only). +.It TSTERR +Test error (G.703 only). +.El +.\"-------------------------------------------------------------- +.Sh SEE ALSO +.Xr stty 1 +.Xr ioctl 2 +.Xr sppp 4 +.Xr spppconrol 8 +.Xr ifconfig 8 +.Xr route 8 +.\"-------------------------------------------------------------- +.Sh HISTORY +This utility is a replacement of utilities +.Nm cxconfig +and +.Nm ctconfig +that was used in past with FreeBSD drivers. Those two utilities and the present +utility are not compatible. And therefore all scripts should be rewritten. More +over, Linux and FreeBSD version of present utility not fully compatible. +.\"-------------------------------------------------------------- +.Sh BUGS +All software produced by Cronyx Engineering is thoroughly tested. But +as created by the man it can contain some +.So +BUGS +.Sc . +If you have caught one, try to localize it and send a letter with description +of this bug and all operation that you have done. We will try to reproduce +an error and fix it. +.\"-------------------------------------------------------------- +.Sh CONTACT +E-mail: info@cronyx.ru +.Pp +http://www.cronyx.ru diff --git a/sbin/sconfig/sconfig.c b/sbin/sconfig/sconfig.c new file mode 100644 index 0000000..4f8125c --- /dev/null +++ b/sbin/sconfig/sconfig.c @@ -0,0 +1,2275 @@ +/* + * Channel configuration utility for Cronyx serial adapters. + * + * Copyright (C) 1997-2002 Cronyx Engineering. + * Author: Serge Vakulenko, <vak@cronyx.ru> + * + * Copyright (C) 1999-2003 Cronyx Engineering. + * Author: Roman Kurakin, <rik@cronyx.ru> + * + * 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.2.2.4 2003/06/20 16:20:48 rik Exp $ + * $FreeBSD$ + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <ctype.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <net/if.h> +#include <machine/cserial.h> + +#define MAXCHAN 128 + +int vflag, eflag, sflag, mflag, cflag, fflag, iflag, aflag, xflag; +int tflag, uflag; +char mask[48]; +int adapter_type; /* 0-sigma, 1-tau, 2-tau */ +char chan_name[16]; + +extern char *optarg; +extern int optind; + +static void +usage (void) +{ + printf( +"Serial Adapter Configuration Utility\n" +"Copyright (C) 1998-1999 Cronyx Engineering Ltd.\n" +"See also man sconfig (8)\n" +"Usage:\n" +"\tsconfig [-aimsxeftuc] [device [parameters ...]]\n" +"\n" +"Options:\n" +"\t<no options>\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<number>\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<number>\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" +"\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=<num>\t\t -- connect channel to link<num>\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<v; ++i) + ts |= 1L << i; + ts |= 1L << v; + + lastv = 0; + s = e; + } + return ts; +} + +static int +ppp_ok (void) +{ +#ifdef __linux__ + int s, p; + struct ifreq ifr; + char pttyname[32]; + char *p1, *p2; + int i, j; + int ppp_disc = N_PPP; + + /* + * Open a socket for doing the ioctl operations. + */ + s = socket (AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + fprintf (stderr, "Error opening socket.\n"); + return 0; + } + strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + if (ioctl (s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 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 +print_ifconfig (int fd) +{ + 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 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 & 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_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<maxi; ++i) { + printf (" "); + print_frac (0, st.interval[i].uas, 15*60); + print_frac (1, 60 * st.interval[i].dm, 15*60); + + print_frac (0, st.interval[i].bpv, 15*60); + print_frac (1, st.interval[i].fse, 15*60); + + print_frac (0, st.interval[i].crce, 15*60); + print_frac (1, st.interval[i].rcrce, 15*60); + + print_frac (0, st.interval[i].es, 15*60); + print_frac (1, st.interval[i].les, 15*60); + + print_frac (0, st.interval[i].ses, 15*60); + print_frac (1, st.interval[i].bes, 15*60); + + print_frac (0, st.interval[i].oofs, 15*60); + print_frac (1, st.interval[i].css, 15*60); + + if (i < 3) + printf (" -- %dm\n", (i+1)*15); + else + printf (" -- %dh %dm\n", (i+1)/4, (i+1)%4*15); + } + } +} + +static char * +format_e3_status (unsigned long status) +{ + static char buf [80]; + + buf[0] = 0; + if (status & E3_LOS) strcat (buf, ",LOS"); + if (status & E3_TXE) strcat (buf, ",XMIT"); + if (buf[0] == ',') + return buf+1; + return "Ok"; +} + +static char * +format_e3_cv (unsigned long cv, unsigned long baud, unsigned long time) +{ + static char buf[80]; + + if (!cv || !baud || !time) + sprintf (buf, " - "); + else + sprintf (buf, "%10lu (%.1e)", cv, (double)cv/baud/time); + return buf; +} + +static void +print_e3_stats (int fd, int need_header) +{ + struct e3_statistics st; + int i, maxi; + long baud; + + if (need_header) + printf ("Chan\t--Code Violations---\t\t\t\t\t ----Status----\n"); + + if (ioctl (fd, SERIAL_GETE3STAT, &st) < 0 || + ioctl (fd, SERIAL_GETBAUD, &baud) < 0) + return; + + if (!st.cursec) + st.cursec = 1; + + printf ("%s\t%s\t\t\t\t\t", chan_name, + format_e3_cv (st.ccv, baud, st.cursec)); + + printf (" %s\n", format_e3_status (st.status)); + + + if (uflag) { + /* Print total statistics. */ + printf ("\t%s\t\t\t\t\t", + format_e3_cv (st.tcv, baud, st.totsec)); + printf (" -- Total\n"); + + /* Print 24-hour history. */ + maxi = (st.totsec - st.cursec) / 900; + if (maxi > 48) + maxi = 48; + for (i=0; i<maxi; ++i) { + printf ("\t%s\t\t\t\t\t", + format_e3_cv (st.icv[i], baud, 15*60)); + if (i < 3) + printf (" -- %2dm\n", (i+1)*15); + else + printf (" -- %2dh %2dm\n", (i+1)/4, (i+1)%4*15); + } + } +} + +static void +print_chan (int fd) +{ + char protocol [8]; + char cfg; + int loop, dpll, nrzi, invclk, clk, higain, phony, use16, crc4; + int level, keepalive, debug, port, invrclk, invtclk, unfram, monitor; + int cable, dir, scrambler; + int cablen, rloop; + long baud, timeslots, subchan; + int protocol_valid, baud_valid, loop_valid, use16_valid, crc4_valid; + int dpll_valid, nrzi_valid, invclk_valid, clk_valid, phony_valid; + int timeslots_valid, subchan_valid, higain_valid, level_valid; + int keepalive_valid, debug_valid, cfg_valid, port_valid; + int invrclk_valid, invtclk_valid, unfram_valid, monitor_valid; + int cable_valid, dir_valid, scrambler_valid; + int cablen_valid, rloop_valid; + + protocol_valid = ioctl (fd, SERIAL_GETPROTO, &protocol) >= 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; + 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; + + 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 (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 (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; + int higain, clk, keepalive, debug, port, dlci, invrclk, invtclk; + int monitor, dir, scrambler, rloop, cablen; + long baud, timeslots; + + for (i=0; i<argc; ++i) { + if (argv[i][0] >= '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"); + } 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\0\0\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 (strncasecmp ("debug=", argv[i], 6) == 0) { + debug = strtol (argv[i]+6, 0, 10); + 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 (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, 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); + } + + if ((fd < 0) && (fd1 < 0) && (fd2 < 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); + } +#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; + } +#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; + } +#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 EOF: + 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 < 3; ++adapter_type) +#endif + { + for (chan_num=0; chan_num<MAXCHAN; ++chan_num) + if (mask[adapter_type*16+chan_num/8] & 1 << (chan_num & 7)) { + 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); + 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 { + 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); +} +/* + * Channel configuration utility for Cronyx serial adapters. + * + * Copyright (C) 1997-2002 Cronyx Engineering. + * Author: Serge Vakulenko, <vak@cronyx.ru> + * + * Copyright (C) 1999-2003 Cronyx Engineering. + * Author: Roman Kurakin, <rik@cronyx.ru> + * + * 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. + * + * $Id: sconfig.c,v 1.2.2.4 2003/06/20 16:20:48 rik Exp $ + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <ctype.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <net/if.h> +#include <machine/cserial.h> + +#define MAXCHAN 128 + +int vflag, eflag, sflag, mflag, cflag, fflag, iflag, aflag, xflag; +int tflag, uflag; +char mask[48]; +int adapter_type; /* 0-sigma, 1-tau, 2-tau */ +char chan_name[16]; + +extern char *optarg; +extern int optind; + +static void +usage (void) +{ + printf( +"Serial Adapter Configuration Utility\n" +"Copyright (C) 1998-1999 Cronyx Engineering Ltd.\n" +"See also man sconfig (8)\n" +"Usage:\n" +"\tsconfig [-aimsxeftuc] [device [parameters ...]]\n" +"\n" +"Options:\n" +"\t<no options>\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<number>\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<number>\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" +"\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=<num>\t\t -- connect channel to link<num>\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<v; ++i) + ts |= 1L << i; + ts |= 1L << v; + + lastv = 0; + s = e; + } + return ts; +} + +static int +ppp_ok (void) +{ +#ifdef __linux__ + int s, p; + struct ifreq ifr; + char pttyname[32]; + char *p1, *p2; + int i, j; + int ppp_disc = N_PPP; + + /* + * Open a socket for doing the ioctl operations. + */ + s = socket (AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + fprintf (stderr, "Error opening socket.\n"); + return 0; + } + strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + if (ioctl (s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 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 +print_ifconfig (int fd) +{ + 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 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 & 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_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<maxi; ++i) { + printf (" "); + print_frac (0, st.interval[i].uas, 15*60); + print_frac (1, 60 * st.interval[i].dm, 15*60); + + print_frac (0, st.interval[i].bpv, 15*60); + print_frac (1, st.interval[i].fse, 15*60); + + print_frac (0, st.interval[i].crce, 15*60); + print_frac (1, st.interval[i].rcrce, 15*60); + + print_frac (0, st.interval[i].es, 15*60); + print_frac (1, st.interval[i].les, 15*60); + + print_frac (0, st.interval[i].ses, 15*60); + print_frac (1, st.interval[i].bes, 15*60); + + print_frac (0, st.interval[i].oofs, 15*60); + print_frac (1, st.interval[i].css, 15*60); + + if (i < 3) + printf (" -- %dm\n", (i+1)*15); + else + printf (" -- %dh %dm\n", (i+1)/4, (i+1)%4*15); + } + } +} + +static char * +format_e3_status (unsigned long status) +{ + static char buf [80]; + + buf[0] = 0; + if (status & E3_LOS) strcat (buf, ",LOS"); + if (status & E3_TXE) strcat (buf, ",XMIT"); + if (buf[0] == ',') + return buf+1; + return "Ok"; +} + +static char * +format_e3_cv (unsigned long cv, unsigned long baud, unsigned long time) +{ + static char buf[80]; + + if (!cv || !baud || !time) + sprintf (buf, " - "); + else + sprintf (buf, "%10lu (%.1e)", cv, (double)cv/baud/time); + return buf; +} + +static void +print_e3_stats (int fd, int need_header) +{ + struct e3_statistics st; + int i, maxi; + long baud; + + if (need_header) + printf ("Chan\t--Code Violations---\t\t\t\t\t ----Status----\n"); + + if (ioctl (fd, SERIAL_GETE3STAT, &st) < 0 || + ioctl (fd, SERIAL_GETBAUD, &baud) < 0) + return; + + if (!st.cursec) + st.cursec = 1; + + printf ("%s\t%s\t\t\t\t\t", chan_name, + format_e3_cv (st.ccv, baud, st.cursec)); + + printf (" %s\n", format_e3_status (st.status)); + + + if (uflag) { + /* Print total statistics. */ + printf ("\t%s\t\t\t\t\t", + format_e3_cv (st.tcv, baud, st.totsec)); + printf (" -- Total\n"); + + /* Print 24-hour history. */ + maxi = (st.totsec - st.cursec) / 900; + if (maxi > 48) + maxi = 48; + for (i=0; i<maxi; ++i) { + printf ("\t%s\t\t\t\t\t", + format_e3_cv (st.icv[i], baud, 15*60)); + if (i < 3) + printf (" -- %2dm\n", (i+1)*15); + else + printf (" -- %2dh %2dm\n", (i+1)/4, (i+1)%4*15); + } + } +} + +static void +print_chan (int fd) +{ + char protocol [8]; + char cfg; + int loop, dpll, nrzi, invclk, clk, higain, phony, use16, crc4; + int level, keepalive, debug, port, invrclk, invtclk, unfram, monitor; + int cable, dir, scrambler; + int cablen, rloop; + long baud, timeslots, subchan; + int protocol_valid, baud_valid, loop_valid, use16_valid, crc4_valid; + int dpll_valid, nrzi_valid, invclk_valid, clk_valid, phony_valid; + int timeslots_valid, subchan_valid, higain_valid, level_valid; + int keepalive_valid, debug_valid, cfg_valid, port_valid; + int invrclk_valid, invtclk_valid, unfram_valid, monitor_valid; + int cable_valid, dir_valid, scrambler_valid; + int cablen_valid, rloop_valid; + + protocol_valid = ioctl (fd, SERIAL_GETPROTO, &protocol) >= 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; + 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; + + 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 (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 (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; + int higain, clk, keepalive, debug, port, dlci, invrclk, invtclk; + int monitor, dir, scrambler, rloop, cablen; + long baud, timeslots; + + for (i=0; i<argc; ++i) { + if (argv[i][0] >= '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"); + } 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\0\0\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 (strncasecmp ("debug=", argv[i], 6) == 0) { + debug = strtol (argv[i]+6, 0, 10); + 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 (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, 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); + } + + if ((fd < 0) && (fd1 < 0) && (fd2 < 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); + } +#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; + } +#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; + } +#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 EOF: + 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 < 3; ++adapter_type) +#endif + { + for (chan_num=0; chan_num<MAXCHAN; ++chan_num) + if (mask[adapter_type*16+chan_num/8] & 1 << (chan_num & 7)) { + 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); + 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 { + 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); +} |