wifi.c - spoon - set dwm status | |
git clone git://git.codemadness.org/spoon | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
wifi.c (4257B) | |
--- | |
1 #include <sys/ioctl.h> | |
2 | |
3 #include <err.h> | |
4 #include <ifaddrs.h> | |
5 #include <stdio.h> | |
6 #include <string.h> | |
7 #include <unistd.h> | |
8 | |
9 #include "util.h" | |
10 | |
11 void | |
12 wifiprint(char *buf, size_t len, int quality) | |
13 { | |
14 char *icon; | |
15 | |
16 if (quality == 100) | |
17 icon = "::"; | |
18 else if (quality >= 75) | |
19 icon = ":."; | |
20 else if (quality >= 50) | |
21 icon = ".."; | |
22 else if (quality >= 25) | |
23 icon = ". "; | |
24 else | |
25 icon = " "; | |
26 snprintf(buf, len, "%s", icon); | |
27 } | |
28 | |
29 #ifdef __OpenBSD__ | |
30 #include <sys/types.h> | |
31 #include <sys/socket.h> | |
32 #include <sys/select.h> | |
33 | |
34 #include <net/if.h> | |
35 #include <net/if_media.h> | |
36 #include <net80211/ieee80211.h> | |
37 #include <net80211/ieee80211_ioctl.h> | |
38 | |
39 int | |
40 wifiread(void *arg, char *buf, size_t len) | |
41 { | |
42 struct ifaddrs *ifa, *ifas; | |
43 struct ifmediareq ifmr; | |
44 struct ieee80211_nodereq nr; | |
45 struct ieee80211_bssid bssid; | |
46 int quality = -1; | |
47 int fd, ibssid; | |
48 | |
49 if (getifaddrs(&ifas) < 0) { | |
50 warn("getifaddrs"); | |
51 return -1; | |
52 } | |
53 fd = socket(AF_INET, SOCK_DGRAM, 0); | |
54 if (fd < 0) { | |
55 warn("socket"); | |
56 return -1; | |
57 } | |
58 for (ifa = ifas; ifa; ifa = ifa->ifa_next) { | |
59 memset(&ifmr, 0, sizeof(ifmr)); | |
60 strlcpy(ifmr.ifm_name, ifa->ifa_name, IF_NAMESIZE); | |
61 if (ioctl(fd, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) | |
62 continue; | |
63 if ((ifmr.ifm_active & IFM_IEEE80211) == 0) | |
64 continue; | |
65 if ((ifmr.ifm_active & IFM_IEEE80211_HOSTAP) != 0) | |
66 continue; | |
67 memset(&bssid, 0, sizeof(bssid)); | |
68 strlcpy(bssid.i_name, ifa->ifa_name, sizeof(bssid.i_name… | |
69 ibssid = ioctl(fd, SIOCG80211BSSID, &bssid); | |
70 if (ibssid < 0) | |
71 continue; | |
72 memset(&nr, 0, sizeof(nr)); | |
73 memcpy(&nr.nr_macaddr, bssid.i_bssid, sizeof(nr.nr_macad… | |
74 strlcpy(nr.nr_ifname, ifa->ifa_name, sizeof(nr.nr_ifname… | |
75 if (ioctl(fd, SIOCG80211NODE, &nr) < 0) | |
76 continue; | |
77 if (nr.nr_rssi == 0) | |
78 continue; | |
79 if (nr.nr_max_rssi == 0) { | |
80 if (nr.nr_rssi <= -100) | |
81 quality = 0; | |
82 else if (nr.nr_rssi >= -50) | |
83 quality = 100; | |
84 else | |
85 quality = 2 * (nr.nr_rssi + 100); | |
86 } else { | |
87 quality = IEEE80211_NODEREQ_RSSI(&nr); | |
88 } | |
89 break; | |
90 } | |
91 close(fd); | |
92 freeifaddrs(ifas); | |
93 | |
94 DPRINTF_D(quality); | |
95 if (quality == -1) | |
96 return -1; | |
97 wifiprint(buf, len, quality); | |
98 return 0; | |
99 } | |
100 #elif __linux__ | |
101 #include <sys/types.h> | |
102 #include <sys/socket.h> | |
103 | |
104 #include <linux/wireless.h> | |
105 | |
106 int | |
107 wifiread(void *arg, char *buf, size_t len) | |
108 { | |
109 struct ifaddrs *ifa, *ifas; | |
110 struct iw_quality *max_qual, *qual; | |
111 struct iw_statistics stats; | |
112 struct iw_range range; | |
113 struct iwreq wrq; | |
114 int quality = -1; | |
115 int level; | |
116 int ret, fd; | |
117 | |
118 if (getifaddrs(&ifas) < 0) { | |
119 warn("getifaddrs"); | |
120 return -1; | |
121 } | |
122 fd = socket(PF_INET, SOCK_DGRAM, 0); | |
123 if (fd == -1) { | |
124 warn("socket"); | |
125 return -1; | |
126 } | |
127 for (ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) { | |
128 DPRINTF_S(ifa->ifa_name); | |
129 memset(&wrq, 0, sizeof(wrq)); | |
130 strlcpy(wrq.ifr_name, ifa->ifa_name, IFNAMSIZ); | |
131 ret = ioctl(fd, SIOCGIWNAME, &wrq); | |
132 if (ret != 0) | |
133 continue; | |
134 memset(&wrq, 0, sizeof(wrq)); | |
135 strlcpy(wrq.ifr_name, ifa->ifa_name, IFNAMSIZ); | |
136 wrq.u.data.pointer = ⦥ | |
137 wrq.u.data.length = sizeof(range); | |
138 memset(&range, 0, sizeof(range)); | |
139 ret = ioctl(fd, SIOCGIWRANGE, &wrq); | |
140 if (ret < 0) { | |
141 warnx("cannot get wifi range"); | |
142 continue; | |
143 } | |
144 memset(&wrq, 0, sizeof(wrq)); | |
145 strlcpy(wrq.ifr_name, ifa->ifa_name, IFNAMSIZ); | |
146 wrq.u.data.pointer = &stats; | |
147 wrq.u.data.length = sizeof(stats); | |
148 wrq.u.data.flags = 1; | |
149 memset(&stats, 0, sizeof(stats)); | |
150 ret = ioctl(fd, SIOCGIWSTATS, &wrq); | |
151 if (ret < 0) { | |
152 warnx("cannot get wifi stats"); | |
153 continue; | |
154 } | |
155 max_qual = &range.max_qual; | |
156 qual = &stats.qual; | |
157 DPRINTF_U(max_qual->qual); | |
158 DPRINTF_U(max_qual->level); | |
159 DPRINTF_U(qual->qual); | |
160 DPRINTF_U(qual->level); | |
161 if (max_qual->qual != 0) { | |
162 /* driver provides a quality metric */ | |
163 quality = (((float)qual->qual / max_qual->qual) … | |
164 } else if (max_qual->level != 0) { | |
165 /* driver provides signal strength (RSSI) */ | |
166 quality = (((float)qual->level / max_qual->level… | |
167 } else if (max_qual->level == 0) { | |
168 /* driver provides absolute dBm values */ | |
169 level = qual->level - 0x100; | |
170 if (level <= -100) | |
171 quality = 0; | |
172 else if (level >= -50) | |
173 quality = 100; | |
174 else | |
175 quality = 2 * (level + 100); | |
176 } | |
177 break; | |
178 } | |
179 close(fd); | |
180 freeifaddrs(ifas); | |
181 | |
182 DPRINTF_D(quality); | |
183 if (quality == -1) | |
184 return -1; | |
185 wifiprint(buf, len, quality); | |
186 return 0; | |
187 } | |
188 #endif |