8 #define IW_ESSID_MAX_SIZE 32
13 #define WIRELESS_INFO_FLAG_HAS_ESSID (1 << 0)
14 #define WIRELESS_INFO_FLAG_HAS_QUALITY (1 << 1)
15 #define WIRELESS_INFO_FLAG_HAS_SIGNAL (1 << 2)
16 #define WIRELESS_INFO_FLAG_HAS_NOISE (1 << 3)
18 #define PERCENT_VALUE(value, total) ((int)(value * 100 / (float)total + 0.5f))
22 char essid[IW_ESSID_MAX_SIZE + 1];
33 static int get_wireless_info(const char *interface, wireless_info_t *info) {
34 memset(info, 0, sizeof(wireless_info_t));
37 int skfd = iw_sockets_open();
39 perror("iw_sockets_open");
44 if (iw_get_basic_config(skfd, interface, &wcfg) < 0) {
49 if (wcfg.has_essid && wcfg.essid_on) {
50 info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;
51 strncpy(&info->essid[0], wcfg.essid, IW_ESSID_MAX_SIZE);
52 info->essid[IW_ESSID_MAX_SIZE] = '\0';
55 /* Wireless quality is a relative value in a driver-specific range.
56 Signal and noise level can be either relative or absolute values
57 in dBm. Furthermore, noise and quality can be expressed directly
58 in dBm or in RCPI (802.11k), which we convert to dBm. When those
59 values are expressed directly in dBm, they range from -192 to 63,
60 and since the values are packed into 8 bits, we need to perform
61 8-bit arithmetic on them. Assume absolute values if everything
62 else fails (driver bug). */
65 if (iw_get_range_info(skfd, interface, &range) < 0) {
71 if (iw_get_stats(skfd, interface, &stats, &range, 1) < 0) {
76 if (stats.qual.level != 0 || (stats.qual.updated & (IW_QUAL_DBM | IW_QUAL_RCPI))) {
77 if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
78 info->quality = stats.qual.qual;
79 info->quality_max = range.max_qual.qual;
80 info->quality_average = range.avg_qual.qual;
81 info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
84 if (stats.qual.updated & IW_QUAL_RCPI) {
85 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
86 info->signal_level = stats.qual.level / 2.0 - 110 + 0.5;
87 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
89 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
90 info->noise_level = stats.qual.noise / 2.0 - 110 + 0.5;
91 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
95 if ((stats.qual.updated & IW_QUAL_DBM) || stats.qual.level > range.max_qual.level) {
96 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
97 info->signal_level = stats.qual.level;
98 if (info->signal_level > 63)
99 info->signal_level -= 256;
100 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
102 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
103 info->noise_level = stats.qual.noise;
104 if (info->noise_level > 63)
105 info->noise_level -= 256;
106 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
110 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
111 info->signal_level = stats.qual.level;
112 info->signal_level_max = range.max_qual.level;
113 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
115 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
116 info->noise_level = stats.qual.noise;
117 info->noise_level_max = range.max_qual.noise;
118 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
124 if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
125 info->quality = stats.qual.qual;
126 info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
128 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
129 info->quality = stats.qual.level;
130 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
132 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
133 info->quality = stats.qual.noise;
134 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
139 if (iw_get_ext(skfd, interface, SIOCGIWRATE, &wrq) >= 0)
140 info->bitrate = wrq.u.bitrate.value;
148 void print_wireless_info(const char *interface, const char *format_up, const char *format_down) {
150 wireless_info_t info;
151 if (get_wireless_info(interface, &info)) {
153 if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY)
154 printf("%s", info.quality < info.quality_average ? color("color_degraded") : color("color_good"));
158 printf("%s", color("color_bad"));
161 for (; *walk != '\0'; walk++) {
167 if (BEGINS_WITH(walk+1, "quality")) {
168 if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY) {
169 if (info.quality_max)
170 printf("%03d%%", PERCENT_VALUE(info.quality, info.quality_max));
172 printf("%d", info.quality);
177 walk += strlen("quality");
180 if (BEGINS_WITH(walk+1, "signal")) {
181 if (info.flags & WIRELESS_INFO_FLAG_HAS_SIGNAL) {
182 if (info.signal_level_max)
183 printf("%03d%%", PERCENT_VALUE(info.signal_level, info.signal_level_max));
185 printf("%d dBm", info.signal_level);
190 walk += strlen("signal");
193 if (BEGINS_WITH(walk+1, "noise")) {
194 if (info.flags & WIRELESS_INFO_FLAG_HAS_NOISE) {
195 if (info.noise_level_max)
196 printf("%03d%%", PERCENT_VALUE(info.noise_level, info.noise_level_max));
198 printf("%d dBm", info.noise_level);
203 walk += strlen("noise");
206 if (BEGINS_WITH(walk+1, "essid")) {
207 if (info.flags & WIRELESS_INFO_FLAG_HAS_ESSID)
208 printf("%s", info.essid);
211 walk += strlen("essid");
214 if (BEGINS_WITH(walk+1, "ip")) {
215 const char *ip_address = get_ip_addr(interface);
216 if (ip_address != NULL)
217 (void)printf("%s", get_ip_addr(interface));
218 else (void)printf("no IP");
219 walk += strlen("ip");
223 if (BEGINS_WITH(walk+1, "bitrate")) {
226 iw_print_bitrate(buffer, sizeof(buffer), info.bitrate);
228 printf("%s", buffer);
229 walk += strlen("bitrate");
234 (void)printf("%s", endcolor());