root/lm-sensors/trunk/prog/sensord/chips.c

Revision 5797, 10.1 KB (checked in by khali, 3 years ago)

"alarm" is a glibc function, don't use this identifier for our own
variables to prevent any confusion.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * sensord
3 *
4 * A daemon that periodically logs sensor information to syslog.
5 *
6 * Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301 USA.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include "sensord.h"
29
30/* TODO: Temp in C/F */
31
32/** formatters **/
33
34static char buff[4096];
35
36static const char *fmtExtra(int alrm, int beep)
37{
38        if (alrm)
39                sprintf(buff + strlen(buff), " [ALARM]");
40        if (beep)
41                sprintf(buff + strlen(buff), " (beep)");
42        return buff;
43}
44
45static const char *fmtTemps_1(const double values[], int alrm, int beep)
46{
47        sprintf(buff, "%.1f C (limit = %.1f C, hysteresis = %.1f C)",
48                values[0], values[1], values[2]);
49        return fmtExtra(alrm, beep);
50}
51
52static const char *fmtTemps_minmax_1(const double values[], int alrm,
53                                     int beep) {
54        sprintf(buff, "%.1f C (min = %.1f C, max = %.1f C)", values[0],
55                values[1], values[2]);
56        return fmtExtra(alrm, beep);
57}
58
59static const char *fmtTemp_only(const double values[], int alrm, int beep)
60{
61        sprintf(buff, "%.1f C", values[0]);
62        return fmtExtra(alrm, beep);
63}
64
65static const char *fmtVolt_2(const double values[], int alrm, int beep)
66{
67        sprintf(buff, "%+.2f V", values[0]);
68        return fmtExtra(alrm, beep);
69}
70
71static const char *fmtVolt_3(const double values[], int alrm, int beep)
72{
73        sprintf(buff, "%+.3f V", values[0]);
74        return fmtExtra(alrm, beep);
75}
76
77static const char *fmtVolts_2(const double values[], int alrm, int beep)
78{
79        sprintf(buff, "%+.2f V (min = %+.2f V, max = %+.2f V)", values[0],
80                values[1], values[2]);
81        return fmtExtra(alrm, beep);
82}
83
84static const char *fmtFans_0(const double values[], int alrm, int beep)
85{
86        sprintf(buff, "%.0f RPM (min = %.0f RPM, div = %.0f)", values[0],
87                values[1], values[2]);
88        return fmtExtra(alrm, beep);
89}
90
91static const char *fmtFans_nodiv_0(const double values[], int alrm, int beep)
92{
93        sprintf(buff, "%.0f RPM (min = %.0f RPM)", values[0], values[1]);
94        return fmtExtra(alrm, beep);
95}
96
97static const char *fmtFan_only(const double values[], int alrm, int beep)
98{
99        sprintf(buff, "%.0f RPM", values[0]);
100        return fmtExtra(alrm, beep);
101}
102
103static const char *fmtSoundAlarm(const double values[], int alrm, int beep)
104{
105        sprintf(buff, "Sound alarm %s",
106                (values[0] < 0.5) ? "disabled" : "enabled");
107        return fmtExtra(alrm, beep);
108}
109
110static const char *rrdF0(const double values[])
111{
112        sprintf(buff, "%.0f", values[0]);
113        return buff;
114}
115
116static const char *rrdF1(const double values[])
117{
118        sprintf(buff, "%.1f", values[0]);
119        return buff;
120}
121
122static const char *rrdF2(const double values[])
123{
124        sprintf(buff, "%.2f", values[0]);
125        return buff;
126}
127
128static const char *rrdF3(const double values[])
129{
130        sprintf(buff, "%.3f", values[0]);
131        return buff;
132}
133
134static void fillChipVoltage(FeatureDescriptor *voltage,
135                            const sensors_chip_name *name,
136                            const sensors_feature *feature)
137{
138        const sensors_subfeature *sf, *sfmin, *sfmax;
139        int pos = 0;
140
141        voltage->rrd = rrdF2;
142        voltage->type = DataType_voltage;
143
144        sf = sensors_get_subfeature(name, feature,
145                                    SENSORS_SUBFEATURE_IN_INPUT);
146        if (sf)
147                voltage->dataNumbers[pos++] = sf->number;
148
149        sfmin = sensors_get_subfeature(name, feature,
150                                       SENSORS_SUBFEATURE_IN_MIN);
151        sfmax = sensors_get_subfeature(name, feature,
152                                       SENSORS_SUBFEATURE_IN_MAX);
153        if (sfmin && sfmax) {
154                voltage->format = fmtVolts_2;
155                voltage->dataNumbers[pos++] = sfmin->number;
156                voltage->dataNumbers[pos++] = sfmax->number;
157        } else {
158                voltage->format = fmtVolt_2;
159        }
160
161        /* terminate the list */
162        voltage->dataNumbers[pos] = -1;
163
164        /* alarm if applicable */
165        if ((sf = sensors_get_subfeature(name, feature,
166                                         SENSORS_SUBFEATURE_IN_ALARM)) ||
167            (sf = sensors_get_subfeature(name, feature,
168                                         SENSORS_SUBFEATURE_IN_MIN_ALARM)) ||
169            (sf = sensors_get_subfeature(name, feature,
170                                         SENSORS_SUBFEATURE_IN_MAX_ALARM))) {
171                voltage->alarmNumber = sf->number;
172        } else {
173                voltage->alarmNumber = -1;
174        }
175        /* beep if applicable */
176        if ((sf = sensors_get_subfeature(name, feature,
177                                         SENSORS_SUBFEATURE_IN_BEEP))) {
178                voltage->beepNumber = sf->number;
179        } else {
180                voltage->beepNumber = -1;
181        }
182}
183
184static void fillChipTemperature(FeatureDescriptor *temperature,
185                                const sensors_chip_name *name,
186                                const sensors_feature *feature)
187{
188        const sensors_subfeature *sf, *sfmin, *sfmax, *sfhyst;
189        int pos = 0;
190
191        temperature->rrd = rrdF1;
192        temperature->type = DataType_temperature;
193
194        sf = sensors_get_subfeature(name, feature,
195                                    SENSORS_SUBFEATURE_TEMP_INPUT);
196        if (sf)
197                temperature->dataNumbers[pos++] = sf->number;
198
199        sfmin = sensors_get_subfeature(name, feature,
200                                       SENSORS_SUBFEATURE_TEMP_MIN);
201        sfmax = sensors_get_subfeature(name, feature,
202                                       SENSORS_SUBFEATURE_TEMP_MAX);
203        sfhyst = sensors_get_subfeature(name, feature,
204                                        SENSORS_SUBFEATURE_TEMP_MAX_HYST);
205        if (sfmin && sfmax) {
206                temperature->format = fmtTemps_minmax_1;
207                temperature->dataNumbers[pos++] = sfmin->number;
208                temperature->dataNumbers[pos++] = sfmax->number;
209        } else if (sfmax && sfhyst) {
210                temperature->format = fmtTemps_1;
211                temperature->dataNumbers[pos++] = sfmax->number;
212                temperature->dataNumbers[pos++] = sfhyst->number;
213        } else {
214                temperature->format = fmtTemp_only;
215        }
216
217        /* terminate the list */
218        temperature->dataNumbers[pos] = -1;
219
220        /* alarm if applicable */
221        if ((sf = sensors_get_subfeature(name, feature,
222                                         SENSORS_SUBFEATURE_TEMP_ALARM)) ||
223            (sf = sensors_get_subfeature(name, feature,
224                                         SENSORS_SUBFEATURE_TEMP_MAX_ALARM))) {
225                temperature->alarmNumber = sf->number;
226        } else {
227                temperature->alarmNumber = -1;
228        }
229        /* beep if applicable */
230        if ((sf = sensors_get_subfeature(name, feature,
231                                         SENSORS_SUBFEATURE_TEMP_BEEP))) {
232                temperature->beepNumber = sf->number;
233        } else {
234                temperature->beepNumber = -1;
235        }
236}
237
238static void fillChipFan(FeatureDescriptor *fan,
239                        const sensors_chip_name *name,
240                        const sensors_feature *feature)
241{
242        const sensors_subfeature *sf, *sfmin, *sfdiv;
243        int pos = 0;
244
245        fan->rrd = rrdF0;
246        fan->type = DataType_rpm;
247
248        sf = sensors_get_subfeature(name, feature,
249                                    SENSORS_SUBFEATURE_FAN_INPUT);
250        if (sf)
251                fan->dataNumbers[pos++] = sf->number;
252
253        sfmin = sensors_get_subfeature(name, feature,
254                                       SENSORS_SUBFEATURE_FAN_MIN);
255        if (sfmin) {
256                fan->dataNumbers[pos++] = sfmin->number;
257                sfdiv = sensors_get_subfeature(name, feature,
258                                               SENSORS_SUBFEATURE_FAN_DIV);
259                if (sfdiv) {
260                        fan->format = fmtFans_0;
261                        fan->dataNumbers[pos++] = sfdiv->number;
262                } else {
263                        fan->format = fmtFans_nodiv_0;
264                }
265        } else {
266                fan->format = fmtFan_only;
267        }
268
269        /* terminate the list */
270        fan->dataNumbers[pos] = -1;
271
272        /* alarm if applicable */
273        sf = sensors_get_subfeature(name, feature,
274                                    SENSORS_SUBFEATURE_FAN_ALARM);
275        if (sf) {
276                fan->alarmNumber = sf->number;
277        } else {
278                fan->alarmNumber = -1;
279        }
280        /* beep if applicable */
281        sf = sensors_get_subfeature(name, feature,
282                                    SENSORS_SUBFEATURE_FAN_BEEP);
283        if (sf) {
284                fan->beepNumber = sf->number;
285        } else {
286                fan->beepNumber = -1;
287        }
288}
289
290static void fillChipVid(FeatureDescriptor *vid,
291                        const sensors_chip_name *name,
292                        const sensors_feature *feature)
293{
294        const sensors_subfeature *sub;
295
296        sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_VID);
297        if (!sub)
298                return;
299
300        vid->format = fmtVolt_3;
301        vid->rrd = rrdF3;
302        vid->type = DataType_voltage;
303        vid->alarmNumber = -1;
304        vid->beepNumber = -1;
305        vid->dataNumbers[0] = sub->number;
306        vid->dataNumbers[1] = -1;
307}
308
309static void fillChipBeepEnable(FeatureDescriptor *beepen,
310                               const sensors_chip_name *name,
311                               const sensors_feature *feature)
312{
313        const sensors_subfeature *sub;
314
315        sub = sensors_get_subfeature(name, feature,
316                                     SENSORS_SUBFEATURE_BEEP_ENABLE);
317        if (!sub)
318                return;
319
320        beepen->format = fmtSoundAlarm;
321        beepen->rrd = rrdF0;
322        beepen->type = DataType_other;
323        beepen->alarmNumber = -1;
324        beepen->beepNumber = -1;
325        beepen->dataNumbers[0] = sub->number;
326        beepen->dataNumbers[1] = -1;
327}
328
329static FeatureDescriptor * generateChipFeatures(const sensors_chip_name *chip)
330{
331        int nr, count = 1;
332        const sensors_feature *sensor;
333        FeatureDescriptor *features;
334
335        /* How many main features do we have? */
336        nr = 0;
337        while ((sensor = sensors_get_features(chip, &nr)))
338                count++;
339
340        /* Allocate the memory we need */
341        features = calloc(count, sizeof(FeatureDescriptor));
342        if (!features)
343                return NULL;
344
345        /* Fill in the data structures */
346        count = 0;
347        nr = 0;
348        while ((sensor = sensors_get_features(chip, &nr))) {
349                switch (sensor->type) {
350                case SENSORS_FEATURE_TEMP:
351                        fillChipTemperature(&features[count], chip, sensor);
352                        break;
353                case SENSORS_FEATURE_IN:
354                        fillChipVoltage(&features[count], chip, sensor);
355                        break;
356                case SENSORS_FEATURE_FAN:
357                        fillChipFan(&features[count], chip, sensor);
358                        break;
359                case SENSORS_FEATURE_VID:
360                        fillChipVid(&features[count], chip, sensor);
361                        break;
362                case SENSORS_FEATURE_BEEP_ENABLE:
363                        fillChipBeepEnable(&features[count], chip, sensor);
364                        break;
365                default:
366                        continue;
367                }
368
369                features[count].feature = sensor;
370                count++;
371        }
372
373        return features;
374}
375
376ChipDescriptor * knownChips;
377
378int initKnownChips(void)
379{
380        int nr, count = 1;
381        const sensors_chip_name *name;
382
383        /* How many chips do we have? */
384        nr = 0;
385        while ((name = sensors_get_detected_chips(NULL, &nr)))
386                count++;
387
388        /* Allocate the memory we need */
389        knownChips = calloc(count, sizeof(ChipDescriptor));
390        if (!knownChips)
391                return 1;
392
393        /* Fill in the data structures */
394        count = 0;
395        nr = 0;
396        while ((name = sensors_get_detected_chips(NULL, &nr))) {
397                knownChips[count].name = name;
398                if ((knownChips[count].features = generateChipFeatures(name)))
399                        count++;
400        }
401
402        return 0;
403}
404
405void freeKnownChips(void)
406{
407        int index0;
408
409        for (index0 = 0; knownChips[index0].features; index0++)
410                free(knownChips[index0].features);
411        free(knownChips);
412}
Note: See TracBrowser for help on using the browser.