]> git.decadent.org.uk Git - ap-utils.git/blobdiff - src/stations.c
Merge commit 'upstream/1.5'
[ap-utils.git] / src / stations.c
index 6c23478305ad874811e587dfbf1945aa2a7cfef4..bb6ca9018cac9f347b8cce6ce4ea0ade72c3327e 100644 (file)
@@ -2,6 +2,7 @@
  *      stations.c from Access Point SNMP Utils for Linux
  *
  * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
+ * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License Version 2 from
 #include <string.h>
 #include "ap-utils.h"
 
-/*
- * NOTE: SBRIDGES seems to be currently handled by ap-gl =>
- * no SBRIDGES-related code here (yet)!
- */
-
-#define TITLE_AP _("AP link state")
-
-/* following for any non-VERNET ATMEL* MIB */
-#define HEADER_STAS \
-       _(" #            MAC                                               ")
-/* following for VERNET-enhanced ATMEL12350 MIB */
-#define HEADER_STAS_VERNET \
-       _(" #     MAC       Parent MAC    RSSI  Status MACn      IP        ")
-
 #define MAX_LINES LINES-4
 
 extern int LINES;
@@ -51,39 +38,34 @@ void atmel_stations()
     char bridgeOperationalMode[] = {
        0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x04, 0x01, 0x00
     };
-    char StasNum[] = {
+    char AssociatedSTAsNum[] = {
        0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01, 0x00
     };
-    char StasMac[] = {
+    char AssociatedSTAsInfo[] = {
        0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x02, 0x00
     };
 
-    struct AssociatedSTAsInfo {
-       unsigned short Num;
-       unsigned char MacAddress[6];
-       /* following ones are specific for enhanced ATMEL 12350 MIB by VERNET */
-       unsigned char Status;
-       unsigned char Port;
-       unsigned char ParentMacAddress[6];
-       unsigned char RSSI;
-       unsigned char IP[4];
-    } *mac = NULL, get;
+    /* AP mode: connected APClients info */
+
+    struct AssociatedSTAsInfo_ATMEL410 ap_410;
+    struct AssociatedSTAsInfo_ATMEL12350 ap_12350;
 
     struct MacListStat *first = NULL, *curr = NULL;
     char message[1024];
     int mac_idx, begin, end, total_mac;
     varbind varbinds[1];
 
+
     if (ap_type == ATMEL12350) {
         bridgeOperationalMode[5] = 0xE0;
        bridgeOperationalMode[6] = 0x3E;
-       StasNum[5] = 0xE0;
-       StasNum[6] = 0x3E;
-       StasMac[5] = 0xE0;
-       StasMac[6] = 0x3E;
+       AssociatedSTAsNum[5] = 0xE0;
+       AssociatedSTAsNum[6] = 0x3E;
+       AssociatedSTAsInfo[5] = 0xE0;
+       AssociatedSTAsInfo[6] = 0x3E;
     }  
 
-    /* find out in what mode the AP currently is */
+    /* find out mode the device is currently in */
     varbinds[0].oid = bridgeOperationalMode;
     varbinds[0].len_oid = sizeof(bridgeOperationalMode);
     varbinds[0].value = bridgeOperationalMode;
@@ -95,29 +77,26 @@ void atmel_stations()
          goto exit;
     }
 
-    /* for AP in AP-Client mode & without VERNET firmware, disable status */
-    if (*(varbinds[0].value) == 3 && ap_vendorext != VERNET) {
-       mvwaddstr(main_sub, 3, 1, _("AP is currently in AP Client Mode => "
-           "no associated STAtions."));
+    /* Rule out all modes except AP(2). */
+    if (*(varbinds[0].value) != 2) {
+       mvwaddstr(main_sub, 1, 1, _("Not available (device not in AP mode)."));
        print_help(ANY_KEY);
        wrefresh(main_sub);
-       getch();
        goto exit;
     }
 
     noecho();
-    wattrset(main_sub, COLOR_PAIR(3));
-    if (ap_vendorext == VERNET)
-       mvwaddstr(main_sub, 0, 0, HEADER_STAS_VERNET);
-    else
-       mvwaddstr(main_sub, 0, 0, HEADER_STAS);
+
+    wattrset(main_sub, COLOR_PAIR(13));
+    mvwaddstr(main_sub, 0, 0,
+       _("  #     MAC       Parent MAC  RSSI   LQ Sts MACn      IP        "));
     wattrset(main_sub, A_NORMAL);
 
 refresh:
     /* find out how many STAtions is in the list */
-    varbinds[0].oid = StasNum;
-    varbinds[0].len_oid = sizeof(StasNum);
-    varbinds[0].value = StasNum;
+    varbinds[0].oid = AssociatedSTAsNum;
+    varbinds[0].len_oid = sizeof(AssociatedSTAsNum);
+    varbinds[0].value = AssociatedSTAsNum;
     varbinds[0].type = NULL_VALUE;
     varbinds[0].len_val = 0;
 
@@ -125,59 +104,74 @@ refresh:
 
     if (snmp(varbinds, 1, GET) <= 0) {
        print_helperr(ERR_RET);
-       getch();
        goto exit;
     }
 
     total_mac = *(varbinds[0].value);
     print_help(WAIT_SET);
     mac_idx = 1;
-    while (mac_idx <= total_mac) {
 
-       /* tell the AP we want first mac_idx-th MAC */
-       varbinds[0].oid = StasMac;
-       varbinds[0].len_oid = sizeof(StasMac);
+    while (mac_idx <= total_mac) {
+       /*
+        * Tell the AP we want mac_idx-th AssociatedSTAsInfo structure.
+        * Note: since:
+        * - position of 'Index' member in ap_* struct is always the same
+        * - only the 'Index' member is actually to be used
+        * - both structures have same size (24)
+        * we may pick *any* ap_* struct here.
+        */
+       varbinds[0].oid = AssociatedSTAsInfo;
+       varbinds[0].len_oid = sizeof(AssociatedSTAsInfo);
        varbinds[0].type = INT_VALUE;
-       get.Num = swap2(mac_idx);
-       varbinds[0].value = (char *) &get;
-       varbinds[0].len_val = sizeof(get);
+       ap_410.Index = swap2(mac_idx);
+       varbinds[0].value = (char *)&ap_410;
+       varbinds[0].len_val = sizeof(ap_410);
 
        if (snmp(varbinds, 1, SET) <= 0) {
            print_helperr(ERR_RET);
-           getch();
            goto exit;
        }
 
-       if (varbinds[0].len_val == 24) {
-           if (mac)
-               free(mac);
-           mac =
-               (struct AssociatedSTAsInfo *) malloc(varbinds[0].len_val);
-           memcpy(mac, varbinds[0].value, varbinds[0].len_val);
-           /* mac = (struct AssociatedSTAsInfo *) varbinds[0].value; */
-       } else {
+       if (varbinds[0].len_val != 24) {
            print_helperr(_("AssociatedSTAsInfo packet error"));
            goto exit;
        }
 
        if (first == NULL) {
            first =
-               (struct MacListStat *) malloc(sizeof(struct MacListStat));
+               (struct MacListStat *) calloc(1, sizeof(struct MacListStat));
            curr = first;
        } else {
            curr->next =
-               (struct MacListStat *) malloc(sizeof(struct MacListStat));
+               (struct MacListStat *) calloc(1, sizeof(struct MacListStat));
            curr = curr->next;
        }
 
-       memcpy(curr->addr, mac->MacAddress, 6);
-
-       if (ap_vendorext == VERNET) {
-           curr->Status = mac->Status;
-           curr->Port = mac->Port;
-           memcpy(curr->ParentMacAddress, mac->ParentMacAddress, 6);
-           curr->rssi = mac->RSSI;
-           memcpy(&(curr->IP.s_addr), mac->IP, 4);
+       /* lets not use black magic (casting) here, ok? */
+       if (ap_type == ATMEL410) {
+           memcpy(&ap_410, varbinds[0].value, sizeof(ap_410));
+
+           memcpy(curr->addr, ap_410.MacAddress, 6);
+           if (ap_vendorext == SBRIDGES) {
+               memcpy(curr->ParentMacAddress, ap_410.ParentMacAddress, 6);
+               memcpy(&(curr->IP.s_addr), ap_410.IP, 4);
+               curr->rssi = ap_410.RSSI;
+               curr->quality = ap_410.LinkQuality;
+               curr->Status = ap_410.Status;
+               curr->Port = ap_410.Port;
+           }
+       } else { /* ap_type == ATMEL12350 */
+           memcpy(&ap_12350, varbinds[0].value, sizeof(ap_12350));
+
+           memcpy(curr->addr, ap_12350.MacAddress, 6);
+           if (ap_vendorext == EZYNET) {
+               memcpy(curr->ParentMacAddress, ap_12350.ParentMacAddress, 6);
+               memcpy(&(curr->IP.s_addr), ap_12350.IP, 4);
+               curr->rssi = ap_12350.RSSI;
+               /* curr->quality stays empty */
+               curr->Status = ap_12350.Status;
+               curr->Port = ap_12350.Port;
+           }
        }
 
        curr->next = NULL;
@@ -187,20 +181,19 @@ refresh:
     begin = 1;
     end = (MAX_LINES < mac_idx) ? MAX_LINES : mac_idx;
 
-    sprintf(message, "%s: %d", TITLE_STAS, total_mac);
+    sprintf(message, "%s: %d", ST_TITLE, total_mac);
     while (1) {
-       if (ap_vendorext == VERNET) {
+       if ((ap_type == ATMEL410 && ap_vendorext == SBRIDGES) ||
+           (ap_type == ATMEL12350 && ap_vendorext == EZYNET)) {
            print_top_rssi(message);
-
            print_help(_("Arrows - scroll; S - save to file; Q - return; "
                         "T - toggle view; Other - refresh"));
-           scroll_rows(first, begin, end, 1, 3);
        } else {
            print_top(NULL, message);
            print_help(_("Arrows - scroll; S - save to file; Q - return; "
                         "Other key - refresh"));
-           scroll_rows(first, begin, end, 1, 0);
        }
+       scroll_rows(first, begin, end, 1, 2);
 
        switch (getch()) {
            case 'S':
@@ -223,10 +216,11 @@ refresh:
                continue;
            case 'Q':
            case 'q':
-               goto exit;
+               goto quit;
            case 'T':
            case 't':
-               if (ap_vendorext == VERNET) {
+               if ((ap_type == ATMEL410 && ap_vendorext == SBRIDGES) ||
+                   (ap_type == ATMEL12350 && ap_vendorext == EZYNET)) {
                    sts_viewtype += 1;
                    if (sts_viewtype == 3)
                        sts_viewtype = 0;
@@ -243,6 +237,8 @@ refresh:
     }
 
 exit:
+    getch();
+quit:
     while ((curr = first)) {
        first = curr->next;
        free(curr);
@@ -274,7 +270,7 @@ void nwn_stations()
 
 
     mac_idx = 0;
-    print_top(NULL, TITLE_STAS);
+    print_top(NULL, ST_TITLE);
     mvwaddstr(main_sub, 0, 3,
        _("Id       MAC address     Quality  Age  RSSI"));
     noecho();
@@ -320,7 +316,7 @@ void nwn_stations()
        varbinds[3].len_oid = sizeof(RSSI);
        varbinds[3].len_val = 0;
        varbinds[3].type = NULL_VALUE;
-       if (snmp(varbinds, 4, GET) <= 0) {
+       if (snmp(varbinds, 4, GET) < 4) {
            print_helperr(ERR_RET);
            getch();
            goto exit;
@@ -369,7 +365,7 @@ void nwn_stations()
 
        scroll_rows(first, begin, end, 1, 1);
 
-       sprintf(message, "%s: %d", TITLE_STAS, mac_idx);
+       sprintf(message, "%s: %d", ST_TITLE, mac_idx);
        print_top_rssi(message);
 
        switch (getch()) {
@@ -417,4 +413,3 @@ void nwn_stations()
     print_top(NULL, NULL);
     clear_main(0);
 }
-