|
|
- /* $OpenBSD: sensors.c,v 1.19 2006/06/02 21:17:01 henning Exp $ */
-
- /*
- * Copyright (c) 2006 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #include <sys/param.h>
- #include <sys/queue.h>
- #include <sys/sensors.h>
- #include <sys/sysctl.h>
- #include <sys/device.h>
- #include <sys/hotplug.h>
-
- #include <errno.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-
- #include "ntpd.h"
-
- #define SENSORS_MAX 255
- #define _PATH_DEV_HOTPLUG "/dev/hotplug"
-
- void sensor_probe(int);
- void sensor_add(struct sensor *);
- void sensor_remove(struct ntp_sensor *);
-
- struct ntpd_conf *conf;
-
- void
- sensor_init(struct ntpd_conf *c)
- {
- conf = c;
- TAILQ_INIT(&conf->ntp_sensors);
- }
-
- void
- sensor_scan(void)
- {
- int i;
-
- for (i = 0; i < SENSORS_MAX; i++)
- sensor_probe(i);
- }
-
- void
- sensor_probe(int id)
- {
- int mib[3];
- size_t len;
- struct sensor sensor;
-
- mib[0] = CTL_HW;
- mib[1] = HW_SENSORS;
- mib[2] = id;
-
- len = sizeof(sensor);
- if (sysctl(mib, 3, &sensor, &len, NULL, 0) == -1) {
- if (errno != ENOENT)
- log_warn("sensor_probe sysctl");
- return;
- }
-
- if (sensor.type == SENSOR_TIMEDELTA)
- sensor_add(&sensor);
- }
-
- void
- sensor_add(struct sensor *sensor)
- {
- struct ntp_sensor *s;
- struct ntp_conf_sensor *cs;
-
- /* check wether it is already there */
- TAILQ_FOREACH(s, &conf->ntp_sensors, entry)
- if (!strcmp(s->device, sensor->device))
- return;
-
- /* check wether it is requested in the config file */
- for (cs = TAILQ_FIRST(&conf->ntp_conf_sensors); cs != NULL &&
- strcmp(cs->device, sensor->device) && strcmp(cs->device, "*");
- cs = TAILQ_NEXT(cs, entry))
- ; /* nothing */
- if (cs == NULL)
- return;
-
- if ((s = calloc(1, sizeof(*s))) == NULL)
- fatal("sensor_add calloc");
-
- s->next = time(NULL);
- s->weight = cs->weight;
- if ((s->device = strdup(sensor->device)) == NULL)
- fatal("sensor_add strdup");
- s->sensorid = sensor->num;
-
- TAILQ_INSERT_TAIL(&conf->ntp_sensors, s, entry);
-
- log_debug("sensor %s added", s->device);
- }
-
- void
- sensor_remove(struct ntp_sensor *s)
- {
- TAILQ_REMOVE(&conf->ntp_sensors, s, entry);
- free(s->device);
- free(s);
- }
-
- void
- sensor_query(struct ntp_sensor *s)
- {
- struct sensor sensor;
- u_int32_t refid;
- int mib[3];
- size_t len;
-
- s->next = time(NULL) + SENSOR_QUERY_INTERVAL;
- if (s->update.rcvd < time(NULL) - SENSOR_DATA_MAXAGE)
- s->update.good = 0;
-
- mib[0] = CTL_HW;
- mib[1] = HW_SENSORS;
- mib[2] = s->sensorid;
- len = sizeof(sensor);
- if (sysctl(mib, 3, &sensor, &len, NULL, 0) == -1) {
- if (errno == ENOENT)
- sensor_remove(s);
- else
- log_warn("sensor_query sysctl");
- return;
- }
-
- if (sensor.flags & SENSOR_FINVALID ||
- sensor.status != SENSOR_S_OK)
- return;
-
- if (sensor.type != SENSOR_TIMEDELTA ||
- strcmp(sensor.device, s->device)) {
- sensor_remove(s);
- return;
- }
-
- if (sensor.tv.tv_sec == s->update.rcvd) /* already seen */
- return;
-
- memcpy(&refid, "HARD", sizeof(refid));
- s->update.status.refid = htonl(refid);
- s->update.offset = 0 - (float)sensor.value / 1000000000.0;
- s->update.status.stratum = 0; /* increased when sent out */
- s->update.status.rootdelay = 0;
- s->update.status.rootdispersion = 0;
- s->update.status.reftime = sensor.tv.tv_sec;
- s->update.rcvd = sensor.tv.tv_sec;
- s->update.good = 1;
-
- log_debug("sensor %s: offset %f", s->device, s->update.offset);
- }
-
- int
- sensor_hotplugfd(void)
- {
- #ifdef notyet
- int fd, flags;
-
- if ((fd = open(_PATH_DEV_HOTPLUG, O_RDONLY, 0)) == -1) {
- log_warn("open %s", _PATH_DEV_HOTPLUG);
- return (-1);
- }
-
- if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
- fatal("fnctl F_GETFL");
- flags |= O_NONBLOCK;
- if ((flags = fcntl(fd, F_SETFL, flags)) == -1)
- fatal("fnctl F_SETFL");
-
- return (fd);
- #else
- return (-1);
- #endif
- }
-
- void
- sensor_hotplugevent(int fd)
- {
- struct hotplug_event he;
- ssize_t n;
-
- do {
- if ((n = read(fd, &he, sizeof(he))) == -1 &&
- errno != EINTR && errno != EAGAIN)
- fatal("sensor_hotplugevent read");
-
- if (n == sizeof(he))
- switch (he.he_type) {
- case HOTPLUG_DEVAT:
- if (he.he_devclass == DV_DULL &&
- !strcmp(he.he_devname, "sensor"))
- sensor_scan();
- break;
- default: /* ignore */
- break;
- }
- else if (n > 0)
- fatal("sensor_hotplugevent: short read");
- } while (n > 0 || (n == -1 && errno == EINTR));
- }
|