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];
31 static int get_wireless_info(const char *interface, wireless_info_t *info) {
32 memset(info, 0, sizeof(wireless_info_t));
35 int skfd = iw_sockets_open();
37 perror("iw_sockets_open");
42 if (iw_get_basic_config(skfd, interface, &wcfg) < 0) {
47 if (wcfg.has_essid && wcfg.essid_on) {
48 info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;
49 strncpy(&info->essid[0], wcfg.essid, IW_ESSID_MAX_SIZE);
50 info->essid[IW_ESSID_MAX_SIZE] = '\0';
53 /* Wireless quality is a relative value in a driver-specific range.
54 Signal and noise level can be either relative or absolute values
55 in dBm. Furthermore, noise and quality can be expressed directly
56 in dBm or in RCPI (802.11k), which we convert to dBm. When those
57 values are expressed directly in dBm, they range from -192 to 63,
58 and since the values are packed into 8 bits, we need to perform
59 8-bit arithmetic on them. Assume absolute values if everything
60 else fails (driver bug). */
63 if (iw_get_range_info(skfd, interface, &range) < 0) {
69 if (iw_get_stats(skfd, interface, &stats, &range, 1) < 0) {
74 if (stats.qual.level != 0 || (stats.qual.updated & (IW_QUAL_DBM | IW_QUAL_RCPI))) {
75 if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
76 info->quality = stats.qual.qual;
77 info->quality_max = range.max_qual.qual;
78 info->quality_average = range.avg_qual.qual;
79 info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
82 if (stats.qual.updated & IW_QUAL_RCPI) {
83 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
84 info->signal_level = stats.qual.level / 2.0 - 110 + 0.5;
85 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
87 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
88 info->noise_level = stats.qual.noise / 2.0 - 110 + 0.5;
89 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
93 if ((stats.qual.updated & IW_QUAL_DBM) || stats.qual.level > range.max_qual.level) {
94 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
95 info->signal_level = stats.qual.level;
96 if (info->signal_level > 63)
97 info->signal_level -= 256;
98 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
100 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
101 info->noise_level = stats.qual.noise;
102 if (info->noise_level > 63)
103 info->noise_level -= 256;
104 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
108 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
109 info->signal_level = stats.qual.level;
110 info->signal_level_max = range.max_qual.level;
111 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
113 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
114 info->noise_level = stats.qual.noise;
115 info->noise_level_max = range.max_qual.noise;
116 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
122 if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
123 info->quality = stats.qual.qual;
124 info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
126 if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
127 info->quality = stats.qual.level;
128 info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
130 if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
131 info->quality = stats.qual.noise;
132 info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
137 if (iw_get_ext(skfd, interface, SIOCGIWRATE, &wrq) >= 0)
138 info->bitrate = wrq.u.bitrate.value;
145 void print_wireless_info(const char *interface, const char *format_up, const char *format_down) {
147 wireless_info_t info;
148 if (get_wireless_info(interface, &info)) {
150 if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY)
151 printf("%s", info.quality < info.quality_average ? color("color_degraded") : color("color_good"));
155 printf("%s", color("color_bad"));
158 for (; *walk != '\0'; walk++) {
164 if (BEGINS_WITH(walk+1, "quality")) {
165 if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY) {
166 if (info.quality_max)
167 printf("%03d%%", PERCENT_VALUE(info.quality, info.quality_max));
169 printf("%d", info.quality);
174 walk += strlen("quality");
177 if (BEGINS_WITH(walk+1, "signal")) {
178 if (info.flags & WIRELESS_INFO_FLAG_HAS_SIGNAL) {
179 if (info.signal_level_max)
180 printf("%03d%%", PERCENT_VALUE(info.signal_level, info.signal_level_max));
182 printf("%d dBm", info.signal_level);
187 walk += strlen("signal");
190 if (BEGINS_WITH(walk+1, "noise")) {
191 if (info.flags & WIRELESS_INFO_FLAG_HAS_NOISE) {
192 if (info.noise_level_max)
193 printf("%03d%%", PERCENT_VALUE(info.noise_level, info.noise_level_max));
195 printf("%d dBm", info.noise_level);
200 walk += strlen("noise");
203 if (BEGINS_WITH(walk+1, "essid")) {
204 if (info.flags & WIRELESS_INFO_FLAG_HAS_ESSID)
205 printf("%s", info.essid);
208 walk += strlen("essid");
211 if (BEGINS_WITH(walk+1, "ip")) {
212 const char *ip_address = get_ip_addr(interface);
213 if (ip_address != NULL)
214 (void)printf("%s", get_ip_addr(interface));
215 else (void)printf("no IP");
216 walk += strlen("ip");
219 if (BEGINS_WITH(walk+1, "bitrate")) {
222 iw_print_bitrate(buffer, sizeof(buffer), info.bitrate);
224 printf("%s", buffer);
225 walk += strlen("bitrate");
229 (void)printf("%s", endcolor());