summaryrefslogtreecommitdiff
path: root/src/pmdas/roomtemp/roomtemp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/roomtemp/roomtemp.c')
-rw-r--r--src/pmdas/roomtemp/roomtemp.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/src/pmdas/roomtemp/roomtemp.c b/src/pmdas/roomtemp/roomtemp.c
new file mode 100644
index 0000000..510cf7c
--- /dev/null
+++ b/src/pmdas/roomtemp/roomtemp.c
@@ -0,0 +1,211 @@
+/*
+ * Roomtemp PMDA
+ *
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "pmapi.h"
+#include "impl.h"
+#include "pmda.h"
+#include "domain.h"
+#include "dsread.h"
+
+/*
+ * Roomtemp PMDA
+ *
+ * This PMDA exports the temperature from one or more sensors built using
+ * the DS2480 and DS1280 chipsets and MicroLAN technology from Dallas
+ * Semiconductor Corporation.
+ */
+
+/*
+ * Serial device
+ */
+static char *tty;
+
+/*
+ * list of instances
+ */
+
+static pmdaInstid *device = NULL;
+
+/*
+ * list of instance domains
+ */
+
+static pmdaIndom indomtab[] = {
+#define DEVICE 0
+ { DEVICE, 0, NULL },
+};
+
+typedef struct {
+ unsigned char sn[8];
+} sn_t;
+
+sn_t *sntab = NULL;
+
+/*
+ * All metrics supported in this PMDA - one table entry for each.
+ * The 4th field specifies the serial number of the instance domain
+ * for the metric, and must be either PM_INDOM_NULL (denoting a
+ * metric that only ever has a single value), or the serial number
+ * of one of the instance domains declared in the instance domain table
+ * (i.e. in indomtab, above).
+ */
+
+static pmdaMetric metrictab[] = {
+/* roomtemp.celsius */
+ { NULL,
+ { PMDA_PMID(0,0), PM_TYPE_FLOAT, DEVICE, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+/* roomtemp.fahrenheit */
+ { NULL,
+ { PMDA_PMID(0,1), PM_TYPE_FLOAT, DEVICE, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+};
+
+/*
+ * callback provided to pmdaFetch
+ */
+static int
+roomtemp_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+ char return_msg[128];
+ int numval = 0;
+
+ if (idp->cluster == 0) {
+ if (inst >= indomtab[DEVICE].it_numinst)
+ return PM_ERR_INST;
+ switch (idp->item) {
+ case 0: /* roomtemp.celsius */
+ case 1: /* roomtemp.fahrenheit */
+ if (!Aquire1WireNet(tty, return_msg)) {
+ fputs(return_msg, stderr);
+ exit(1);
+ }
+ if (ReadTemperature(sntab[inst].sn, &atom->f))
+ numval = 1;
+ Release1WireNet(return_msg);
+ if (idp->item == 1)
+ /* convert to fahrenheit */
+ atom->f = atom->f * 9 / 5 + 32;
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ }
+ else
+ return PM_ERR_PMID;
+
+ return numval;
+}
+
+/*
+ * Initialise the agent
+ */
+void
+roomtemp_init(pmdaInterface *dp)
+{
+ int i;
+ char return_msg[128];
+ unsigned char *p;
+
+ if (dp->status != 0)
+ return;
+
+ pmdaSetFetchCallBack(dp, roomtemp_fetchCallBack);
+
+ if (!Aquire1WireNet(tty, return_msg)) {
+ fputs(return_msg, stderr);
+ exit(1);
+ }
+ for (i = 0; ; i++) {
+ if ((p = nextsensor()) == NULL)
+ break;
+ if ((sntab = (sn_t *)realloc(sntab, (i+1) * sizeof(sn_t))) == NULL) {
+ __pmNoMem("roomtemp_init: realloc sntab", (i+1) * sizeof(sn_t), PM_FATAL_ERR);
+ }
+ if ((device = (pmdaInstid *)realloc(device, (i+1) * sizeof(pmdaInstid))) == NULL) {
+ __pmNoMem("roomtemp_init: realloc device", (i+1) * sizeof(pmdaInstid), PM_FATAL_ERR);
+ }
+ if ((device[i].i_name = (char *)malloc(17)) == NULL) {
+ __pmNoMem("roomtemp_init: malloc name", 17, PM_FATAL_ERR);
+ }
+ memcpy(sntab[i].sn, p, 8); /* SN for later fetch */
+ device[i].i_inst = i; /* internal name is ordinal number */
+ /* external name is SN in hex */
+ sprintf(device[i].i_name, "%02X%02X%02X%02X%02X%02X%02X%02X",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ fprintf(stderr, "Found temp sensor SN %s\n", device[i].i_name);
+ }
+ Release1WireNet(return_msg);
+ indomtab[DEVICE].it_numinst = i;
+ indomtab[DEVICE].it_set = device;
+
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]), metrictab,
+ sizeof(metrictab)/sizeof(metrictab[0]));
+
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options] tty ...\n\n", pmProgname);
+ fputs("Options:\n"
+ " -d domain use domain (numeric) for metrics domain of PMDA\n"
+ " -l logfile write log into logfile rather than using default log name\n"
+ "\nExactly one of the following options may appear:\n"
+ " -i port expect PMCD to connect on given inet port (number or name)\n"
+ " -p expect PMCD to supply stdin/stdout (pipe)\n"
+ " -u socket expect PMCD to connect on given unix domain socket\n"
+ " -6 port expect PMCD to connect on given ipv6 port (number or name)\n",
+ stderr);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int err = 0;
+ int sep = __pmPathSeparator();
+ pmdaInterface dispatch;
+ char mypath[MAXPATHLEN];
+
+ __pmSetProgname(argv[0]);
+
+ snprintf(mypath, sizeof(mypath), "%s%c" "roomtemp" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_3, pmProgname, ROOMTEMP,
+ "roomtemp.log", mypath);
+
+ if (pmdaGetOpt(argc, argv, "D:d:i:l:pu:6:?", &dispatch, &err) != EOF)
+ err++;
+ if (err)
+ usage();
+ if (argc != optind+1)
+ usage();
+ tty = argv[optind];
+
+ pmdaOpenLog(&dispatch);
+ roomtemp_init(&dispatch);
+ pmdaConnect(&dispatch);
+ pmdaMain(&dispatch);
+
+ exit(0);
+}