xref: /freebsd/tools/tools/ath/athaggrstats/main.c (revision 315ee00f)
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 
31 /*
32  * Simple Atheros-specific tool to inspect and monitor software queue
33  * and aggregate statistics.
34  *
35  *	athaggrstats [-i interface] [-bz] [-l] [-o fmtstring] [interval]
36  *
37  * (default interface is ath0).  If interval is specified a rolling output
38  * a la netstat -i is displayed every interval seconds.  The format of
39  * the rolling display can be controlled a la ps.  The -l option will
40  * print a list of all possible statistics for use with the -o option.
41  */
42 
43 #include <sys/param.h>
44 
45 #include <err.h>
46 #include <signal.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <unistd.h>
51 
52 #include "athaggrstats.h"
53 
54 static struct {
55 	const char *tag;
56 	const char *fmt;
57 } tags[] = {
58   { "default",
59     "singlepkt,nonbawpkt,aggrpkt,bawclosedpkt,lhsinglepkt,schednopkt,rtsaggrlimit"
60   },
61 };
62 
63 static const char *
64 getfmt(const char *tag)
65 {
66 	int i;
67 	for (i = 0; i < nitems(tags); i++)
68 		if (strcasecmp(tags[i].tag, tag) == 0)
69 			return tags[i].fmt;
70 	return tag;
71 }
72 
73 static int signalled;
74 
75 static void
76 catchalarm(int signo __unused)
77 {
78 	signalled = 1;
79 }
80 
81 int
82 main(int argc, char *argv[])
83 {
84 	struct athaggrstatfoo *wf;
85 	const char *ifname;
86 	int c, banner = 1;
87 
88 	ifname = getenv("ATH");
89 	if (ifname == NULL)
90 		ifname = ATH_DEFAULT;
91 	wf = athaggrstats_new(ifname, getfmt("default"));
92 	while ((c = getopt(argc, argv, "bi:lo:z")) != -1) {
93 		switch (c) {
94 		case 'b':
95 			banner = 0;
96 			break;
97 		case 'i':
98 			wf->setifname(wf, optarg);
99 			break;
100 		case 'l':
101 			wf->print_fields(wf, stdout);
102 			return 0;
103 		case 'o':
104 			wf->setfmt(wf, getfmt(optarg));
105 			break;
106 		case 'z':
107 			wf->zerostats(wf);
108 			break;
109 		default:
110 			errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [-z] [interval]\n", argv[0]);
111 			/*NOTREACHED*/
112 		}
113 	}
114 	argc -= optind;
115 	argv += optind;
116 
117 	if (argc > 0) {
118 		u_long interval = strtoul(argv[0], NULL, 0);
119 		int line, omask;
120 
121 		if (interval < 1)
122 			interval = 1;
123 		signal(SIGALRM, catchalarm);
124 		signalled = 0;
125 		alarm(interval);
126 	banner:
127 		if (banner)
128 			wf->print_header(wf, stdout);
129 		line = 0;
130 	loop:
131 		if (line != 0) {
132 			wf->collect_cur(wf);
133 			wf->print_current(wf, stdout);
134 			wf->update_tot(wf);
135 		} else {
136 			wf->collect_tot(wf);
137 			wf->print_total(wf, stdout);
138 		}
139 		fflush(stdout);
140 		omask = sigblock(sigmask(SIGALRM));
141 		if (!signalled)
142 			sigpause(0);
143 		sigsetmask(omask);
144 		signalled = 0;
145 		alarm(interval);
146 		line++;
147 		if (line == 21)		/* XXX tty line count */
148 			goto banner;
149 		else
150 			goto loop;
151 		/*NOTREACHED*/
152 	} else {
153 		wf->collect_tot(wf);
154 		wf->print_verbose(wf, stdout);
155 	}
156 	return 0;
157 }
158