From 0fec2b7fb065a6020136bb0497da9bc884215345 Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Wed, 28 Oct 1998 21:08:41 +0000 Subject: [PATCH] Added code for ISDN here. 1998-10-28 Martin Baulig * ppp.c: Added code for ISDN here. --- sysdeps/linux/ChangeLog | 4 + sysdeps/linux/ppp.c | 157 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/sysdeps/linux/ChangeLog b/sysdeps/linux/ChangeLog index b5965e85..97d973a0 100644 --- a/sysdeps/linux/ChangeLog +++ b/sysdeps/linux/ChangeLog @@ -1,3 +1,7 @@ +1998-10-28 Martin Baulig + + * ppp.c: Added code for ISDN here. + 1998-10-26 Martin Baulig * netload.c: New file. Currently empty. diff --git a/sysdeps/linux/ppp.c b/sysdeps/linux/ppp.c index b81dfdb2..7c4a989b 100644 --- a/sysdeps/linux/ppp.c +++ b/sysdeps/linux/ppp.c @@ -21,9 +21,19 @@ #include #include +#include #include -static const unsigned long _glibtop_sysdeps_ppp = 0; +#include +#include +#include +#include + +#include + +static const unsigned long _glibtop_sysdeps_ppp = +(1 << GLIBTOP_PPP_STATE) + (1 << GLIBTOP_PPP_BYTES_IN) + +(1 << GLIBTOP_PPP_BYTES_OUT); /* Init function. */ @@ -33,10 +43,155 @@ glibtop_init_ppp_s (glibtop *server) server->sysdeps.ppp = _glibtop_sysdeps_ppp; } +static int +get_ISDN_stats (glibtop *server, int *in, int *out) +{ + unsigned long *isdn_stats, *ptr; + int fd, i; + + *in = *out = 0; + + isdn_stats = glibtop_calloc_r (server, ISDN_MAX_CHANNELS * 2, + sizeof (unsigned long)); + + fd = open ("/dev/isdninfo", O_RDONLY); + if (fd < 0) { + glibtop_free_r (server, isdn_stats); + return FALSE; + } + + if ((ioctl (fd, IIOCGETCPS, isdn_stats) < 0) && (errno != 0)) { + glibtop_free_r (server, isdn_stats); + close (fd); + + return FALSE; + } + + for (i = 0, ptr = isdn_stats; i < ISDN_MAX_CHANNELS; i++) { + *in += *ptr++; *out += *ptr++; + } + + glibtop_free_r (server, isdn_stats); + close (fd); + + return TRUE; +} + +static int is_ISDN_on (glibtop *server, int *online) +{ + FILE *f = 0; + char buffer [BUFSIZ], *p; + int i; + + /* Perhaps I should try to explain this code a little bit. + * + * ------------------------------------------------------------ + * This is from the manpage of isdninfo(4): + * + * DESCRIPTION + * /dev/isdninfo is a character device with major number 45 + * and minor number 255. It delivers status information from + * the Linux ISDN subsystem to user level. + * + * DATA FORMAT + * When reading from this device, the current status of the + * Linux ISDN subsystem is delivered in 6 lines of text. Each + * line starts with a tag string followed by a colon and + * whitespace. After that the status values are appended sep- + * arated by whitespace. + * + * flags is the tag of line 5. In this line for every driver + * slot, it's B-Channel status is shown. If no driver + * is registered in a slot, a ? is shown. For every + * established B-Channel of the driver, a bit is set + * in the shown value. The driver's first channel is + * mapped to bit 0, the second channel to bit 1 and so + * on. + * ------------------------------------------------------------ + * + * So we open /dev/isdninfo, discard the first four lines of text + * and then check whether we have something that is not `0' or `?' + * in one of the flags fields. + * + * Sounds complicated, but I don't see any other way to check whether + * we are connected. Also, this is the method some other ISDN tools + * for Linux use. + * + * Martin + */ + + f = fopen ("/dev/isdninfo", "r"); + + if (!f) return FALSE; + + for (i = 0; i < 5; i++) { + if (fgets (buffer, BUFSIZ, f) == NULL) { + fclose (f); + return FALSE; + } + } + + if (strncmp (buffer, "flags:", 6)) { + fclose (f); + return FALSE; + } + + p = buffer+6; + + while (*p) { + char *end = p; + + if (isspace (*p)) { + p++; + continue; + } + + for (end = p; *end && !isspace (*end); end++) + ; + + if (*end == 0) + break; + else + *end = 0; + + if (!strcmp (p, "?") || !strcmp (p, "0")) { + p = end+1; + continue; + } + + fclose (f); + + *online = TRUE; + return TRUE; + } + + fclose (f); + + *online = FALSE; + return TRUE; +} + /* Provides PPP/ISDN information. */ void glibtop_get_ppp_s (glibtop *server, glibtop_ppp *buf, unsigned short device) { + int in, out, online; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_PPP, 0); + memset (buf, 0, sizeof (glibtop_ppp)); + + if (is_ISDN_on (server, &online)) { + buf->state = online ? GLIBTOP_PPP_STATE_ONLINE : + GLIBTOP_PPP_STATE_HANGUP; + buf->flags |= (1 << GLIBTOP_PPP_STATE); + } + + if (get_ISDN_stats (server, &in, &out)) { + buf->bytes_in = in; + buf->bytes_out = out; + buf->flags |= (1 << GLIBTOP_PPP_BYTES_IN) | + (1 << GLIBTOP_PPP_BYTES_OUT); + } }