add wireless measurement probe infrastructure, developed at Fraunhofer FOKUS
[openwrt/staging/florian.git] / package / wprobe / src / user / wprobe-info.c
1 /*
2 * wprobe-test.c: Wireless probe user space test code
3 * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but 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.
14 */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <inttypes.h>
20 #include <errno.h>
21 #include <stdint.h>
22 #include <getopt.h>
23 #include <stdbool.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <linux/wprobe.h>
28 #include "wprobe.h"
29
30 static const char *
31 wprobe_dump_value(struct wprobe_attribute *attr)
32 {
33 static char buf[128];
34
35 #define HANDLE_TYPE(_type, _format) \
36 case WPROBE_VAL_##_type: \
37 snprintf(buf, sizeof(buf), _format, attr->val._type); \
38 break
39
40 switch(attr->type) {
41 HANDLE_TYPE(S8, "%d");
42 HANDLE_TYPE(S16, "%d");
43 HANDLE_TYPE(S32, "%d");
44 HANDLE_TYPE(S64, "%lld");
45 HANDLE_TYPE(U8, "%d");
46 HANDLE_TYPE(U16, "%d");
47 HANDLE_TYPE(U32, "%d");
48 HANDLE_TYPE(U64, "%lld");
49 case WPROBE_VAL_STRING:
50 /* FIXME: implement this */
51 default:
52 strncpy(buf, "<unknown>", sizeof(buf));
53 break;
54 }
55 if ((attr->flags & WPROBE_F_KEEPSTAT) &&
56 (attr->val.n > 0)) {
57 int len = strlen(buf);
58 snprintf(buf + len, sizeof(buf) - len, " (avg: %.02f; stdev: %.02f, n=%d)", attr->val.avg, attr->val.stdev, attr->val.n);
59 }
60 #undef HANDLE_TYPE
61
62 return buf;
63 }
64
65
66 static void
67 wprobe_dump_data(const char *ifname, struct list_head *gl, struct list_head *ll, struct list_head *ls)
68 {
69 struct wprobe_attribute *attr;
70 struct wprobe_link *link;
71 bool first = true;
72
73 fprintf(stderr, "\n");
74 wprobe_request_data(ifname, gl, NULL, 2);
75 list_for_each_entry(attr, gl, list) {
76 fprintf(stderr, (first ?
77 "Global: %s=%s\n" :
78 " %s=%s\n"),
79 attr->name,
80 wprobe_dump_value(attr)
81 );
82 first = false;
83 }
84
85 list_for_each_entry(link, ls, list) {
86 first = true;
87 wprobe_request_data(ifname, ll, link->addr, 2);
88 list_for_each_entry(attr, ll, list) {
89 if (first) {
90 fprintf(stderr,
91 "%02x:%02x:%02x:%02x:%02x:%02x: %s=%s\n",
92 link->addr[0], link->addr[1], link->addr[2],
93 link->addr[3], link->addr[4], link->addr[5],
94 attr->name,
95 wprobe_dump_value(attr));
96 first = false;
97 } else {
98 fprintf(stderr,
99 " %s=%s\n",
100 attr->name,
101 wprobe_dump_value(attr));
102 }
103 }
104 }
105 }
106
107 static const char *attr_typestr[] = {
108 [0] = "Unknown",
109 [WPROBE_VAL_STRING] = "String",
110 [WPROBE_VAL_U8] = "Unsigned 8 bit",
111 [WPROBE_VAL_U16] = "Unsigned 16 bit",
112 [WPROBE_VAL_U32] = "Unsigned 32 bit",
113 [WPROBE_VAL_U64] = "Unsigned 64 bit",
114 [WPROBE_VAL_S8] = "Signed 8 bit",
115 [WPROBE_VAL_S16] = "Signed 16 bit",
116 [WPROBE_VAL_S32] = "Signed 32 bit",
117 [WPROBE_VAL_S64] = "Signed 64 bit",
118 };
119
120 static int usage(const char *prog)
121 {
122 fprintf(stderr, "Usage: %s <interface>\n", prog);
123 return 1;
124 }
125
126 int main(int argc, char **argv)
127 {
128 struct wprobe_attribute *attr;
129 const char *ifname;
130 LIST_HEAD(global_attr);
131 LIST_HEAD(link_attr);
132 LIST_HEAD(links);
133 int i = 0;
134
135 if (argc < 2)
136 return usage(argv[0]);
137
138 ifname = argv[1];
139
140 if (wprobe_init() != 0)
141 return -1;
142
143 wprobe_dump_attributes(ifname, false, &global_attr, NULL);
144 wprobe_dump_attributes(ifname, true, &link_attr, NULL);
145
146 if (list_empty(&global_attr) &&
147 list_empty(&link_attr)) {
148 fprintf(stderr, "Interface '%s' not found\n", ifname);
149 return -1;
150 }
151
152 list_for_each_entry(attr, &global_attr, list) {
153 fprintf(stderr, "Global attribute: '%s' (%s)\n",
154 attr->name, attr_typestr[attr->type]);
155 }
156 list_for_each_entry(attr, &link_attr, list) {
157 fprintf(stderr, "Link attribute: '%s' (%s)\n",
158 attr->name, attr_typestr[attr->type]);
159 }
160
161 while (1) {
162 usleep(100 * 1000);
163 wprobe_measure(ifname);
164
165 if (i-- > 0)
166 continue;
167
168 i = 10;
169 wprobe_update_links(ifname, &links);
170 wprobe_dump_data(ifname, &global_attr, &link_attr, &links);
171 }
172 wprobe_free();
173
174 return 0;
175 }