aboutsummaryrefslogtreecommitdiffstats
path: root/aplst_scr.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--aplst_scr.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/aplst_scr.c b/aplst_scr.c
new file mode 100644
index 0000000..c0f868f
--- /dev/null
+++ b/aplst_scr.c
@@ -0,0 +1,134 @@
+/*
+ * wavemon - a wireless network monitoring aplication
+ *
+ * Copyright (c) 2001-2002 Jan Morgenstern <jan@jm-music.de>
+ *
+ * wavemon is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2, or (at your option) any later
+ * version.
+ *
+ * wavemon is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with wavemon; see the file COPYING. If not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "iw_if.h"
+
+static void display_aplist(WINDOW *w_aplst)
+{
+ uint8_t buf[(sizeof(struct iw_quality) +
+ sizeof(struct sockaddr)) * IW_MAX_AP];
+ char s[0x100];
+ int i, j, line = 2;
+ struct iw_quality *qual, qual_pivot;
+ struct sockaddr *hwa, hwa_pivot;
+ struct iw_range range;
+ struct iw_levelstat dbm;
+ struct iwreq iwr;
+ int skfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if (skfd < 0)
+ err_sys("%s: can not open socket", __func__);
+
+ iw_getinf_range(conf.ifname, &range);
+ for (i = 1; i <= MAXYLEN; i++)
+ mvwclrtoborder(w_aplst, i, 1);
+
+ strncpy(iwr.ifr_name, conf.ifname, IFNAMSIZ);
+ iwr.u.data.pointer = (caddr_t) buf;
+ iwr.u.data.length = IW_MAX_AP;
+ iwr.u.data.flags = 0;
+
+ if (ioctl(skfd, SIOCGIWAPLIST, &iwr) < 0) {
+ sprintf(s, "%s does not have a list of peers/access points",
+ conf.ifname);
+ waddstr_center(w_aplst, WAV_HEIGHT/2 - 1, s);
+ goto done;
+ }
+
+ if (iwr.u.data.length == 0) {
+ sprintf(s, "%s: no peer/access point in range", conf.ifname);
+ waddstr_center(w_aplst, WAV_HEIGHT/2 - 1, s);
+ } else if (iwr.u.data.length == 1) {
+ mvwaddstr(w_aplst, line, 1, "Peer/access point:");
+ } else {
+ sprintf(s, "%d peers/access points in range:", iwr.u.data.length);
+ mvwaddstr(w_aplst, line, 1, s);
+ }
+
+ hwa = (struct sockaddr *) buf;
+ qual = (struct iw_quality *) (hwa + iwr.u.data.length);
+
+ /*
+ * Show access points in descending order of signal quality by
+ * sorting both lists in parallel, using simple insertion sort.
+ */
+ for (i = 0; i < iwr.u.data.length; i++) {
+
+ qual_pivot = qual[i];
+ hwa_pivot = hwa[i];
+
+ for (j = i; j > 0 && qual[j-1].qual < qual_pivot.qual; j--) {
+ qual[j] = qual[j-1];
+ hwa[j] = hwa[j-1];
+ }
+
+ qual[j] = qual_pivot;
+ hwa[j] = hwa_pivot;
+ }
+
+ line += 2;
+
+ /* Truncate overly long access point lists to match screen height */
+ for (i = 0; i < iwr.u.data.length && line < MAXYLEN; i++, line++) {
+
+ mvwaddstr(w_aplst, line++, 1, " ");
+ waddstr_b(w_aplst, mac_addr(&hwa[i]));
+
+ if (iwr.u.data.flags) {
+ iw_sanitize(&range, &qual[i], &dbm);
+ sprintf(s, "Quality%c %2d/%d, Signal%c %.0f dBm (%s), Noise%c %.0f dBm",
+ qual[i].updated & IW_QUAL_QUAL_UPDATED ? ':' : '=',
+ qual[i].qual, range.max_qual.qual,
+ qual[i].updated & IW_QUAL_LEVEL_UPDATED ? ':' : '=',
+ dbm.signal, dbm2units(dbm.signal),
+ qual[i].updated & IW_QUAL_NOISE_UPDATED ? ':' : '=',
+ dbm.noise);
+ mvwaddstr(w_aplst, line++, 5, s);
+ }
+ }
+done:
+ close(skfd);
+ wrefresh(w_aplst);
+}
+
+enum wavemon_screen scr_aplst(WINDOW *w_menu)
+{
+ WINDOW *w_aplst;
+ struct timer t1;
+ int key = 0;
+
+ w_aplst = newwin_title(0, WAV_HEIGHT, "Access point list", false);
+
+ while (key < KEY_F(1) || key > KEY_F(10)) {
+ display_aplist(w_aplst);
+ start_timer(&t1, 50000);
+ while (!end_timer(&t1) && (key = wgetch(w_menu)) <= 0)
+ usleep(5000);
+
+ /* Keyboard shortcuts */
+ if (key == 'q')
+ key = KEY_F(10);
+ else if (key == 'i')
+ key = KEY_F(1);
+ }
+
+ delwin(w_aplst);
+
+ return key - KEY_F(1);
+}