]> git.decadent.org.uk Git - ap-utils.git/blobdiff - src/aplink.c
Imported Upstream version 1.5
[ap-utils.git] / src / aplink.c
index eb5ed3d0640c80acf462aae7c72a51ea42823a63..e3e5413133893be188995e6cbeda226c2fe2f078 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  */
-#include <sys/wait.h>
-#include <unistd.h>
 #include <stdlib.h>
-#include <fcntl.h>
-#include <signal.h>
 #include <string.h>
+#include <unistd.h>
 #include "ap-utils.h"
 
 #define S_RSSI     _("RSSI:     [")
 #define S_RSSI_AVG _("RSSI avg: [")
 #define S_RSSI_TOP _("RSSI top: [")
+#define S_RSSI_ROU _("RSSI rou: [")
+#define APLINK_HELP _("P - pause, T - toggle graph view, Q - quit to menu, Other key - force update.")
+
+#define GRWIN_LENGTH   (COLS - MCOLS - 7)
+#define GRWIN_HEIGHT    (LAST_ROW - 10)
+
+int gr_mode = 0;
 
 extern WINDOW *main_sub;
 extern short ap_type, ap_vendorext;
-extern int wait_mode, snmp_retries;
+extern int wait_mode, poll_delay;
 
 /*
  * TODO: Implement APClientInfo as alternative, for NetGear ME102 MIB
@@ -44,7 +48,7 @@ void atmel_aplink()
        0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x04, 0x01, 0x00
     };
     /*
-     * ATMEL12350 EZYNET MIB and ATMEL410 SBRIDGES MIB specific:
+     * ATMEL12350 EZYNET MIB and ATMEL410 SBRIDGES MIB specific OIDs:
      * for ATMEL410 SBRIDGES MIB: .1.3.6.1.4.1.410.1.2.8.1.0
      * for ATMEL12350 EZYNET MIB: .1.3.6.1.4.1.12350.1.2.7.4.0
      */
@@ -68,11 +72,26 @@ void atmel_aplink()
     unsigned char ESSID[32];
     unsigned long ESSLEN; /* uchar for NetworkSettings_ATMEL410_SBRIDGES */
 
+    int i, j = 0, linked = 0, samples = 0, sum = 0, rssi_perc;
+    int rssi_avg = 0, rssi_avg_perc, rssi_top = 0, rssi_top_perc;
+    int rssi_rou, rssi_rou_perc, lq_perc = 0, lq_perc_top = 0;
+    int ringbuf_pos = 0, p_wait_mode = wait_mode;
+    char ringbuf[20];
     char message[1024];
-    int i, linked = 0, rssi_perc, samples = 0, sum = 0, avg = 0, avg_perc;
-    int top = 0, top_perc;
+    char *gr_modes[5] = { _("RSSI [%]"),
+                         _("RSSI average [%]"),
+                         _("RSSI rounded [%]"),
+                         _("Link Quality [%]"),
+                         NULL };
+    WINDOW *gauge_rssi;
+    WINDOW *gauge_rssi_top;
+    WINDOW *gauge_rssi_avg;
+    WINDOW *gauge_rssi_rou;
+    WINDOW *grwin_rssi;
+    WINDOW *grwin_rssi_avg = NULL;
+    WINDOW *grwin_rssi_rou = NULL;
+    WINDOW *grwin_lq = NULL;
     varbind varbinds[1];
-    WINDOW *gauge_rssi, *gauge_rssi_avg, *gauge_rssi_top;
 
     if (ap_type == ATMEL12350) {
        bridgeOperationalMode[5] = 0xE0;
@@ -87,6 +106,8 @@ void atmel_aplink()
     gauge_rssi = derwin(main_sub, 1, 20, 2, strlen(S_RSSI));
     gauge_rssi_top = derwin(main_sub, 1, 20, 3, strlen(S_RSSI_TOP));
     gauge_rssi_avg = derwin(main_sub, 1, 20, 4, strlen(S_RSSI_AVG));
+    gauge_rssi_rou = derwin(main_sub, 1, 20, 5, strlen(S_RSSI_ROU));
+    grwin_rssi = derwin(main_sub, GRWIN_HEIGHT + 2, GRWIN_LENGTH + 2, 9, 3);
 
     /* find out mode the device is currently in */
     varbinds[0].oid = bridgeOperationalMode;
@@ -120,35 +141,86 @@ void atmel_aplink()
        goto exit;
     }
 
-    print_top(wait_mode == WAIT_TIMEOUT ? POLL_ON : POLL_OFF, AP_TITLE);
-    print_help(QT_HELP);
+    wait_mode = WAIT_TIMEOUT;
+
+    print_top(POLL_ON, AP_TITLE);
+    print_help(APLINK_HELP);
     noecho();
 
+    memset(ringbuf, 0, sizeof(ringbuf));
+
+    box(grwin_rssi, 0, 0);
+    for (i = GRWIN_HEIGHT - GRWIN_HEIGHT / 3; i > 0; i -= GRWIN_HEIGHT / 3) {
+       j += 33;
+       mvwprintw(main_sub, 9 + i, 0, "%u", j);
+       mvwaddch(grwin_rssi, i, 0, ACS_SSSS);
+    }
+    delwin(grwin_rssi);
+    wmove(main_sub, 9, 6);
+    print_bold(main_sub, gr_modes[gr_mode]);
+    grwin_rssi     = newwin(GRWIN_HEIGHT, GRWIN_LENGTH, 12, MCOLS + 4);
+    grwin_rssi_avg = newwin(GRWIN_HEIGHT, GRWIN_LENGTH, 12, MCOLS + 4);
+    grwin_rssi_rou = newwin(GRWIN_HEIGHT, GRWIN_LENGTH, 12, MCOLS + 4);
+    if (ap_type == ATMEL410)
+       grwin_lq       = newwin(GRWIN_HEIGHT, GRWIN_LENGTH, 12, MCOLS + 4);
+    wattrset(grwin_rssi,     COLOR_PAIR(COLOR_BLUE));
+    wattrset(grwin_rssi_avg, COLOR_PAIR(COLOR_BLUE));
+    wattrset(grwin_rssi_rou, COLOR_PAIR(COLOR_BLUE));
+    if (ap_type == ATMEL410)
+       wattrset(grwin_lq, COLOR_PAIR(COLOR_BLUE));
+
     while (1) {
-       /* find out how many STAtions is in the list */
+       mvwaddstr(main_sub, 0, 0, "Associated with AP: ");
+
        varbinds[0].oid = NetworkSettings;
        varbinds[0].len_oid = sizeof(NetworkSettings);
        varbinds[0].value = NetworkSettings;
        varbinds[0].type = STRING_VALUE;
        varbinds[0].len_val = 0;
 
-       if (wait_mode == WAIT_FOREVER)
-           print_help(WAIT_RET);
-
-       snmp_retries = 1;
-       mvwaddstr(main_sub, 0, 0, "Associated with AP: ");
        if (snmp(varbinds, 1, GET) <= 0) {
+           /* do just once */
            waddstr(main_sub, NO);
-           if (linked)
-               clear_main(0);
+           if (linked) {
+               linked = sum = samples = ringbuf_pos = 0;
+               memset(ringbuf, 0, sizeof(ringbuf));
+
+               wclrtoeol(main_sub);
+               clear_main_new(1, 9);
+               /* wclrtobot(main_sub); */
+
+               wattrset(grwin_rssi,     COLOR_PAIR(COLOR_RED));
+               wattrset(grwin_rssi_avg, COLOR_PAIR(COLOR_RED));
+               wattrset(grwin_rssi_rou, COLOR_PAIR(COLOR_RED));
+               if (ap_type == ATMEL410)
+                   wattrset(grwin_lq,   COLOR_PAIR(COLOR_RED));
+
+               for (i = 0; i < GRWIN_HEIGHT; i++) {
+                   mvwdelch(grwin_rssi,     i, 0);
+                   mvwdelch(grwin_rssi_avg, i, 0);
+                   mvwdelch(grwin_rssi_rou, i, 0);
+                   mvwaddch(grwin_rssi,     i, GRWIN_LENGTH - 1, ACS_SBSB);
+                   mvwaddch(grwin_rssi_avg, i, GRWIN_LENGTH - 1, ACS_SBSB);
+                   mvwaddch(grwin_rssi_rou, i, GRWIN_LENGTH - 1, ACS_SBSB);
+                   if (ap_type == ATMEL410) {
+                       mvwdelch(grwin_lq,   i, 0);
+                       mvwaddch(grwin_lq,   i, GRWIN_LENGTH - 1, ACS_SBSB);
+                   }
+               }
+               wattrset(grwin_rssi,     COLOR_PAIR(COLOR_BLUE));
+               wattrset(grwin_rssi_avg, COLOR_PAIR(COLOR_BLUE));
+               wattrset(grwin_rssi_rou, COLOR_PAIR(COLOR_BLUE));
+               if (ap_type == ATMEL410)
+                   wattrset(grwin_lq,   COLOR_PAIR(COLOR_BLUE));
+           }
 
-           wrefresh(main_sub);
-           linked = 0;
-           sum = samples = 0;
-       } else {
-           if (wait_mode == WAIT_FOREVER)
-               print_help(QT_HELP);
+           wnoutrefresh(main_sub);
+           wnoutrefresh(gr_mode == 0 ? grwin_rssi :
+                        gr_mode == 1 ? grwin_rssi_avg :
+                        gr_mode == 2 ? grwin_rssi_rou : grwin_lq);
 
+           doupdate();
+       } else {
            waddstr(main_sub, YES);
 
            if (ap_type == ATMEL410) {
@@ -192,15 +264,15 @@ void atmel_aplink()
            }
            wnoutrefresh(gauge_rssi);
            sprintf(message, "] [%4ddBm] [%3u%%] [%3u]",
-               -96 + Rssi, rssi_perc, Rssi);
+               dbmconv(Rssi), rssi_perc, Rssi);
            mvwaddstr(main_sub, 2, strlen(S_RSSI) + 20, message);
 
            mvwaddstr(main_sub, 3, 0, S_RSSI_TOP);
-           if (Rssi > top)
-               top = Rssi;
-           top_perc = (int)((minimum (top, 40)) * (float)2.5);
+           if (Rssi > rssi_top)
+               rssi_top = Rssi;
+           rssi_top_perc = (int)((minimum (rssi_top, 40)) * (float)2.5);
            werase(gauge_rssi_top);
-           for (i = 0; i < (20 * top_perc / 100); i++) {
+           for (i = 0; i < (20 * rssi_top_perc / 100); i++) {
                if (i == 0)
                    wattrset(gauge_rssi_top, COLOR_PAIR(COLOR_RED));
                if (i == 7)
@@ -211,19 +283,19 @@ void atmel_aplink()
            }
            wnoutrefresh(gauge_rssi_top);
            sprintf(message, "] [%4ddBm] [%3u%%] [%3u]",
-               -96 + top, top_perc, top);
+               dbmconv(rssi_top), rssi_top_perc, rssi_top);
            mvwaddstr(main_sub, 3, strlen(S_RSSI_TOP) + 20, message);
 
            mvwaddstr(main_sub, 4, 0, S_RSSI_AVG);
            sum += Rssi;
-           avg = sum / ++samples;
+           rssi_avg = sum / ++samples;
            if (samples == 100000) {
                samples = 1;
                sum = Rssi;
            }
-           avg_perc = (int)((minimum (avg, 40)) * (float)2.5);
+           rssi_avg_perc = (int)((minimum (rssi_avg, 40)) * (float)2.5);
            werase(gauge_rssi_avg);
-           for (i = 0; i < (20 * avg_perc / 100); i++) {
+           for (i = 0; i < (20 * rssi_avg_perc / 100); i++) {
                if (i == 0)
                    wattrset(gauge_rssi_avg, COLOR_PAIR(COLOR_RED));
                if (i == 7)
@@ -234,12 +306,38 @@ void atmel_aplink()
            }
            wnoutrefresh(gauge_rssi_avg);
            sprintf(message, "] [%4ddBm] [%3u%%] / %5u sampl.",
-               -96 + avg, avg_perc, samples);
+               dbmconv(rssi_avg), rssi_avg_perc, samples);
            mvwaddstr(main_sub, 4, strlen(S_RSSI_AVG) + 20, message);
 
+           mvwaddstr(main_sub, 5, 0, S_RSSI_ROU);
+           ringbuf[ringbuf_pos++] = Rssi;
+           if (ringbuf_pos == sizeof(ringbuf))
+               ringbuf_pos = 0;
+           rssi_rou = 0;
+           for (i = 0; i < (int)sizeof(ringbuf); rssi_rou += ringbuf[i], i++);
+           rssi_rou /= sizeof(ringbuf);
+           rssi_rou_perc = (int)((minimum (rssi_rou, 40)) * (float)2.5);
+           werase(gauge_rssi_rou);
+           for (i = 0; i < (20 * rssi_rou_perc / 100); i++) {
+               if (i == 0)
+                   wattrset(gauge_rssi_rou, COLOR_PAIR(COLOR_RED));
+               if (i == 7)
+                   wattrset(gauge_rssi_rou, COLOR_PAIR(COLOR_YELLOW) | A_BOLD);
+               if (i == 14)
+                   wattrset(gauge_rssi_rou, COLOR_PAIR(COLOR_GREEN));
+               waddch(gauge_rssi_rou, ACS_BLOCK);
+           }
+           wnoutrefresh(gauge_rssi_rou);
+           sprintf(message, "] [%4ddBm] [%3u%%] / last %2u sam.",
+               dbmconv(rssi_rou), rssi_rou_perc, sizeof(ringbuf));
+           mvwaddstr(main_sub, 5, strlen(S_RSSI_ROU) + 20, message);
+
            if (ap_type == ATMEL410) {
-               sprintf(message, "Link quality: %3u%%",
-                   (int)(100 - (minimum (LQCR, 40)) * (float)2.5));
+               lq_perc = (int)(100 - (minimum (LQCR, 40)) * (float)2.5);
+               if (lq_perc > lq_perc_top)
+                   lq_perc_top = lq_perc;
+               sprintf(message, "Link quality: %3u%% (top: %3u%%)",
+                   lq_perc, lq_perc_top);
            } else { /* ap_type == ATMEL12350 */
                sprintf(message, "Current rate: ");
                switch(LQCR) {
@@ -256,49 +354,86 @@ void atmel_aplink()
                        strcat(message, "11 Mbps ");
                }
            }
-           mvwaddstr(main_sub, 5, 0, message);
+           mvwaddstr(main_sub, 6, 0, message);
 
            sprintf(message, "Channel: %2u", Channel);
-           mvwaddstr(main_sub, 6, 0, message);
+           mvwaddstr(main_sub, 7, 0, message);
 
-           mvwaddstr(main_sub, 7, 0, "ESSID: ");
+           mvwaddstr(main_sub, 8, 0, "ESSID: ");
            waddnstr(main_sub, ESSID, ESSLEN);
 /*
            sprintf(message, "InfoCapability: %3u", InfoCapability & 0xFF);
-           mvwaddstr(main_sub, 8, 0, message);
+           mvwaddstr(main_sub, 9, 0, message);
 */
            wnoutrefresh(main_sub);
 
-           doupdate();
-
-           i = wait_key();
-           if (i == -1)
-               goto exit;
-
-           switch((char) i) {
-               case 'q':
-               case 'Q':
-                   goto exit;
-               case 't':
-               case 'T':
-                   wait_mode = (wait_mode == WAIT_FOREVER ?
-                       WAIT_TIMEOUT : WAIT_FOREVER);
-                   print_top(wait_mode == WAIT_TIMEOUT ? POLL_ON : POLL_OFF,
-                       AP_TITLE);
+           for (i = 0; i < GRWIN_HEIGHT; i++) {
+               mvwdelch(grwin_rssi,     i, 0);
+               mvwdelch(grwin_rssi_avg, i, 0);
+               mvwdelch(grwin_rssi_rou, i, 0);
+               if (ap_type == ATMEL410)
+                   mvwdelch(grwin_lq,   i, 0);
            }
+           for (i = 0; i < GRWIN_HEIGHT * rssi_perc / 100; i++)
+               mvwaddch(grwin_rssi,
+                   GRWIN_HEIGHT - 1 - i, GRWIN_LENGTH - 1, ACS_BLOCK);
+           for (i = 0; i < GRWIN_HEIGHT * rssi_avg_perc / 100; i++)
+               mvwaddch(grwin_rssi_avg,
+                   GRWIN_HEIGHT - 1 - i, GRWIN_LENGTH - 1, ACS_BLOCK);
+           for (i = 0; i < GRWIN_HEIGHT * rssi_rou_perc / 100; i++)
+               mvwaddch(grwin_rssi_rou,
+                   GRWIN_HEIGHT - 1 - i, GRWIN_LENGTH - 1, ACS_BLOCK);
+           if (ap_type == ATMEL410)
+               for (i = 0; i < GRWIN_HEIGHT * lq_perc / 100; i++)
+                   mvwaddch(grwin_lq,
+                       GRWIN_HEIGHT - 1 - i, GRWIN_LENGTH - 1, ACS_BLOCK);
+
+           wnoutrefresh(gr_mode == 0 ? grwin_rssi :
+                        gr_mode == 1 ? grwin_rssi_avg :
+                        gr_mode == 2 ? grwin_rssi_rou : grwin_lq);
+
+           doupdate();
 
            linked = 1;
+       }
 
-           /* either timeout for user input (i == 0) or invalid key => cont. */
+       i = wait_key(poll_delay);
+       switch(i) {
+           case 'p':
+           case 'P':
+               getch();
+               break;
+           case 'q':
+           case 'Q':
+               goto exit;
+           case 't':
+           case 'T':
+               gr_mode++;
+               if (gr_mode == (ap_type == ATMEL410 ? 4 : 3))
+                   gr_mode = 0;
+
+               wmove(main_sub, 9, 6);
+               print_bold(main_sub, gr_modes[gr_mode]);
+               for (i = 0; i < 10; i++)
+                   waddch(main_sub, ACS_BSBS);
        }
+       /* either timeout for user input (i == 0) or invalid key => cont. */
     }
 
 exit:
-    snmp_retries = 5;
+    wait_mode = p_wait_mode;
+
     delwin(gauge_rssi);
     delwin(gauge_rssi_top);
     delwin(gauge_rssi_avg);
+    delwin(gauge_rssi_rou);
+
+    delwin(grwin_rssi);
+    delwin(grwin_rssi_avg);
+    delwin(grwin_rssi_rou);
+    if (ap_type == ATMEL410)
+       delwin(grwin_lq);
+
     print_top(NULL, NULL);
     clear_main(0);
 }
-