--- a/linux.c Tue Dec 11 19:49:49 2018 +0000
+++ b/linux.c Tue Dec 11 21:02:20 2018 +0000
@@ -33,6 +33,11 @@
#include <time.h>
#include <math.h>
+#ifndef __USE_MISC
+#define __USE_MISC
+#endif
+#include <linux/wireless.h>
+
#include "mini_snmpd.h"
@@ -178,37 +183,79 @@
memset(netinfo, 0, sizeof(*netinfo));
}
+static inline int get_wireless_sn(char *ifname, double *signal, double *noise)
+{
+ int fd, rc;
+ struct iwreq iwrq;
+ struct iw_statistics iw_s;
+ struct iw_range iw_r;
+
+ *signal = *noise = 0.;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0)
+ goto error2;
+
+ bzero(&iwrq, sizeof(struct iwreq));
+ strncpy(iwrq.ifr_name, ifname, IFNAMSIZ);
+
+ bzero(&iw_s, sizeof(struct iw_statistics));
+ iwrq.u.data.pointer = &iw_s;
+ iwrq.u.data.length = sizeof(struct iw_statistics);
+
+ rc = ioctl(fd, SIOCGIWSTATS, &iwrq);
+ if (rc < 0)
+ goto error1;
+
+ if (iw_s.qual.updated & IW_QUAL_RCPI) {
+ if (!(iw_s.qual.updated & IW_QUAL_LEVEL_INVALID))
+ *signal = (iw_s.qual.level / 2.) - 110.;
+
+ if (!(iw_s.qual.updated & IW_QUAL_NOISE_INVALID))
+ *noise = (iw_s.qual.noise / 2.) - 110.;
+ }
+ else if (iw_s.qual.updated & IW_QUAL_DBM) {
+ if (!(iw_s.qual.updated & IW_QUAL_LEVEL_INVALID))
+ *signal = iw_s.qual.level - 256.;
+
+ if (!(iw_s.qual.updated & IW_QUAL_NOISE_INVALID))
+ *noise = iw_s.qual.noise - 256.;
+ }
+ else {
+ bzero(&iw_r, sizeof(struct iw_range));
+ iwrq.u.data.pointer = &iw_r;
+ iwrq.u.data.length = sizeof(struct iw_range);
+
+ rc = ioctl(fd, SIOCGIWRANGE, &iwrq);
+ if (rc < 0)
+ goto error1;
+
+ if (!(iw_s.qual.updated & IW_QUAL_LEVEL_INVALID) && iw_r.max_qual.level)
+ *signal = (100. * iw_s.qual.level) / iw_r.max_qual.level;
+
+ if (!(iw_s.qual.updated & IW_QUAL_NOISE_INVALID) && iw_r.max_qual.noise)
+ *noise = (100. * iw_s.qual.noise) / iw_r.max_qual.noise;
+ }
+
+ close(fd);
+ return 0;
+
+error1:
+ close(fd);
+error2:
+ return -1;
+}
+
void get_wirelessinfo(wirelessinfo_t *wirelessinfo)
{
- char buffer[BUFSIZ];
- char name[16];
- char *ptr;
+ double signal, noise;
size_t i;
- if (read_file("/proc/net/wireless", buffer, sizeof (buffer)) == -1) {
- buffer[0] = '\0';
- }
for (i = 0; i < g_wireless_list_length; i++) {
- if (buffer[0] != '\0') {
- snprintf(name, sizeof (name), "%s:", g_wireless_list[i]);
- ptr = strstr(buffer, name);
- if (ptr != NULL) {
- ptr += strlen(name);
- strtoul(ptr, &ptr, 0); /* Status */
+ get_wireless_sn(g_wireless_list[i], &signal, &noise);
- /* When the Quality values have been updated
- * since the last read of the entry, a dot will
- * follow that value
- */
- strtoul(ptr, &ptr, 0); /* Quality */
- wirelessinfo->signal[i] = strtoul(ptr + 1, &ptr, 0); /* Signal */
- wirelessinfo->noise[i] = strtoul(ptr + 1, &ptr, 0); /* Noise */
- } else {
- wirelessinfo->signal[i] = wirelessinfo->noise[i] = 0;
- }
- } else {
- wirelessinfo->signal[i] = wirelessinfo->noise[i] = 0;
- }
+ wirelessinfo->signal[i] = (int)(signal + .5);
+ wirelessinfo->noise[i] = (int)(noise + .5);
}
}