diff --git a/lib/access.c b/lib/access.c index 57fe0784..d92b4db3 100644 --- a/lib/access.c +++ b/lib/access.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "access.h" #include "sensors.h" #include "data.h" @@ -27,6 +28,13 @@ #include "proc.h" #include "general.h" +#define GET_TYPE_REGEX "\\([[:alpha:]]\\{1,\\}\\)[[:digit:]]\\{0,\\}\\(_\\([[:alpha:]]\\{1,\\}\\)\\)\\{0,1\\}" + +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (const char *)__mptr - offsetof(type,member) );}) + static int sensors_do_this_chip_sets(sensors_chip_name name); /* Compare two chips name descriptions, to see whether they could match. @@ -497,72 +505,101 @@ int sensors_do_all_sets(void) return sensors_do_chip_sets(name); } +/* Static mappings for use by sensors_feature_get_type() */ +struct feature_type_match +{ + const char *name; + sensors_feature_type type; + + struct feature_type_match *submatches; +}; + +static struct feature_type_match temp_matches[] = { + { "max", SENSORS_FEATURE_TEMP_MAX }, + { "min", SENSORS_FEATURE_TEMP_MIN }, + { "type", SENSORS_FEATURE_TEMP_SENS }, + { "hyst", SENSORS_FEATURE_TEMP_HYST }, + { "over", SENSORS_FEATURE_TEMP_OVER }, + { "max", SENSORS_FEATURE_TEMP_MAX }, + { "min", SENSORS_FEATURE_TEMP_MIN }, + { "low", SENSORS_FEATURE_TEMP_LOW }, + { "crit", SENSORS_FEATURE_TEMP_CRIT }, + { "fault", SENSORS_FEATURE_TEMP_FAULT }, + { "alarm", SENSORS_FEATURE_TEMP_ALARM }, + { "type", SENSORS_FEATURE_TEMP_SENS }, + { 0 } +}; + +static struct feature_type_match in_matches[] = { + { "max", SENSORS_FEATURE_IN_MAX }, + { "max_alarm", SENSORS_FEATURE_IN_MAX_ALARM }, + { "min", SENSORS_FEATURE_IN_MIN }, + { "min_alarm", SENSORS_FEATURE_IN_MIN_ALARM }, + { "alarm", SENSORS_FEATURE_IN_ALARM }, + { 0 } +}; + +static struct feature_type_match fan_matches[] = { + { "min", SENSORS_FEATURE_FAN_MIN }, + { "div", SENSORS_FEATURE_FAN_DIV }, + { "alarm", SENSORS_FEATURE_FAN_ALARM }, + { "fault", SENSORS_FEATURE_FAN_FAULT }, + { 0 } +}; + +static struct feature_type_match matches[] = { + { "temp", SENSORS_FEATURE_TEMP, temp_matches }, + { "in", SENSORS_FEATURE_IN, in_matches }, + { "fan", SENSORS_FEATURE_FAN, fan_matches }, + { "vrm", SENSORS_FEATURE_VRM, 0 }, + { "vid", SENSORS_FEATURE_VID, 0 }, + { "sensor", SENSORS_FEATURE_TEMP_SENS, 0 }, + { 0 } +}; + /* Return the feature type based on the feature name */ sensors_feature_type sensors_feature_get_type( const sensors_feature_data *feature) { - const char *name; + const char *name; + regex_t preg; + regmatch_t pmatch[4]; + int size_first, size_second, retval, i; + struct feature_type_match *submatches; - /* this will only work when the sensors_chip_feature is obtained through - sensors_get_all_features */ - if (((const struct sensors_chip_feature *)feature)->sysname) - name = ((const struct sensors_chip_feature *)feature)->sysname; + /* use sysname if exists */ + if (container_of(feature, const struct sensors_chip_feature, data)->sysname) + name = container_of(feature, const struct sensors_chip_feature, data)->sysname; else name = feature->name; - if (strstr(name, "temp")) { - if (strlen(name) == 5) - return SENSORS_FEATURE_TEMP; - - if (strstr(name, "hyst")) - return SENSORS_FEATURE_TEMP_HYST; - - if (strstr(name, "over")) - return SENSORS_FEATURE_TEMP_OVER; - - if (strstr(name, "max")) - return SENSORS_FEATURE_TEMP_MAX; - - if (strstr(name, "min")) - return SENSORS_FEATURE_TEMP_MIN; - - if (strstr(name, "low")) - return SENSORS_FEATURE_TEMP_LOW; - - if (strstr(name, "crit")) - return SENSORS_FEATURE_TEMP_CRIT; - } else if (strstr(name, "in") && name[0] != 'f') { - if (strlen(name) == 3 || strstr(name, "input")) - return SENSORS_FEATURE_IN; - - if (strstr(name, "max_alarm")) - return SENSORS_FEATURE_IN_MAX_ALARM; - - if (strstr(name, "max")) - return SENSORS_FEATURE_IN_MAX; - - if (strstr(name, "min_alarm")) - return SENSORS_FEATURE_IN_MIN_ALARM; - - if (strstr(name, "min")) - return SENSORS_FEATURE_IN_MIN; - - if (strstr(name, "alarm")) - return SENSORS_FEATURE_IN_ALARM; - } else if (strstr(name, "fan")) { - if (strlen(name) == 4) - return SENSORS_FEATURE_FAN; - - if (strstr(name, "min")) - return SENSORS_FEATURE_FAN_MIN; - - if (strstr(name, "div")) - return SENSORS_FEATURE_FAN_DIV; - } else if (!strcmp(name, "vrm")) { - return SENSORS_FEATURE_VRM; - } else if (strstr(name, "vid")) { - return SENSORS_FEATURE_VID; - } + regcomp(&preg, GET_TYPE_REGEX, 0); + + retval = regexec(&preg, name, 4, pmatch, 0); + + regfree(&preg); + + if (retval == -1) + return SENSORS_FEATURE_UNKNOWN; + + size_first = pmatch[1].rm_eo - pmatch[1].rm_so; + size_second = pmatch[3].rm_eo - pmatch[3].rm_so; + + for(i = 0; matches[i].name != 0; i++) + if (!strncmp(name, matches[i].name, size_first)) + break; + + if (matches[i].name == NULL) /* no match */ + return SENSORS_FEATURE_UNKNOWN; + else if (size_second == 0) /* single type */ + return matches[i].type; + else if (matches[i].submatches == NULL) /* not single type, but no submatches */ + return SENSORS_FEATURE_UNKNOWN; + + submatches = matches[i].submatches; + for(i = 0; submatches[i].name != 0; i++) + if (!strncmp(name + pmatch[3].rm_so, submatches[i].name, size_second)) + return submatches[i].type; return SENSORS_FEATURE_UNKNOWN; } diff --git a/lib/sensors.h b/lib/sensors.h index eeaca583..8e50482b 100644 --- a/lib/sensors.h +++ b/lib/sensors.h @@ -21,6 +21,7 @@ #define LIB_SENSORS_SENSORS_H #include +#include /* Publicly accessible library functions */ @@ -147,8 +148,10 @@ extern const sensors_feature_data *sensors_get_all_features (sensors_chip_name name, int *nr1,int *nr2); typedef enum sensors_feature_type { - SENSORS_FEATURE_TEMP = 0, + SENSORS_FEATURE_TEMP = 0x0, SENSORS_FEATURE_TEMP_ALARM, + SENSORS_FEATURE_TEMP_FAULT, + SENSORS_FEATURE_TEMP_SENS, SENSORS_FEATURE_TEMP_HYST, SENSORS_FEATURE_TEMP_OVER, SENSORS_FEATURE_TEMP_MAX, @@ -158,26 +161,28 @@ typedef enum sensors_feature_type { SENSORS_FEATURE_TEMP_LIM, SENSORS_FEATURE_TEMP_CRIT, - SENSORS_FEATURE_IN, + SENSORS_FEATURE_IN = 0x100, SENSORS_FEATURE_IN_ALARM, SENSORS_FEATURE_IN_MIN, SENSORS_FEATURE_IN_MAX, SENSORS_FEATURE_IN_MIN_ALARM, SENSORS_FEATURE_IN_MAX_ALARM, - SENSORS_FEATURE_FAN, + SENSORS_FEATURE_FAN = 0x200, SENSORS_FEATURE_FAN_ALARM, + SENSORS_FEATURE_FAN_FAULT, SENSORS_FEATURE_FAN_MIN, SENSORS_FEATURE_FAN_DIV, - SENSORS_FEATURE_VID, + SENSORS_FEATURE_VID = 0x300, SENSORS_FEATURE_VRM, - SENSORS_FEATURE_UNKNOWN + SENSORS_FEATURE_UNKNOWN = INT_MAX } sensors_feature_type; -sensors_feature_type sensors_feature_get_type( - const sensors_feature_data *feature); +sensors_feature_type sensors_feature_get_type + (const sensors_feature_data *feature); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/prog/sensors/chips_generic.c b/prog/sensors/chips_generic.c index 27d65aba..b2bfb2f8 100644 --- a/prog/sensors/chips_generic.c +++ b/prog/sensors/chips_generic.c @@ -193,9 +193,23 @@ static void print_generic_chip_temp(const sensors_chip_name *name, print_temp_info_real(val, max, min, 0.0, type, 1, 1); } - /* TODO: check for FAULT */ - if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_ALARM) && - TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_ALARM)) { + /* print out temperature sensor info */ + if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_SENS)) { + int sens = (int)TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_SENS); + printf("sensor = %s ", sens == 0 ? "disabled" : + sens == 1 ? "diode" : + sens == 2 ? "transistor" : + sens == 3 ? "thermal diode" : + sens == 4 ? "thermistor" : + "unkown"); + } + + /* ALARM and FAULT features */ + if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_FAULT) && + TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_FAULT) > 0.5) { + printf(" FAULT"); + } else if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_ALARM) && + TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_ALARM) > 0.5) { printf(" ALARM"); } printf("\n");