xref: /freebsd/tools/tools/ath/athaggrstats/main.c (revision 325151a3)
1 /*-
2  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3  *               2012, Adrian Chadd
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer,
11  *    without modification.
12  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
14  *    redistribution must be conditioned upon including a substantially
15  *    similar Disclaimer requirement for further binary redistribution.
16  *
17  * NO WARRANTY
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
21  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
23  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGES.
29  *
30  * $FreeBSD$
31  */
32 
33 /*
34  * Simple Atheros-specific tool to inspect and monitor software queue
35  * and aggregate statistics.
36  *
37  *	athaggrstats [-i interface] [-bz] [-l] [-o fmtstring] [interval]
38  *
39  * (default interface is ath0).  If interval is specified a rolling output
40  * a la netstat -i is displayed every interval seconds.  The format of
41  * the rolling display can be controlled a la ps.  The -l option will
42  * print a list of all possible statistics for use with the -o option.
43  */
44 
45 #include <sys/param.h>
46 
47 #include <err.h>
48 #include <signal.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <unistd.h>
53 
54 #include "athaggrstats.h"
55 
56 static struct {
57 	const char *tag;
58 	const char *fmt;
59 } tags[] = {
60   { "default",
61     "singlepkt,nonbawpkt,aggrpkt,bawclosedpkt,lhsinglepkt,schednopkt,rtsaggrlimit"
62   },
63 };
64 
65 static const char *
66 getfmt(const char *tag)
67 {
68 	int i;
69 	for (i = 0; i < nitems(tags); i++)
70 		if (strcasecmp(tags[i].tag, tag) == 0)
71 			return tags[i].fmt;
72 	return tag;
73 }
74 
75 static int signalled;
76 
77 static void
78 catchalarm(int signo __unused)
79 {
80 	signalled = 1;
81 }
82 
83 int
84 main(int argc, char *argv[])
85 {
86 	struct athaggrstatfoo *wf;
87 	const char *ifname;
88 	int c, banner = 1;
89 
90 	ifname = getenv("ATH");
91 	if (ifname == NULL)
92 		ifname = "ath0";
93 	wf = athaggrstats_new(ifname, getfmt("default"));
94 	while ((c = getopt(argc, argv, "bi:lo:z")) != -1) {
95 		switch (c) {
96 		case 'b':
97 			banner = 0;
98 			break;
99 		case 'i':
100 			wf->setifname(wf, optarg);
101 			break;
102 		case 'l':
103 			wf->print_fields(wf, stdout);
104 			return 0;
105 		case 'o':
106 			wf->setfmt(wf, getfmt(optarg));
107 			break;
108 		case 'z':
109 			wf->zerostats(wf);
110 			break;
111 		default:
112 			errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [-z] [interval]\n", argv[0]);
113 			/*NOTREACHED*/
114 		}
115 	}
116 	argc -= optind;
117 	argv += optind;
118 
119 	if (argc > 0) {
120 		u_long interval = strtoul(argv[0], NULL, 0);
121 		int line, omask;
122 
123 		if (interval < 1)
124 			interval = 1;
125 		signal(SIGALRM, catchalarm);
126 		signalled = 0;
127 		alarm(interval);
128 	banner:
129 		if (banner)
130 			wf->print_header(wf, stdout);
131 		line = 0;
132 	loop:
133 		if (line != 0) {
134 			wf->collect_cur(wf);
135 			wf->print_current(wf, stdout);
136 			wf->update_tot(wf);
137 		} else {
138 			wf->collect_tot(wf);
139 			wf->print_total(wf, stdout);
140 		}
141 		fflush(stdout);
142 		omask = sigblock(sigmask(SIGALRM));
143 		if (!signalled)
144 			sigpause(0);
145 		sigsetmask(omask);
146 		signalled = 0;
147 		alarm(interval);
148 		line++;
149 		if (line == 21)		/* XXX tty line count */
150 			goto banner;
151 		else
152 			goto loop;
153 		/*NOTREACHED*/
154 	} else {
155 		wf->collect_tot(wf);
156 		wf->print_verbose(wf, stdout);
157 	}
158 	return 0;
159 }
160