root/lm-sensors/branches/lm-sensors-3.0.0/prog/sensord/chips.c @ 5163

Revision 5163, 10.5 KB (checked in by khali, 6 years ago)

Patch from Aurelien Jarno:

I have just noticed that the FSF address is the old one in all files
except COPYING. Please find a patch below to fix that.

  • 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 *
37fmtExtra
38(int alarm, int beep) {
39  if (alarm)
40    sprintf (buff + strlen (buff), " [ALARM]");
41  if (beep)
42    sprintf (buff + strlen (buff), " (beep)");
43  return buff;
44}
45
46static const char *
47fmtTemps_1
48(const double values[], int alarm, int beep) {
49  sprintf (buff, "%.1f C (limit = %.1f C, hysteresis = %.1f C)", values[0], values[1], values[2]);
50  return fmtExtra (alarm, beep);
51}
52
53static const char *
54fmtTemps_minmax_1
55(const double values[], int alarm, int beep) {
56 sprintf (buff, "%.1f C (min = %.1f C, max = %.1f C)", values[0], values[1], values[2]);
57 return fmtExtra (alarm, beep);
58}
59
60static const char *
61fmtTemp_only
62(const double values[], int alarm, int beep) {
63  sprintf (buff, "%.1f C", values[0]);
64  return fmtExtra (alarm, beep);
65}
66
67static const char *
68fmtVolt_2
69(const double values[], int alarm, int beep) {
70  sprintf (buff, "%+.2f V", values[0]);
71  return fmtExtra (alarm, beep);
72}
73
74static const char *
75fmtVolt_3
76(const double values[], int alarm, int beep) {
77  sprintf (buff, "%+.3f V", values[0]);
78  return fmtExtra (alarm, beep);
79}
80
81static const char *
82fmtVolts_2
83(const double values[], int alarm, int beep) {
84  sprintf (buff, "%+.2f V (min = %+.2f V, max = %+.2f V)", values[0], values[1], values[2]);
85  return fmtExtra (alarm, beep);
86}
87
88static const char *
89fmtFans_0
90(const double values[], int alarm, int beep) {
91  sprintf (buff, "%.0f RPM (min = %.0f RPM, div = %.0f)", values[0], values[1], values[2]);
92  return fmtExtra (alarm, beep);
93}
94
95static const char *
96fmtFans_nodiv_0
97(const double values[], int alarm, int beep) {
98  sprintf (buff, "%.0f RPM (min = %.0f RPM)", values[0], values[1]);
99  return fmtExtra (alarm, beep);
100}
101
102static const char *
103fmtFan_only
104(const double values[], int alarm, int beep) {
105  sprintf (buff, "%.0f RPM", values[0]);
106  return fmtExtra (alarm, beep);
107}
108
109static const char *
110fmtSoundAlarm
111(const double values[], int alarm, int beep) {
112  sprintf (buff, "Sound alarm %s", (values[0] < 0.5) ? "disabled" : "enabled");
113  return fmtExtra (alarm, beep);
114}
115
116static const char *
117rrdF0
118(const double values[]) {
119  sprintf (buff, "%.0f", values[0]);
120  return buff;
121}
122
123static const char *
124rrdF1
125(const double values[]) {
126  sprintf (buff, "%.1f", values[0]);
127  return buff;
128}
129
130static const char *
131rrdF2
132(const double values[]) {
133  sprintf (buff, "%.2f", values[0]);
134  return buff;
135}
136
137static const char *
138rrdF3
139(const double values[]) {
140  sprintf (buff, "%.3f", values[0]);
141  return buff;
142}
143
144static void fillChipVoltage (FeatureDescriptor *voltage,
145                             const sensors_chip_name *name,
146                             const sensors_feature *feature)
147{
148  const sensors_subfeature *sf, *sfmin, *sfmax;
149  int pos = 0;
150
151  voltage->rrd = rrdF2;
152  voltage->type = DataType_voltage;
153
154  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_INPUT);
155  if (sf)
156    voltage->dataNumbers[pos++] = sf->number;
157
158  sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MIN);
159  sfmax = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MAX);
160  if (sfmin && sfmax) {
161    voltage->format = fmtVolts_2;
162    voltage->dataNumbers[pos++] = sfmin->number;
163    voltage->dataNumbers[pos++] = sfmax->number;
164  } else {
165    voltage->format = fmtVolt_2;
166  }
167 
168  /* terminate the list */
169  voltage->dataNumbers[pos] = -1;
170
171  /* alarm if applicable */
172  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_ALARM)) ||
173      (sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MIN_ALARM)) ||
174      (sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MAX_ALARM))) {
175    voltage->alarmNumber = sf->number;
176  } else {
177    voltage->alarmNumber = -1;
178  }
179  /* beep if applicable */
180  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_BEEP))) {
181    voltage->beepNumber = sf->number;
182  } else {
183    voltage->beepNumber = -1;
184  }
185}
186
187static void fillChipTemperature (FeatureDescriptor *temperature,
188                                 const sensors_chip_name *name,
189                                 const sensors_feature *feature)
190{
191  const sensors_subfeature *sf, *sfmin, *sfmax, *sfhyst;
192  int pos = 0;
193
194  temperature->rrd = rrdF1;
195  temperature->type = DataType_temperature;
196
197  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
198  if (sf)
199    temperature->dataNumbers[pos++] = sf->number;
200
201  sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MIN);
202  sfmax = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX);
203  sfhyst = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX_HYST);
204  if (sfmin && sfmax) {
205    temperature->format = fmtTemps_minmax_1;
206    temperature->dataNumbers[pos++] = sfmin->number;
207    temperature->dataNumbers[pos++] = sfmax->number;
208  } else if (sfmax && sfhyst) {
209    temperature->format = fmtTemps_1;
210    temperature->dataNumbers[pos++] = sfmax->number;
211    temperature->dataNumbers[pos++] = sfhyst->number;
212  } else {
213    temperature->format = fmtTemp_only;
214  }
215 
216  /* terminate the list */
217  temperature->dataNumbers[pos] = -1;
218
219  /* alarm if applicable */
220  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_ALARM)) ||
221      (sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX_ALARM))) {
222    temperature->alarmNumber = sf->number;
223  } else {
224    temperature->alarmNumber = -1;
225  }
226  /* beep if applicable */
227  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_BEEP))) {
228    temperature->beepNumber = sf->number;
229  } else {
230    temperature->beepNumber = -1;
231  }
232}
233
234static void fillChipFan (FeatureDescriptor *fan,
235                         const sensors_chip_name *name,
236                         const sensors_feature *feature)
237{
238  const sensors_subfeature *sf, *sfmin, *sfdiv;
239  int pos = 0;
240
241  fan->rrd = rrdF0;
242  fan->type = DataType_rpm;
243
244  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_INPUT);
245  if (sf)
246    fan->dataNumbers[pos++] = sf->number;
247
248  sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_MIN);
249  if (sfmin) {
250    fan->dataNumbers[pos++] = sfmin->number;
251    sfdiv = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_DIV);
252    if (sfdiv) {
253      fan->format = fmtFans_0;
254      fan->dataNumbers[pos++] = sfdiv->number;
255    } else {
256      fan->format = fmtFans_nodiv_0;
257    }
258  } else {
259      fan->format = fmtFan_only;
260  }
261 
262  /* terminate the list */
263  fan->dataNumbers[pos] = -1;
264
265  /* alarm if applicable */
266  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_ALARM);
267  if (sf) {
268    fan->alarmNumber = sf->number;
269  } else {
270    fan->alarmNumber = -1;
271  }
272  /* beep if applicable */
273  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_BEEP);
274  if (sf) {
275    fan->beepNumber = sf->number;
276  } else {
277    fan->beepNumber = -1;
278  }
279}
280
281static void fillChipVid (FeatureDescriptor *vid,
282                         const sensors_chip_name *name,
283                         const sensors_feature *feature)
284{
285  const sensors_subfeature *sub;
286
287  sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_VID);
288  if (!sub)
289    return;
290
291  vid->format = fmtVolt_3;
292  vid->rrd = rrdF3;
293  vid->type = DataType_voltage;
294  vid->alarmNumber = -1;
295  vid->beepNumber = -1;
296  vid->dataNumbers[0] = sub->number;
297  vid->dataNumbers[1] = -1;
298}
299
300static void fillChipBeepEnable (FeatureDescriptor *beepen,
301                                const sensors_chip_name *name,
302                                const sensors_feature *feature)
303{
304  const sensors_subfeature *sub;
305
306  sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_BEEP_ENABLE);
307  if (!sub)
308    return;
309
310  beepen->format = fmtSoundAlarm;
311  beepen->rrd = rrdF0;
312  beepen->type = DataType_other;
313  beepen->alarmNumber = -1;
314  beepen->beepNumber = -1;
315  beepen->dataNumbers[0] = sub->number;
316  beepen->dataNumbers[1] = -1;
317}
318
319static
320FeatureDescriptor * generateChipFeatures (const sensors_chip_name *chip)
321{
322        int nr, count = 1;
323        const sensors_feature *sensor;
324        FeatureDescriptor *features;
325
326        /* How many main features do we have? */
327        nr = 0;
328        while ((sensor = sensors_get_features(chip, &nr)))
329                count++;
330
331        /* Allocate the memory we need */
332        features = calloc(count, sizeof(FeatureDescriptor));
333        if (!features)
334                return NULL;
335
336        /* Fill in the data structures */
337        count = 0;
338        nr = 0;
339        while ((sensor = sensors_get_features(chip, &nr))) {
340                switch (sensor->type) {
341                case SENSORS_FEATURE_TEMP:
342                        fillChipTemperature(&features[count], chip, sensor);
343                        break;
344                case SENSORS_FEATURE_IN:
345                        fillChipVoltage(&features[count], chip, sensor);
346                        break;
347                case SENSORS_FEATURE_FAN:
348                        fillChipFan(&features[count], chip, sensor);
349                        break;
350                case SENSORS_FEATURE_VID:
351                        fillChipVid(&features[count], chip, sensor);
352                        break;
353                case SENSORS_FEATURE_BEEP_ENABLE:
354                        fillChipBeepEnable(&features[count], chip, sensor);
355                        break;
356                default:
357                        continue;
358                }
359
360                features[count].feature = sensor;
361                count++;
362        }
363
364        return features;
365}
366
367ChipDescriptor * knownChips;
368
369int initKnownChips (void)
370{
371  int nr, count = 1;
372  const sensors_chip_name *name;
373
374  /* How many chips do we have? */
375  nr = 0;
376  while ((name = sensors_get_detected_chips(NULL, &nr)))
377    count++;
378
379  /* Allocate the memory we need */
380  knownChips = calloc(count, sizeof(ChipDescriptor));
381  if (!knownChips)
382    return 1;
383
384  /* Fill in the data structures */
385  count = 0;
386  nr = 0;
387  while ((name = sensors_get_detected_chips(NULL, &nr))) {
388    knownChips[count].name = name;
389    if ((knownChips[count].features = generateChipFeatures(name)))
390      count++;
391  }
392
393  return 0;
394}
395
396void freeKnownChips (void)
397{
398  int index0;
399
400  for (index0 = 0; knownChips[index0].features; index0++)
401    free (knownChips[index0].features);
402  free (knownChips);
403}
Note: See TracBrowser for help on using the browser.