2 * aplink.c from Access Point SNMP Utils for Linux
4 * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License Version 2 from
8 * June 1991 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define S_RSSI _("RSSI: [")
29 #define S_RSSI_AVG _("RSSI avg: [")
30 #define S_RSSI_TOP _("RSSI top: [")
32 extern WINDOW *main_sub;
33 extern short ap_type, ap_vendorext;
34 extern int wait_mode, snmp_retries;
37 * TODO: Implement APClientInfo as alternative, for NetGear ME102 MIB
38 * (ap_type == ATMEL12350 && ap_vendorext == NONE).
43 char bridgeOperationalMode[] = {
44 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x04, 0x01, 0x00
47 * ATMEL12350 EZYNET MIB and ATMEL410 SBRIDGES MIB specific:
48 * for ATMEL410 SBRIDGES MIB: .1.3.6.1.4.1.410.1.2.8.1.0
49 * for ATMEL12350 EZYNET MIB: .1.3.6.1.4.1.12350.1.2.7.4.0
51 char NetworkSettings[] = {
52 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x08, 0x01, 0x00
55 /* APClient mode: AP link diagnostics */
57 struct NetworkSettings_ATMEL410_SBRIDGES sa_sb_410;
58 struct NetworkSettings_ATMEL12350_EZYNET sa_en_12350;
60 /* Used common members of the 2 structures above. */
61 unsigned char BSSID[6];
62 /* unsigned short InfoCapability; */
64 unsigned char Channel;
65 /* LinkQuality for NetworkSettings_ATMEL410_SBRIDGES */
66 /* CurrentRate for NetworkSettings_ATMEL12350_EZYNET */
68 unsigned char ESSID[32];
69 unsigned long ESSLEN; /* uchar for NetworkSettings_ATMEL410_SBRIDGES */
72 int i, linked = 0, rssi_perc, samples = 0, sum = 0, avg = 0, avg_perc;
73 int top = 0, top_perc;
75 WINDOW *gauge_rssi, *gauge_rssi_avg, *gauge_rssi_top;
77 if (ap_type == ATMEL12350) {
78 bridgeOperationalMode[5] = 0xE0;
79 bridgeOperationalMode[6] = 0x3E;
81 NetworkSettings[5] = 0xE0;
82 NetworkSettings[6] = 0x3E;
83 NetworkSettings[9] = 0x07;
84 NetworkSettings[10] = 0x04;
87 gauge_rssi = derwin(main_sub, 1, 20, 2, strlen(S_RSSI));
88 gauge_rssi_top = derwin(main_sub, 1, 20, 3, strlen(S_RSSI_TOP));
89 gauge_rssi_avg = derwin(main_sub, 1, 20, 4, strlen(S_RSSI_AVG));
91 /* find out mode the device is currently in */
92 varbinds[0].oid = bridgeOperationalMode;
93 varbinds[0].len_oid = sizeof(bridgeOperationalMode);
94 varbinds[0].value = bridgeOperationalMode;
95 varbinds[0].len_val = 0;
96 varbinds[0].type = NULL_VALUE;
98 if (snmp(varbinds, 1, GET) <= 0) {
99 print_helperr(ERR_RET);
105 * Rule out all modes except APClient(3) mode and WRepeater(5) mode on
106 * device running firmware with necessary vendor extensions.
108 if(!( ((ap_type == ATMEL410 && ap_vendorext == SBRIDGES) ||
109 (ap_type == ATMEL12350 && ap_vendorext == EZYNET)) &&
110 (*(varbinds[0].value) == 3 || *(varbinds[0].value) == 5) )) {
111 mvwaddstr(main_sub, 1, 1,
112 _("Not available - device must have firmware with necessary "));
113 mvwaddstr(main_sub, 2, 1,
114 _("vendor extensions and be in either 'Access Point client'"));
115 mvwaddstr(main_sub, 3, 1,
116 _("or 'Repeater' mode."));
123 print_top(wait_mode == WAIT_TIMEOUT ? POLL_ON : POLL_OFF, AP_TITLE);
128 /* find out how many STAtions is in the list */
129 varbinds[0].oid = NetworkSettings;
130 varbinds[0].len_oid = sizeof(NetworkSettings);
131 varbinds[0].value = NetworkSettings;
132 varbinds[0].type = STRING_VALUE;
133 varbinds[0].len_val = 0;
135 if (wait_mode == WAIT_FOREVER)
136 print_help(WAIT_RET);
139 mvwaddstr(main_sub, 0, 0, "Associated with AP: ");
140 if (snmp(varbinds, 1, GET) <= 0) {
141 waddstr(main_sub, NO);
149 if (wait_mode == WAIT_FOREVER)
152 waddstr(main_sub, YES);
154 if (ap_type == ATMEL410) {
155 memcpy(&sa_sb_410, varbinds[0].value, varbinds[0].len_val);
157 memcpy(BSSID, sa_sb_410.BSSID, 6);
158 /* InfoCapability = sa_sb_410.InfoCapability; */
159 Rssi = sa_sb_410.Rssi;
160 Channel = sa_sb_410.Channel;
161 LQCR = sa_sb_410.LinkQuality;
162 memcpy(ESSID, sa_sb_410.ESSID, 32);
163 ESSLEN = sa_sb_410.ESSLEN;
164 } else { /* ap_type == ATMEL12350 */
165 memcpy(&sa_en_12350, varbinds[0].value, varbinds[0].len_val);
167 memcpy(BSSID, sa_en_12350.BSSID, 6);
168 /* InfoCapability = sa_en_12350.InfoCapability; */
169 Rssi = sa_en_12350.Rssi;
170 Channel = sa_en_12350.Channel;
171 LQCR = sa_en_12350.CurrentRate;
172 memcpy(ESSID, sa_en_12350.ESSID, 32);
173 ESSLEN = sa_en_12350.ESSLEN;
176 sprintf(message, "Joined BSSID: %02X%02X%02X%02X%02X%02X",
177 BSSID[0] & 0xFF, BSSID[1] & 0xFF, BSSID[2] & 0xFF,
178 BSSID[3] & 0xFF, BSSID[4] & 0xFF, BSSID[5] & 0xFF);
179 mvwaddstr(main_sub, 1, 0, message);
181 mvwaddstr(main_sub, 2, 0, S_RSSI);
182 rssi_perc = (int)((minimum (Rssi, 40)) * (float)2.5);
184 for (i = 0; i < (20 * rssi_perc / 100); i++) {
186 wattrset(gauge_rssi, COLOR_PAIR(COLOR_RED));
188 wattrset(gauge_rssi, COLOR_PAIR(COLOR_YELLOW) | A_BOLD);
190 wattrset(gauge_rssi, COLOR_PAIR(COLOR_GREEN));
191 waddch(gauge_rssi, ACS_BLOCK);
193 wnoutrefresh(gauge_rssi);
194 sprintf(message, "] [%4ddBm] [%3u%%] [%3u]",
195 -96 + Rssi, rssi_perc, Rssi);
196 mvwaddstr(main_sub, 2, strlen(S_RSSI) + 20, message);
198 mvwaddstr(main_sub, 3, 0, S_RSSI_TOP);
201 top_perc = (int)((minimum (top, 40)) * (float)2.5);
202 werase(gauge_rssi_top);
203 for (i = 0; i < (20 * top_perc / 100); i++) {
205 wattrset(gauge_rssi_top, COLOR_PAIR(COLOR_RED));
207 wattrset(gauge_rssi_top, COLOR_PAIR(COLOR_YELLOW) | A_BOLD);
209 wattrset(gauge_rssi_top, COLOR_PAIR(COLOR_GREEN));
210 waddch(gauge_rssi_top, ACS_BLOCK);
212 wnoutrefresh(gauge_rssi_top);
213 sprintf(message, "] [%4ddBm] [%3u%%] [%3u]",
214 -96 + top, top_perc, top);
215 mvwaddstr(main_sub, 3, strlen(S_RSSI_TOP) + 20, message);
217 mvwaddstr(main_sub, 4, 0, S_RSSI_AVG);
219 avg = sum / ++samples;
220 if (samples == 100000) {
224 avg_perc = (int)((minimum (avg, 40)) * (float)2.5);
225 werase(gauge_rssi_avg);
226 for (i = 0; i < (20 * avg_perc / 100); i++) {
228 wattrset(gauge_rssi_avg, COLOR_PAIR(COLOR_RED));
230 wattrset(gauge_rssi_avg, COLOR_PAIR(COLOR_YELLOW) | A_BOLD);
232 wattrset(gauge_rssi_avg, COLOR_PAIR(COLOR_GREEN));
233 waddch(gauge_rssi_avg, ACS_BLOCK);
235 wnoutrefresh(gauge_rssi_avg);
236 sprintf(message, "] [%4ddBm] [%3u%%] / %5u sampl.",
237 -96 + avg, avg_perc, samples);
238 mvwaddstr(main_sub, 4, strlen(S_RSSI_AVG) + 20, message);
240 if (ap_type == ATMEL410) {
241 sprintf(message, "Link quality: %3u%%",
242 (int)(100 - (minimum (LQCR, 40)) * (float)2.5));
243 } else { /* ap_type == ATMEL12350 */
244 sprintf(message, "Current rate: ");
247 strcat(message, "1 Mbps ");
250 strcat(message, "2 Mbps ");
253 strcat(message, "5.5 Mbps");
256 strcat(message, "11 Mbps ");
259 mvwaddstr(main_sub, 5, 0, message);
261 sprintf(message, "Channel: %2u", Channel);
262 mvwaddstr(main_sub, 6, 0, message);
264 mvwaddstr(main_sub, 7, 0, "ESSID: ");
265 waddnstr(main_sub, ESSID, ESSLEN);
267 sprintf(message, "InfoCapability: %3u", InfoCapability & 0xFF);
268 mvwaddstr(main_sub, 8, 0, message);
270 wnoutrefresh(main_sub);
284 wait_mode = (wait_mode == WAIT_FOREVER ?
285 WAIT_TIMEOUT : WAIT_FOREVER);
286 print_top(wait_mode == WAIT_TIMEOUT ? POLL_ON : POLL_OFF,
292 /* either timeout for user input (i == 0) or invalid key => cont. */
299 delwin(gauge_rssi_top);
300 delwin(gauge_rssi_avg);
301 print_top(NULL, NULL);