11 #define WIRELESS_INFO_FLAG_HAS_ESSID (1 << 0)
12 #define WIRELESS_INFO_FLAG_HAS_QUALITY (1 << 1)
13 #define WIRELESS_INFO_FLAG_HAS_SIGNAL (1 << 2)
14 #define WIRELESS_INFO_FLAG_HAS_NOISE (1 << 3)
16 #define PERCENT_VALUE(value, total) ((int)(value * 100 / (float)total + 0.5f))
20 char essid[IW_ESSID_MAX_SIZE + 1];
30 static int get_wireless_info(const char *interface, wireless_info_t *info) {
31 memset(info, 0, sizeof(wireless_info_t));
34 int skfd = iw_sockets_open();
36 perror("iw_sockets_open");
41 if (iw_get_basic_config(skfd, interface, &wcfg) < 0) {
46 if (wcfg.has_essid && wcfg.essid_on) {
47 info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;
48 strncpy(&info->essid[0], wcfg.essid, IW_ESSID_MAX_SIZE);
49 info->essid[IW_ESSID_MAX_SIZE] = '\0';
52 /* Wireless quality is a relative value in a driver-specific range.
53 Signal and noise level can be either relative or absolute values
54 in dBm. Furthermore, noise and quality can be expressed directly
55 in dBm or in RCPI (802.11k), which we convert to dBm. When those
56 values are expressed directly in dBm, they range from -192 to 63,
57 and since the values are packed into 8 bits, we need to perform
58 8-bit arithmetic on them. Assume absolute values if everything
59 else fails (driver bug). */
62 if (iw_get_range_info(skfd, interface, &range) < 0) {
68 if (iw_get_stats(skfd, interface, &stats, &range, 1) < 0) {
73 if (stats.qual.level != 0 || (stats.qual.updated & (IW_QUAL_DBM | IW_QUAL_RCPI))) {
74 if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
75 info->quality = stats.qual.qual;
76 info->quality_max = range.max_qual.qual;
77 info->quality_average = range.avg_qual.qual;
78 info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
81 if (stats.qual.updated & IW_QUAL_RCPI) {
82 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
83 info->signal_level = stats.qual.level / 2.0 - 110 + 0.5;
84 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
86 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
87 info->noise_level = stats.qual.noise / 2.0 - 110 + 0.5;
88 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
92 if ((stats.qual.updated & IW_QUAL_DBM) || stats.qual.level > range.max_qual.level) {
93 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
94 info->signal_level = stats.qual.level;
95 if (info->signal_level > 63)
96 info->signal_level -= 256;
97 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
99 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
100 info->noise_level = stats.qual.noise;
101 if (info->noise_level > 63)
102 info->noise_level -= 256;
103 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
107 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
108 info->signal_level = stats.qual.level;
109 info->signal_level_max = range.max_qual.level;
110 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
112 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
113 info->noise_level = stats.qual.noise;
114 info->noise_level_max = range.max_qual.noise;
115 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
121 if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
122 info->quality = stats.qual.qual;
123 info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
125 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
126 info->quality = stats.qual.level;
127 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
129 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
130 info->quality = stats.qual.noise;
131 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
140 void print_wireless_info(const char *interface, const char *format_up, const char *format_down) {
142 wireless_info_t info;
143 if (get_wireless_info(interface, &info)) {
145 if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY)
146 printf("%s", info.quality < info.quality_average ? color("color_degraded") : color("color_good"));
150 printf("%s", color("color_bad"));
153 for (; *walk != '\0'; walk++) {
159 if (BEGINS_WITH(walk+1, "quality")) {
160 if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY) {
161 if (info.quality_max)
162 printf("%03d%%", PERCENT_VALUE(info.quality, info.quality_max));
164 printf("%d", info.quality);
169 walk += strlen("quality");
172 if (BEGINS_WITH(walk+1, "signal")) {
173 if (info.flags & WIRELESS_INFO_FLAG_HAS_SIGNAL) {
174 if (info.signal_level_max)
175 printf("%03d%%", PERCENT_VALUE(info.signal_level, info.signal_level_max));
177 printf("%d dBm", info.signal_level);
182 walk += strlen("signal");
185 if (BEGINS_WITH(walk+1, "noise")) {
186 if (info.flags & WIRELESS_INFO_FLAG_HAS_NOISE) {
187 if (info.noise_level_max)
188 printf("%03d%%", PERCENT_VALUE(info.noise_level, info.noise_level_max));
190 printf("%d dBm", info.noise_level);
195 walk += strlen("noise");
198 if (BEGINS_WITH(walk+1, "essid")) {
199 if (info.flags & WIRELESS_INFO_FLAG_HAS_ESSID)
200 printf("%s", info.essid);
203 walk += strlen("essid");
206 if (BEGINS_WITH(walk+1, "ip")) {
207 const char *ip_address = get_ip_addr(interface);
208 if (ip_address != NULL)
209 (void)printf("%s", get_ip_addr(interface));
210 else (void)printf("no IP");
211 walk += strlen("ip");
215 (void)printf("%s", endcolor());