diff options
| -rw-r--r-- | NEWS | 16 | ||||
| -rw-r--r-- | THANKS | 2 | ||||
| -rw-r--r-- | conf.c | 132 | ||||
| -rw-r--r-- | conf_scr.c | 2 | ||||
| -rwxr-xr-x | configure | 18 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | iw_if.c | 49 | ||||
| -rw-r--r-- | iw_if.h | 7 | ||||
| -rw-r--r-- | iw_scan.c | 54 | ||||
| -rw-r--r-- | scan_scr.c | 11 | ||||
| -rw-r--r-- | wavemon.1 | 9 | ||||
| -rw-r--r-- | wavemon.h | 22 | ||||
| -rw-r--r-- | wavemonrc.5 | 54 | 
13 files changed, 244 insertions, 134 deletions
| @@ -1,5 +1,21 @@  NEWS  ==== +-------------------- +0.7.4 (2012-02-03) +-------------------- +  * General: +    - deprecate reliance on /proc/net/wireless, since tests on Tiny Core Linux +      showed that it no longer reliably lists available wireless interfaces, +    - instead use safe route of using /proc/net/dev, probing each interface +      in turn for wireless extensions; +  * Scan window: +    - configurable scan sort order (at runtime and via configuration file), +    - can sort by (combinations of) channel, signal strength, and openness, +    - visually distinguish 2.4GHz and 5.8GHz channels; +  * Fixes: +    - wavemonrc.5 manpage fixes thanks to Jonathan McCrohan, +    - support common options (-v/-h) even if no interfaces found, +    - but do not start operation unless at least 1 wireless interface exists.  --------------------  0.7.3 (2011-12-22) @@ -30,3 +30,5 @@ Thanks to Matt who helped fixing several bugs in 0.7.0.  Robert M. Stockmann and Koniu helped with bug fixes in 0.7.1; thanks to Koniu  support for window resizing got started. + +Jonathan McCrohan fixed manpage compilation errors in 0.7.4. @@ -34,6 +34,17 @@ static char *action_items[] = {  	NULL  }; +static char *sort_order[] = { +	[SO_CHAN]	= "Channel", +	[SO_CHAN_REV]	= "Rev Channel", +	[SO_SIGNAL]	= "Signal", +	[SO_OPEN]	= "Open", +	[SO_CHAN_SIG]	= "Chan/Sig", +	[SO_OPEN_SIG]	= "Open/Sig", +	[SO_OPEN_CH_SI]	= "Open/Chan/Sig", +	NULL +}; +  static char *screen_names[] = {  	[SCR_INFO]	= "Info screen",  	[SCR_LHIST]	= "Histogram", @@ -59,6 +70,7 @@ struct wavemon_conf conf = {  	.noise_min		= -102,  	.noise_max		= 10, +	.scan_sort_order	= SO_CHAN,  	.lthreshold_action	= TA_DISABLED,  	.lthreshold		= -80,  	.hthreshold_action	= TA_DISABLED, @@ -67,58 +79,8 @@ struct wavemon_conf conf = {  	.startup_scr		= 0,  }; -static void version(void) -{ -	printf("wavemon wireless monitor %s\n", PACKAGE_VERSION); -	printf("Distributed under the terms of the GPLv3.\n"); -} - -static void usage(void) -{ -	printf("Usage: wavemon [ -dhlrv ] [ -i ifname ]\n\n"); -	printf("  -d            Dump the current device status to stdout and exit\n"); -	printf("  -g            Ensure screen is sufficiently dimensioned\n"); -	printf("  -h            This help screen\n"); -	printf("  -i <ifname>   Use specified network interface (default: auto)\n"); -	printf("  -r            Generate random levels (for testing purposes)\n"); -	printf("  -v            Print version number and exit\n\n"); -} - -static void getargs(int argc, char *argv[]) -{ -	int arg; - -	while ((arg = getopt(argc, argv, "dghi:rv")) >= 0) -		switch (arg) { -		case 'd': -			dump_parameters(); -			exit(EXIT_SUCCESS); -		case 'g': -			conf.check_geometry = true; -			break; -		case 'h': -			usage(); -			exit(EXIT_SUCCESS); -		case 'i': -			conf.if_idx = argv_find(if_list, optarg); -			if (conf.if_idx < 0) -				err_quit("no wireless extensions found on '%s'", -					 optarg); -			break; -		case 'r': -			conf.random = true; -			break; -		case 'v': -			version(); -			exit(EXIT_SUCCESS); -		default: -			/* bad argument. bad bad */ -			exit(EXIT_FAILURE); -		} -} -  /** Populate interface list */ -void conf_get_interface_list(void) +void conf_get_interface_list(bool init)  {  	char *old_if = NULL;  	int idx; @@ -132,7 +94,7 @@ void conf_get_interface_list(void)  		free(if_list);  	}  	if_list = iw_get_interface_list(); -	if (if_list == NULL) +	if (if_list == NULL && !init)  		err_quit("no wireless interfaces found!");  	conf.if_idx = 0; @@ -240,7 +202,7 @@ static void read_cf(void)  			}  			break;  		case t_list: -			v_int = argv_find(ci->list, rv); +			v_int = ci->list ? argv_find(ci->list, rv) : -1;  			if (v_int < 0)  				err_msg("%s, line %d: '%s = %s' is not valid - using defaults",  					 cfname, lnum, lv, rv); @@ -364,6 +326,14 @@ static void init_conf_items(void)  	ll_push(conf_items, "*", item);  	item = calloc(1, sizeof(*item)); +	item->name	= strdup("Scan sort order"); +	item->cfname	= strdup("sort_order"); +	item->type	= t_list; +	item->v.i	= &conf.scan_sort_order; +	item->list	= sort_order; +	ll_push(conf_items, "*", item); + +	item = calloc(1, sizeof(*item));  	item->name	= strdup("Statistics updates");  	item->cfname	= strdup("stat_updates");  	item->type	= t_int; @@ -554,8 +524,60 @@ static void init_conf_items(void)  void getconf(int argc, char *argv[])  { -	conf_get_interface_list(); +	int arg, dump = 0, help = 0, version = 0; + +	conf_get_interface_list(true);  	init_conf_items();  	read_cf(); -	getargs(argc, argv); + +	while ((arg = getopt(argc, argv, "dghi:rv")) >= 0) { +		switch (arg) { +		case 'd': +			if (if_list) +				dump++; +			break; +		case 'g': +			conf.check_geometry = true; +			break; +		case 'h': +			help++; +			break; +		case 'i': +			conf.if_idx = if_list ? argv_find(if_list, optarg) : -1; +			if (conf.if_idx < 0) +				err_quit("no wireless extensions found on '%s'", +					 optarg); +			break; +		case 'r': +			conf.random = true; +			break; +		case 'v': +			version++; +			break; +		default: +			/* bad argument. bad bad */ +			exit(EXIT_FAILURE); +		} +	} + +	if (version) { +		printf("wavemon wireless monitor %s\n", PACKAGE_VERSION); +		printf("Distributed under the terms of the GPLv3.\n%s", help ? "\n" : ""); +	} +	if (help) { +		printf("usage: wavemon [ -dhlrv ] [ -i ifname ]\n"); +		printf("  -d            Dump the current device status to stdout and exit\n"); +		printf("  -g            Ensure screen is sufficiently dimensioned\n"); +		printf("  -h            This help screen\n"); +		printf("  -i <ifname>   Use specified network interface (default: auto)\n"); +		printf("  -r            Generate random levels (for testing purposes)\n"); +		printf("  -v            Print version number\n"); +	} else if (dump) { +		dump_parameters(); +	} + +	if (version || help || dump) +		exit(EXIT_SUCCESS); +	else if (if_list == NULL) +		err_quit("no supported wireless interfaces found");  } @@ -159,7 +159,7 @@ static int m_pref(WINDOW *w_conf, int list_offset, int active_item, int num_item  void scr_conf_init(void)  { -	conf_get_interface_list();	/* may have changed in the meantime */ +	conf_get_interface_list(false);	/* may have changed in the meantime */  	num_items = ll_size(conf_items);  	w_conf    = newwin_title(0, WAV_HEIGHT, "Preferences", false); @@ -1,6 +1,6 @@  #! /bin/sh  # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for wavemon 0.7.3. +# Generated by GNU Autoconf 2.68 for wavemon 0.7.4.  #  # Report bugs to <gerrit@erg.abdn.ac.uk>.  # @@ -560,8 +560,8 @@ MAKEFLAGS=  # Identity of this package.  PACKAGE_NAME='wavemon'  PACKAGE_TARNAME='wavemon-current' -PACKAGE_VERSION='0.7.3' -PACKAGE_STRING='wavemon 0.7.3' +PACKAGE_VERSION='0.7.4' +PACKAGE_STRING='wavemon 0.7.4'  PACKAGE_BUGREPORT='gerrit@erg.abdn.ac.uk'  PACKAGE_URL='http://eden-feed.erg.abdn.ac.uk/wavemon' @@ -1217,7 +1217,7 @@ if test "$ac_init_help" = "long"; then    # Omit some internal or obsolete options to make the list less imposing.    # This message is too long to be a string in the A/UX 3.1 sh.    cat <<_ACEOF -\`configure' configures wavemon 0.7.3 to adapt to many kinds of systems. +\`configure' configures wavemon 0.7.4 to adapt to many kinds of systems.  Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1282,7 +1282,7 @@ fi  if test -n "$ac_init_help"; then    case $ac_init_help in -     short | recursive ) echo "Configuration of wavemon 0.7.3:";; +     short | recursive ) echo "Configuration of wavemon 0.7.4:";;     esac    cat <<\_ACEOF @@ -1363,7 +1363,7 @@ fi  test -n "$ac_init_help" && exit $ac_status  if $ac_init_version; then    cat <<\_ACEOF -wavemon configure 0.7.3 +wavemon configure 0.7.4  generated by GNU Autoconf 2.68  Copyright (C) 2010 Free Software Foundation, Inc. @@ -1786,7 +1786,7 @@ cat >config.log <<_ACEOF  This file contains any messages produced by compilers while  running configure, to aid debugging if configure makes a mistake. -It was created by wavemon $as_me 0.7.3, which was +It was created by wavemon $as_me 0.7.4, which was  generated by GNU Autoconf 2.68.  Invocation command line was    $ $0 $@ @@ -4610,7 +4610,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1  # report actual input values of CONFIG_FILES etc. instead of their  # values after options handling.  ac_log=" -This file was extended by wavemon $as_me 0.7.3, which was +This file was extended by wavemon $as_me 0.7.4, which was  generated by GNU Autoconf 2.68.  Invocation command line was    CONFIG_FILES    = $CONFIG_FILES @@ -4664,7 +4664,7 @@ _ACEOF  cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1  ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"  ac_cs_version="\\ -wavemon config.status 0.7.3 +wavemon config.status 0.7.4  configured by $0, generated by GNU Autoconf 2.68,    with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 62666fe..48e4d88 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@  dnl Process this file with autoconf to produce a configure script.  AC_PREREQ(2.64) -AC_INIT([wavemon], [0.7.3], [gerrit@erg.abdn.ac.uk], [wavemon-current], +AC_INIT([wavemon], [0.7.4], [gerrit@erg.abdn.ac.uk], [wavemon-current],  	[http://eden-feed.erg.abdn.ac.uk/wavemon]) @@ -94,39 +94,45 @@ void if_getinf(const char *ifname, struct if_info *info)  	close(skfd);  } -static FILE *open_proc_net(const char *filename) -{ -	char path[128]; -	FILE *fp; - -	snprintf(path, sizeof(path), "/proc/net/%s", filename); -	if (access(path, F_OK) != 0) -		err_quit("'%s' not accessible - not compiled in?", path); - -	fp = fopen(path, "r"); -	if (fp == NULL) -		err_sys("can not open %s", path); - -	return fp; -} -  /**   * iw_get_interface_list  -  Return NULL-terminated array of WiFi interfaces. + * Use the safe route of checking /proc/net/dev/ for wireless interfaces: + * - SIOCGIFCONF only returns running interfaces that have an IP address; + * - /proc/net/wireless may exist, but may not list all wireless interfaces.   */  char **iw_get_interface_list(void)  {  	char **if_list = NULL, *p, tmp[BUFSIZ];  	int  nifs = 1;		/* if_list[nifs-1] = NULL */ -	FILE *fp = open_proc_net("wireless"); +	struct iwreq wrq; +	FILE *fp; +	int skfd = socket(AF_INET, SOCK_DGRAM, 0); + +	if (skfd < 0) +		err_sys("%s: can not open socket", __func__); + +	fp = fopen("/proc/net/dev", "r"); +	if (fp == NULL) +		err_sys("can not open /proc/net/dev"); -	while (fgets(tmp, sizeof(tmp), fp)) +	while (fgets(tmp, sizeof(tmp), fp)) {  		if ((p = strchr(tmp, ':'))) { -			if_list = realloc(if_list, sizeof(char *) * (nifs + 1));  			for (*p = '\0', p = tmp; isspace(*p); )  				p++; +			/* +			 * Use SIOCGIWNAME as indicator: if interface does not +			 * support this ioctl, it has no wireless extensions. +			 */ +			strncpy(wrq.ifr_name, p, IFNAMSIZ); +			if (ioctl(skfd, SIOCGIWNAME, &wrq) < 0) +				continue; + +			if_list = realloc(if_list, sizeof(char *) * (nifs + 1));  			if_list[nifs-1] = strdup(p);  			if_list[nifs++] = NULL;  		} +	} +	close(skfd);  	fclose(fp);  	return if_list;  } @@ -136,8 +142,11 @@ void if_getstat(const char *ifname, struct if_stat *stat)  	char line[0x100];  	unsigned long d;  	char *lp; -	FILE *fp = open_proc_net("dev"); +	const char path[] = "/proc/net/dev"; +	FILE *fp = fopen(path, "r"); +	if (fp == NULL) +		err_sys("can not open %s", path);  	/*  	 * Inter-|   Receive                                                | Transmit  	 *  face |bytes    packets errs drop fifo frame compressed multicast|bytes packets @@ -255,12 +255,7 @@ struct scan_result {  	struct scan_result *next;  }; -typedef int (*scan_cmp_func)(const struct scan_result *, const struct scan_result *); -extern int      cmp_sig(const struct scan_result *a, const struct scan_result *b); -extern int cmp_freq_sig(const struct scan_result *a, const struct scan_result *b); - -extern struct scan_result *get_scan_list(int skfd, const char *ifname, int we_version, -					 scan_cmp_func cmp_scan_result); +extern struct scan_result *get_scan_list(int skfd, const char *ifname, int we_version);  extern void free_scan_result(struct scan_result *head);  /* @@ -547,25 +547,65 @@ static void iw_extract_ie(struct iw_event *iwe, struct scan_result *sr)  }  /*----------------- End of code copied from iwlib -----------------------*/ +/* + * Ordering functions for scan results + */ +/* Order by ascending frequency. */ +static int cmp_chan(const struct scan_result *a, const struct scan_result *b) +{ +	return a->freq < b->freq; +} + +static int cmp_chan_rev(const struct scan_result *a, const struct scan_result *b) +{ +	return cmp_chan(b, a); +} +  /* Order by descending signal strength. */ -extern int cmp_sig(const struct scan_result *a, const struct scan_result *b) +static int cmp_sig(const struct scan_result *a, const struct scan_result *b)  {  	return a->qual.level - b->qual.level;  }  /* Order by ascending frequency first, then by descending signal strength. */ -extern int cmp_freq_sig(const struct scan_result *a, const struct scan_result *b) +static int cmp_chan_sig(const struct scan_result *a, const struct scan_result *b) +{ +	return a->freq == b->freq ? cmp_sig(a, b) : cmp_chan(a, b); +} + +/* Show open access points first, ordered by mode. */ +static int cmp_open(const struct scan_result *a, const struct scan_result *b) +{ +	return a->has_key > b->has_key; +} + +/* Sort (open) access points by descending signal strength. */ +static int cmp_open_sig(const struct scan_result *a, const struct scan_result *b) +{ +	return a->has_key == b->has_key ? cmp_sig(a, b) : cmp_open(a, b); +} + +/* Sort (open) access points by ascending frequency, then by descending signal. */ +static int cmp_open_chan_sig(const struct scan_result *a, const struct scan_result *b)  { -	return a->freq == b->freq ? cmp_sig(a, b) : a->freq < b->freq; +	return a->has_key == b->has_key ? cmp_chan_sig(a, b) : cmp_open(a, b);  } -struct scan_result *get_scan_list(int skfd, const char *ifname, int we_version, -				  scan_cmp_func cmp_scan_result) +static int (*scan_cmp[])(const struct scan_result *, const struct scan_result *) = { +	[SO_CHAN]	= cmp_chan, +	[SO_CHAN_REV]	= cmp_chan_rev, +	[SO_SIGNAL]	= cmp_sig, +	[SO_OPEN]	= cmp_open, +	[SO_CHAN_SIG]	= cmp_chan_sig, +	[SO_OPEN_SIG]	= cmp_open_sig, +	[SO_OPEN_CH_SI]	= cmp_open_chan_sig +}; + +struct scan_result *get_scan_list(int skfd, const char *ifname, int we_version)  {  	struct scan_result *head = NULL;  	struct iwreq wrq;  	int wait, waited = 0; -  	/*  	 * Some drivers may return very large scan results, either because there  	 * are many cells, or there are many large elements. Do not bother to @@ -649,7 +689,7 @@ struct scan_result *get_scan_list(int skfd, const char *ifname, int we_version,  				f = 0; -				while (cur && cmp_scan_result(cur, new) > 0) +				while (cur && scan_cmp[conf.scan_sort_order](cur, new) > 0)  					prev = &cur->next, cur = cur->next;  				*prev     = new; @@ -52,8 +52,11 @@ static char *fmt_scan_result(struct scan_result *cur, struct iw_range *iw_range,  	if (cur->freq < 1e3)  		len += snprintf(buf + len, buflen - len, ", Chan %2.0f",  				cur->freq); +	else if (channel >= 0 && cur->freq < 5e9) +		len += snprintf(buf + len, buflen - len, ", ch %2d, %g MHz", +				channel, cur->freq / 1e6);  	else if (channel >= 0) -		len += snprintf(buf + len, buflen - len, ", Ch %2d, %g MHz", +		len += snprintf(buf + len, buflen - len, ", CH %3d, %g MHz",  				channel, cur->freq / 1e6);  	else  		len += snprintf(buf + len, buflen - len, ", %g GHz", @@ -84,7 +87,7 @@ static void display_aplist(WINDOW *w_aplst)  	iw_getinf_range(conf_ifname(), &range);  	head = get_scan_list(skfd, conf_ifname(), -			     range.we_version_compiled, cmp_freq_sig); +			     range.we_version_compiled);  	if (head) {  		;  	} else if (errno == EPERM || !has_net_admin_capability()) { @@ -168,8 +171,8 @@ void scr_aplst_init(void)  {  	w_aplst = newwin_title(0, WAV_HEIGHT, "Scan window", false);  	/* -	 * Both parent and child process write to the terminal, updating  -	 * different areas of the screen. Suspending wavemon brings the  +	 * Both parent and child process write to the terminal, updating +	 * different areas of the screen. Suspending wavemon brings the  	 * terminal state out of order, messing up the screen. The choice  	 * is between a more  complicated (sophisticated) handling of  	 * signals, and to keep it simple by not allowing to suspend. @@ -1,4 +1,4 @@ -.TH wavemon 1 "February 2011" Linux "User Manuals" +.TH wavemon 1 "March 2012" Linux "User Manuals"  .SH NAME  wavemon \- a wireless network monitor  .SH SYNOPSIS @@ -125,11 +125,8 @@ print version information and exit.  .IP "LC_NUMERIC"  Influences the grouping of numbers if set. See also \fBlocale\fR(1).  .SH FILES -.I $HOME/.wavemonrc -\   the local per-user configuration file. -.br -.I /proc/net/wireless -\ wireless extensions /proc interface +.IP $HOME/.wavemonrc +The local per-user configuration file.  .SH "AUTHOR"  Written by Jan Morgenstern <jan@jm-music.de>.  .SH "REPORTING BUGS" @@ -33,13 +33,13 @@  #include <ctype.h>  #include <math.h>  #include <stdbool.h> -  #include <ncurses.h>  #include "llist.h"  #define CFNAME	".wavemonrc" -/* + +/**   * Minimum screen dimensions.   * The number of lines depends on the size requirements of scr_info(). The   * number of columns comes from the menubar length (10 items of length 6 @@ -100,6 +100,19 @@ static inline void threshold_action(enum threshold_action action)  }  /* + * Symbolic names for scan sort order comparison. + */ +enum scan_sort_order { +	SO_CHAN, +	SO_CHAN_REV, +	SO_SIGNAL, +	SO_OPEN, +	SO_CHAN_SIG, +	SO_OPEN_SIG, +	SO_OPEN_CH_SI +}; + +/*   * Global in-memory representation of current wavemon configuration state   */  extern struct wavemon_conf { @@ -124,7 +137,8 @@ extern struct wavemon_conf {  		override_bounds;	/* override autodetection */  	/* Enumerated values */ -	int	lthreshold_action,	/* disabled|beep|flash|beep+flash */ +	int	scan_sort_order,	/* channel|signal|open|chan/sig ... */ +		lthreshold_action,	/* disabled|beep|flash|beep+flash */  		hthreshold_action,	/* disabled|beep|flash|beep+flash */  		startup_scr;		/* info|histogram|aplist */  } conf; @@ -257,7 +271,7 @@ static inline int cp_from_scale(float value, const char *cscale, bool reverse)   *	Wireless interfaces   */  extern const char *conf_ifname(void); -extern void conf_get_interface_list(void); +extern void conf_get_interface_list(bool init);  extern char **iw_get_interface_list(void);  extern void dump_parameters(void); diff --git a/wavemonrc.5 b/wavemonrc.5 index 67dea89..87dc89a 100644 --- a/wavemonrc.5 +++ b/wavemonrc.5 @@ -1,4 +1,4 @@ -.TH wavemonrc 5 "December 2010" Linux "User Manuals" +.TH wavemonrc 5 "March 2012" Linux "User Manuals"  .SH NAME  $HOME/.wavemonrc \- wavemon configuration file  .SH DESCRIPTION @@ -10,7 +10,7 @@ on-screen name is shown in parentheses.  .B interface = <ifname>  .RS  .RE -.R (Interface) +(Interface)  .RS  Selects the wireless interface to use.  .P @@ -18,16 +18,28 @@ Selects the wireless interface to use.  .B cisco_mac = (on|off)  .RS  .RE -.R (Cisco-style MAC addresses) +(Cisco-style MAC addresses)  .RS  If enabled, display MAC addresses using lower-case hex digits separated by dots  rather than colons.  .P  .RE +.B sort_order = (channel|rev channel|signal|open|chan/sig|open/sig|open/chan/sig) +.RS +.RE +(Scan Sort Order) +.RS +Determines the ordering used in the scan window: (\fIrev\fR) \fIchannel\fR sorts in ascending +(descending) order of channel number, \fIsignal\fR in descending order of signal strength, and +\fIopen\fR in descending order of openness. The combined variants \fIchan/sig\fR and +\fIopen/sig\fR sort first by channel/openness and then by signal strength; their combined +functionality is provided by \fIopen/chan/sig\fR. +.P +.RE  .B stat_updates = <n>  .RS  .RE -.R (Statistics updates) +(Statistics updates)  .RS  Time interval for polling new statistics (including scan refresh). Range: 10..4000ms.  .P @@ -35,7 +47,7 @@ Time interval for polling new statistics (including scan refresh). Range: 10..40  .B lhist_slot_size = <n>  .RS  .RE -.R (Histogram update cycles) +(Histogram update cycles)  .RS  Number of samples used per each histogram slot. For example, if the stat_updates  interval is 500ms and the histogram slot size is 4, the histogram is moved @@ -45,7 +57,7 @@ one slot further every 2 seconds. Range: 1..64.  .B meter_smoothness = <n>  .RS  .RE -.R (Level meter smoothness) +(Level meter smoothness)  .RS  Determines the responsiveness of level meters, tracking the moving average  rather than following each new sample. The given value specifies the percentage @@ -56,7 +68,7 @@ this option. Range: 0..99%.  .B info_updates = <n>  .RS  .RE -.R (Dynamic info updates) +(Dynamic info updates)  .RS  Sets refresh rate for dynamic device parameters (e.g. bitrate) and the  refresh interval for the Scan window (F3). Range: 1..60s. @@ -65,7 +77,7 @@ refresh interval for the Scan window (F3). Range: 1..60s.  .B override_auto_scale = (on|off)  .RS  .RE -.R (Override scale autodetect) +(Override scale autodetect)  .RS  Override the auto-scaling of the bar graphs and histogram, allowing you to set your own scales.  .P @@ -73,24 +85,24 @@ Override the auto-scaling of the bar graphs and histogram, allowing you to set y  .B min_signal_level, max_signal_level = <n>  .RS  .RE -.R (Minimum signal level, Maximum signal level) +(Minimum signal level, Maximum signal level)  .RS -Set the left and right boundaries of the signal level scales. Ranges: -128..-60dBm (minimum) and -59..120dBm (maximum). +Set the left and right boundaries of the signal level scales. Ranges: \-128..\-60dBm (minimum) and \-59..120dBm (maximum).  .P  .RE  .B min_noise_level, max_noise_level = <n>  .RS  .RE -.R (Minimum noise level, Maximum noise level) +(Minimum noise level, Maximum noise level)  .RS -These work similar to the signal boundary settings. Ranges: -128..-60dBm -(minimum) and -60..120dBm (maximum). +These work similar to the signal boundary settings. Ranges: \-128..\-60dBm +(minimum) and \-60..120dBm (maximum).  .P  .RE  .B random = (on|off)  .RS  .RE -.R (Random signals) +(Random signals)  .RS  Switches on a fancy random generator for testing.  .P @@ -98,7 +110,7 @@ Switches on a fancy random generator for testing.  .B lo_threshold_action = (disabled|beep|flash|beep+flash)  .RS  .RE -.R (Low threshold action) +(Low threshold action)  .RS  Issue a warning  at a given threshold at the lower end of the signal  scale. It is meant for alarming you when a signal appears at the receiver. @@ -107,16 +119,16 @@ scale. It is meant for alarming you when a signal appears at the receiver.  .B lo_threshold = <n>  .RS  .RE -.R (Low threshold) +(Low threshold)  .RS  Sets the threshold value for the 'Low threshold action'. -Range: -120..-60dBm. +Range: \-120..\-60dBm.  .P  .RE  .B hi_threshold_action = (disabled|beep|flash|beep+flash)  .RS  .RE -.R (High threshold action) +(High threshold action)  .RS  Analogous to lo_threshold_action, only this time the threshold is at  the upper end of the scale and the action is performed when the signal level @@ -128,15 +140,15 @@ will tell you when you should move closer to the base station.  .B hi_threshold = <n>  .RS  .RE -.R (High threshold) +(High threshold)  .RS -Sets the threshold for the 'High threshold action'. Range: -59..120dBm. +Sets the threshold for the 'High threshold action'. Range: \-59..120dBm.  .P  .RE  .B startup_screen = (info|histogram|scan window)  .RS  .RE -.R (Startup screen) +(Startup screen)  .RS  Which of the screens appears at program startup.  .SH "AUTHOR" | 
