darwin-sensors.patch [plain text]
diff -Naur net-snmp-5.4.1.rc4/agent/mibgroup/ucd-snmp/data_access/Makefile.test net-snmp-5.4.1.rc4.patched/agent/mibgroup/ucd-snmp/data_access/Makefile.test
--- net-snmp-5.4.1.rc4/agent/mibgroup/ucd-snmp/data_access/Makefile.test 1969-12-31 16:00:00.000000000 -0800
+++ net-snmp-5.4.1.rc4.patched/agent/mibgroup/ucd-snmp/data_access/Makefile.test 2007-07-30 16:33:16.000000000 -0700
@@ -0,0 +1,20 @@
+SNMPDIR_I = $(HOME)/snmp/apple-snmp-5-4
+SNMPDIR_B = $(HOME)/snmp/build/apple-snmp-5-4
+SNMPLIBS = $(SNMPDIR_B)/snmplib/.libs/libnetsnmp.a -lcrypto
+#SNMPLIBS = `net-snmp-config --libs`
+
+HEADERS = -F/System/Library/PrivateFrameworks/ -F/System/Library/Frameworks/
+CFLAGS = -g -O0 -I$(SNMPDIR_B)/include -I$(SNMPDIR_I)/include -DTEST $(HEADERS)
+CC = gcc
+
+SWINSTLIBS = -framework CoreServices -framework CoreFoundation -framework Install
+#LIBS = /System/Library/Frameworks/CoreServices.framework/CoreServices /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation /System/Library/Frameworks/IOKit.framework/IOKit
+
+SWRUNLIBS = -framework CoreFoundation -framework ApplicationServices
+SENSORLIBS = -framework CoreServices -framework CoreFoundation -framework IOKit
+
+all: sensors
+
+
+sensors: sensors.o sensors_darwin.o
+ $(CC) $(CFLAGS) sensors.o sensors_darwin.o $(SENSORLIBS) -o sensors $(SNMPLIBS)
diff -Naur net-snmp-5.4.1.rc4/agent/mibgroup/ucd-snmp/data_access/sensors_darwin.c net-snmp-5.4.1.rc4.patched/agent/mibgroup/ucd-snmp/data_access/sensors_darwin.c
--- net-snmp-5.4.1.rc4/agent/mibgroup/ucd-snmp/data_access/sensors_darwin.c 1969-12-31 16:00:00.000000000 -0800
+++ net-snmp-5.4.1.rc4.patched/agent/mibgroup/ucd-snmp/data_access/sensors_darwin.c 2007-07-30 18:18:43.000000000 -0700
@@ -0,0 +1,1402 @@
+/*
+ * sensor_darwin.c
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/library/container.h>
+#include <net-snmp/library/snmp_debug.h>
+#include <net-snmp/data_access/sensors.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+/***********************************************************************
+ *
+ *
+ */
+
+static int do_type(netsnmp_container *container, int flags);
+static int InitDataCollection(void);
+static CFArrayRef DumpSensorData(CFStringRef inKey);
+
+/***********************************************************************
+ *
+ *
+ */
+
+const CFStringRef kFanDataKey = CFSTR("fan_data");
+const CFStringRef kTempDataKey = CFSTR("temp_data");
+const CFStringRef kVoltDataKey = CFSTR("volt_data");
+const CFStringRef kMiscDataKey = CFSTR("misc_data");
+
+const CFStringRef kDescriptionKey = CFSTR("description");
+const CFStringRef kCurrentValueKey = CFSTR("current_value");
+const CFStringRef kUnknownDescription = CFSTR("No Description available");
+
+/***********************************************************************
+ *
+ *
+ */
+void
+netsnmp_sensors_arch_init(void)
+{
+ netsnmp_container *container;
+ int result = 0;
+
+ result = InitDataCollection();
+ if(result != 0)
+ {
+ snmp_log(LOG_NOTICE,"Sensor Data Collection not supported\n");
+ return;
+ }
+
+ /*
+ * create a temporary container and load all sensors once,
+ * to establish indexes.
+ */
+ container = netsnmp_container_find("sensors:table_container");
+ if (NULL == container) {
+ snmp_log(LOG_ERR,"couldn't allocate sensor container to pre-load indexes\n");
+ return;
+ }
+ container->container_name = strdup("sensors pre-load container");
+
+ do_type(container, NETSNMP_SENSORS_GET_TEMPS);
+ netsnmp_sensors_container_free_items(container);
+
+ do_type(container, NETSNMP_SENSORS_GET_FANS);
+ netsnmp_sensors_container_free_items(container);
+
+ do_type(container, NETSNMP_SENSORS_GET_VOLTS);
+ netsnmp_sensors_container_free_items(container);
+
+ do_type(container, NETSNMP_SENSORS_GET_MISCS);
+ netsnmp_sensors_container_free_items(container);
+ CONTAINER_FREE(container);
+}
+
+void
+netsnmp_sensors_arch_shutdown(void)
+{
+
+}
+
+int
+netsnmp_sensors_arch_load(netsnmp_container *container, u_int flags)
+{
+ if (NULL == container)
+ return -1;
+
+ return do_type(container, flags);
+}
+
+
+/***********************************************************************
+ *
+ *
+ */
+static int
+do_type(netsnmp_container *container, int flags)
+{
+ netsnmp_sensor_entry *entry;
+ CFDictionaryRef tmp_dict;
+ CFStringRef key;
+ CFArrayRef data;
+ CFStringRef description;
+ CFNumberRef value;
+ char *pos;
+ size_t size, i;
+ int32_t i32, rc;
+ u_long tmp, pre_mul = 0, post_div = 0;
+ oid idx;
+
+#if defined (__ppc__) || defined (__ppc64__)
+ if(flags & NETSNMP_SENSORS_GET_TEMPS) {
+ /** temp is in degrees C = current_value/65536 */
+ pre_mul = 1000; /* want mC */
+ post_div = 65536;
+ key = kTempDataKey;
+ }
+ else if(flags & NETSNMP_SENSORS_GET_FANS) {
+ /** fan current_value is in rpm */
+ key = kFanDataKey;
+ }
+ else if(flags & NETSNMP_SENSORS_GET_VOLTS) {
+ /** voltage is in Volts = current_value/65536 */
+ pre_mul = 1000; /* want mV */
+ post_div = 65536;
+ key = kVoltDataKey;
+ }
+ else if(flags & NETSNMP_SENSORS_GET_MISCS) {
+ /** power is in Watts = current_value/65536 */
+ /** current is in Amps = current_value/65536 */
+ pre_mul = 1000; /* want m? */
+ post_div = 65536;
+ key = kMiscDataKey;
+ }
+ else
+ return -2;
+#elif defined (__i386__) || defined(__x86_64__)
+ if(flags & NETSNMP_SENSORS_GET_TEMPS) {
+ /** temp is in degrees C = current_value/65536 */
+ pre_mul = 1000; /* want mC */
+ post_div = 256;
+ key = kTempDataKey;
+ }
+ else if(flags & NETSNMP_SENSORS_GET_FANS) {
+ /** fan current_value is in rpm */
+ key = kFanDataKey;
+ }
+ else if(flags & NETSNMP_SENSORS_GET_VOLTS) {
+ /** voltage is in Volts = current_value/65536 */
+ pre_mul = 1000; /* want mV */
+ post_div = 256;
+ key = kVoltDataKey;
+ }
+ else if(flags & NETSNMP_SENSORS_GET_MISCS) {
+ /** power is in Watts = current_value/65536 */
+ /** current is in Amps = current_value/65536 */
+ pre_mul = 1000; /* want m? */
+ post_div = 256;
+ key = kMiscDataKey;
+ }
+ else
+ return -2;
+#endif
+
+ data = DumpSensorData(key);
+ if (NULL == data)
+ return -3;
+
+ size = CFArrayGetCount( data );
+
+ DEBUGMSGTL(("access:lmSensors","=== Type: %s ===\n",
+ CFStringGetCStringPtr(key,0)));
+ for (i = 0; i < size; ++i ) {
+ tmp_dict = (CFDictionaryRef)CFArrayGetValueAtIndex(data, i);
+ if (NULL == tmp_dict) {
+ DEBUGMSGTL(("access:lmSensors","No dict at index %d\n", i));
+ continue;
+ }
+ description = (CFStringRef)
+ CFDictionaryGetValue(tmp_dict,kDescriptionKey);
+ if (NULL == description) {
+ DEBUGMSGTL(("access:lmSensors","No description at %d\n", i));
+ continue;
+ }
+ pos = CFStringGetCStringPtr(description, 0);
+ value = (CFNumberRef)
+ CFDictionaryGetValue(tmp_dict,kCurrentValueKey);
+ if ((NULL == value) ||
+ (0 == CFNumberGetValue(value, kCFNumberSInt32Type, &i32))) {
+ DEBUGMSGTL(("access:lmSensors","No value at %d\n", i));
+ continue;
+ }
+ if (pre_mul && post_div) {
+ tmp = i32 * pre_mul;
+ tmp /= post_div;
+ DEBUGMSGTL(("access:lmSensors","converted %d to %d\n", i32, tmp ));
+ i32 = tmp;
+ }
+
+ idx = se_find_value_in_slist("lmSensors", pos);
+ if (idx == (oid)SE_DNE) {
+ char *copy;
+
+ idx = se_find_free_value_in_slist("lmSensors");
+ if (idx == SE_DNE)
+ idx = 1;
+
+ copy = strdup(pos);
+ if (NULL == copy) {
+ snmp_log(LOG_ERR, "could not allocate memory\n");
+ continue;
+ }
+ se_add_pair_to_slist("lmSensors", copy, idx);
+ DEBUGMSGTL(("access:lmSensors", "saved index %d for %s\n",
+ idx, copy));
+ }
+
+ entry = netsnmp_sensors_entry_create(idx);
+ if (NULL == entry) {
+ printf("Couldn't not allocate memory for sensor entry\n");
+ SNMP_FREE(entry);
+ continue;
+ }
+ strncpy(entry->device, pos, sizeof(entry->device));
+ entry->device[sizeof(entry->device)-1] = 0;
+ entry->device_len = strlen(entry->device);
+ entry->value = i32;
+
+ rc = CONTAINER_INSERT(container, entry);
+ if (0 != rc ) {
+ DEBUGMSGTL(("access:lmSensors","Couldn't insert %s entry in container\n",
+ entry->device));
+ continue;
+ }
+
+ DEBUGMSGTL(("access:lmSensors","Inserted key %s: value %d\n",
+ pos, i32));
+ }
+
+ DEBUGIF("access:lmSensors") {
+ while(NULL != container) {
+ DEBUGMSGTL(("access:lmSensors","Container %s, %d entries\n", container->container_name,
+ CONTAINER_SIZE(container)));
+ container = container->next;
+ }
+ }
+ CFRelease(data);
+ return 0;
+}
+
+/***********************************************************************
+ *
+ * Created by Leland Wallace on 6/7/07.
+ * Copyright 2007 Apple Computer, Inc. All rights reserved.
+ * -- APPLE CONFIDENTIAL --
+ * -- APPLE INTERNAL USE ONLY --
+ *
+ *
+ * This is a placeholder implementation of the DumpSensorData() routine
+ * that builds & returns a fixed dictionary of results.
+ *
+*
+ this function outputs a CFArray that contains the sensor data for
+ the specified key from a PPC G5 machine
+
+ the structure is as follows:
+
+ CFArray of CFDictionaries {
+ description : CFString
+ current_value : CFNumber
+ }
+ *
+ *
+ * fan current_value is in rpm
+ * temp is in degrees C = current_value/65536
+ * voltage is in Volts = current_value/65536
+ * power is in Watts = current_value/65536
+ * current is in Amps = current_value/65536
+ *
+ */
+CFArrayRef xDumpSensorData(CFStringRef inKey)
+{
+ CFMutableDictionaryRef sensorData = NULL;
+ CFMutableArrayRef tmpArray = NULL;
+ CFDictionaryRef entryDict = NULL;
+
+ const void *entry_template[] = { kDescriptionKey, kCurrentValueKey };
+ void *entry_values[2];
+ int tmpNum = 0;
+
+ sensorData = CFDictionaryCreateMutable (kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ /* fan data */
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+ entry_values[0] = (void *)CFSTR("CPUA_ACS");
+ tmpNum = 0;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("CPUB_ACS");
+ tmpNum = 1005;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("CPUA_INTAKE_FAN");
+ tmpNum = 999;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("CPUA_EXHAUST_FAN");
+ tmpNum = 1000;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("CPUB_INTAKE_FAN");
+ tmpNum = 999;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("CPUB_EXHAUST_FAN");
+ tmpNum = 1001;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("DRIVEBAY_FAN");
+ tmpNum = 1000;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ CFDictionaryAddValue(sensorData, kFanDataKey, tmpArray);
+ CFRelease(tmpArray);
+
+ /* misc-data */
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+ entry_values[0] = (void *)CFSTR("power:FAKE_POWER_CPUA");
+ tmpNum = 2315625;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("power:FAKE_POWER_CPUB");
+ tmpNum = 2753046;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("current:AD7417AD2_CPUA");
+ tmpNum = 302400;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("current:AD7417AD4_CPUA");
+ tmpNum = 1824000;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("current:AD7417AD2_CPUB");
+ tmpNum = 356000;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("current:AD7417AD4_CPUB");
+ tmpNum = 2152000;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("power:PCI Power 3v");
+ tmpNum = 0;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("power:PCI Power 5v");
+ tmpNum = 0;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("power:PCI Power 12v");
+ tmpNum = 0;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("power:PCI Power Combined");
+ tmpNum = 78540;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ CFDictionaryAddValue(sensorData, kMiscDataKey, tmpArray);
+ CFRelease(tmpArray);
+
+ /* volt-data */
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+ entry_values[0] = (void *)CFSTR("AD7417AD3_CPUA");
+ tmpNum = 83200;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("AD7417AD3_CPUB");
+ tmpNum = 83840;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ CFDictionaryAddValue(sensorData, kVoltDataKey, tmpArray);
+ CFRelease(tmpArray);
+
+ /* temp_data */
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+ entry_values[0] = (void *)CFSTR("AD7417AD1_CPUA");
+ tmpNum = 3904576;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("MAX6690RMT_U3");
+ tmpNum = 4579328;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("AD7417TEMP_CPUA");
+ tmpNum = 3473408;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("AD7417TEMP_CPUB");
+ tmpNum = 3358720;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("AD7417AD1_CPUB");
+ tmpNum = 3934852;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("DRIVEBAY");
+ tmpNum = 1933312;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ entry_values[0] = (void *)CFSTR("MAX6690LOC_U3");
+ tmpNum = 3235840;
+ entry_values[1] = (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &tmpNum);
+ entryDict = CFDictionaryCreate(kCFAllocatorDefault, entry_template, (const void **)entry_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(entry_values[1]);
+ CFArrayAppendValue(tmpArray, entryDict);
+ CFRelease(entryDict);
+
+ CFDictionaryAddValue(sensorData, kTempDataKey, tmpArray);
+ CFRelease(tmpArray);
+
+ CFArrayRef result = (CFArrayRef)CFDictionaryGetValue(sensorData, inKey);
+ if(result != NULL)
+ CFRetain(result);
+
+ CFRelease(sensorData);
+ return result;
+}
+
+
+/*
+ * Copyright 2007 Apple Inc. All rights reserved.
+ * -- APPLE CONFIDENTIAL --
+ * -- APPLE INTERNAL USE ONLY --
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+//#include <CoreServices/CoreServices.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+
+static int InitPPCDataCollection(void);
+static int GetPPCSensorData(CFArrayRef *outRef, CFStringRef inKey);
+static int InitSMCDataCollection(void);
+static int GetSMCSensorData(CFArrayRef *outRef, CFStringRef inKey);
+
+#define kSensorDriverName "IOHWSensor"
+#define kControlDriverName "IOHWControl"
+
+static io_service_t platformPlugin;
+
+int InitDataCollection(void)
+{
+ int result = 0;
+
+#if defined (__ppc__) || defined (__ppc64__)
+ result = InitPPCDataCollection();
+#elif defined (__i386__) || defined(__x86_64__)
+ result = InitSMCDataCollection();
+#else
+ // need to do a pragma #warn or something here
+ return -1;
+#endif
+ return result;
+}
+
+CFArrayRef DumpSensorData(CFStringRef inKey)
+{
+ CFArrayRef rawData = NULL;
+ CFMutableArrayRef cookedData = NULL;
+ CFStringRef description = NULL;
+ CFDictionaryRef sourceDict = NULL;
+ CFDictionaryRef destDict = NULL;
+ CFNumberRef value = NULL;
+ CFNumberRef tmpValue = NULL;
+ int result = 0;
+ CFIndex numItems = 0;
+ CFIndex theIndex = 0;
+ UInt32 no_value = 0;
+ const void *opKeys[] = { kDescriptionKey, kCurrentValueKey };
+ void *opValues[2];
+
+#if defined (__ppc__) || defined (__ppc64__)
+ result = GetPPCSensorData(&rawData, inKey);
+#elif defined (__i386__) || defined(__x86_64__)
+ result = GetSMCSensorData(&rawData, inKey);
+#else
+ // need to do a pragma #warn or something here
+
+ return NULL;
+#endif
+
+ if((result != 0) || (rawData == NULL))
+ {
+ return NULL;
+ }
+
+ numItems = CFArrayGetCount(rawData);
+ cookedData = CFArrayCreateMutable(kCFAllocatorDefault, numItems, &kCFTypeArrayCallBacks);
+
+ for(theIndex = 0; theIndex < numItems; theIndex++)
+ {
+ sourceDict = (CFDictionaryRef) CFArrayGetValueAtIndex(rawData, theIndex);
+ description = (CFStringRef) CFDictionaryGetValue(sourceDict, kDescriptionKey);
+ if(description == NULL)
+ {
+ description = (CFStringRef) CFDictionaryGetValue(sourceDict, CFSTR("Desc-Key"));
+ }
+ if(description == NULL)
+ {
+ description = (CFStringRef) CFDictionaryGetValue(sourceDict, CFSTR("location"));
+ }
+ if(description == NULL)
+ {
+ description = kUnknownDescription;
+ }
+ value = (CFNumberRef) CFDictionaryGetValue(sourceDict, kCurrentValueKey);
+ if(value == NULL)
+ {
+ value = (CFNumberRef) CFDictionaryGetValue(sourceDict, CFSTR("current-value"));
+ }
+ if(value == NULL)
+ {
+ value = CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &no_value);
+ }
+ opValues[0] = (void *)description;
+ opValues[1] = (void *)value;
+
+ destDict = CFDictionaryCreate(kCFAllocatorDefault, opKeys, (const void **)opValues, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFArrayAppendValue(cookedData, destDict);
+ CFRelease(destDict);
+ }
+ CFRelease(rawData);
+
+ return (CFArrayRef)cookedData;
+}
+
+
+/* PPC data collection
+ */
+
+static int InitPPCDataCollection(void)
+{
+ // Find the platform plugin
+ platformPlugin = IOServiceGetMatchingService(kIOMasterPortDefault,
+ IOServiceMatching("IOPlatformPlugin"));
+
+ if (!platformPlugin)
+ {
+
+ return -1;
+ }
+ else
+ {
+ io_name_t name;
+ kern_return_t status = IORegistryEntryGetName(platformPlugin, name);
+ if (status == kIOReturnSuccess)
+ {
+ printf("found the platform plugin: %s\n", name);
+ }
+ return 0;
+ }
+
+}
+
+
+static int GetPPCSensorData(CFArrayRef *outRef, CFStringRef inKey)
+{
+ CFDictionaryRef theItem = 0l;
+ CFArrayRef controlsArray = 0l;
+ CFArrayRef sensorArray = 0l;
+ CFMutableArrayRef tmpArray = 0l;
+
+ CFStringRef theType = 0l;
+ CFIndex theIndex = 0;
+
+ if((outRef == NULL) || (*outRef != NULL))
+ {
+ return -1;
+ }
+
+ if(CFStringCompare(kFanDataKey, inKey, 0) == kCFCompareEqualTo)
+ {
+
+ if ((controlsArray = (CFArrayRef)IORegistryEntryCreateCFProperty( platformPlugin,
+ CFSTR("IOHWControls"), NULL, 0l )) != NULL)
+ {
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault,0, &kCFTypeArrayCallBacks);
+ for(theIndex = 0; theIndex < CFArrayGetCount(controlsArray); theIndex++)
+ {
+ theItem = (CFDictionaryRef) CFArrayGetValueAtIndex(controlsArray, theIndex);
+ theType = (CFStringRef) CFDictionaryGetValue(theItem, CFSTR("type"));
+ if(theType == 0l) continue;
+ if(CFStringCompare(CFSTR("fan-rpm"), theType, 0) == kCFCompareEqualTo)
+ {
+ CFArrayAppendValue (tmpArray, theItem);
+ continue;
+ }
+ }
+ CFRelease(controlsArray);
+ } else {
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault,1, &kCFTypeArrayCallBacks); // empty array
+ }
+
+ *outRef = tmpArray;
+ return 0;
+ }
+
+
+ // get temp data
+ if(CFStringCompare(kTempDataKey, inKey, 0) == kCFCompareEqualTo)
+ {
+
+ if ((sensorArray = (CFArrayRef)IORegistryEntryCreateCFProperty( platformPlugin,
+ CFSTR("IOHWSensors"), NULL, 0l )) != NULL)
+ {
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault,0, &kCFTypeArrayCallBacks);
+ for(theIndex = 0; theIndex < CFArrayGetCount(sensorArray); theIndex++)
+ {
+ theItem = (CFDictionaryRef) CFArrayGetValueAtIndex(sensorArray, theIndex);
+ theType = (CFStringRef) CFDictionaryGetValue(theItem, CFSTR("type"));
+ if(theType == 0l) continue;
+ if(CFStringCompare(CFSTR("temperature"), theType, 0) == kCFCompareEqualTo)
+ {
+ CFArrayAppendValue (tmpArray, theItem);
+ continue;
+ }
+ }
+ CFRelease(sensorArray);
+ } else {
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault,1, &kCFTypeArrayCallBacks); // empty array
+ }
+ *outRef = tmpArray;
+ return 0;
+ }
+
+
+
+ // get voltage data
+ if(CFStringCompare(kVoltDataKey, inKey, 0) == kCFCompareEqualTo)
+ {
+
+ if ((sensorArray = (CFArrayRef)IORegistryEntryCreateCFProperty( platformPlugin,
+ CFSTR("IOHWSensors"), NULL, 0l )) != NULL)
+ {
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault,0, &kCFTypeArrayCallBacks);
+ //miscArray = CFArrayCreateMutable(kCFAllocatorDefault,0, &kCFTypeArrayCallBacks);
+ for(theIndex = 0; theIndex < CFArrayGetCount(sensorArray); theIndex++)
+ {
+ theItem = (CFDictionaryRef) CFArrayGetValueAtIndex(sensorArray, theIndex);
+ theType = (CFStringRef) CFDictionaryGetValue(theItem, CFSTR("type"));
+ if(theType == 0l) continue;
+ if(CFStringCompare(CFSTR("voltage"), theType, 0) == kCFCompareEqualTo)
+ {
+ CFArrayAppendValue (tmpArray, theItem);
+ continue;
+ }
+ }
+ CFRelease(sensorArray);
+ } else {
+ tmpArray = CFArrayCreateMutable(kCFAllocatorDefault,1, &kCFTypeArrayCallBacks); // empty array
+ }
+ *outRef = tmpArray;
+ return 0;
+ }
+
+ return -1; // no matching key
+}
+
+/* Intel Data Collection routines
+ */
+
+#include <unistd.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <CoreFoundation/CoreFoundation.h>
+//#include <ApplicationServices/ApplicationServices.h>
+
+
+
+/* Sensor Table
+*/
+#define kSensorTableFilename "SensorDat.xml"
+#define kSensorTableBasePath "/usr/share/snmp/"
+
+static CFDictionaryRef CopySensorTableFor(CFStringRef inModel);
+static char *CopyTablePath(void);
+static CFStringRef CopyModelName(void);
+
+/* SMC interface
+*/
+#define kMyDriversIOKitClassName "AppleSMC"
+
+// SMC data tpyes
+typedef UInt32 SMCKey;
+typedef UInt32 SMCDataType;
+typedef UInt8 SMCDataAttributes;
+typedef UInt8 SMCResult;
+
+// a struct to hold the SMC version
+typedef struct SMCVersion
+{
+ unsigned char major;
+ unsigned char minor;
+ unsigned char build;
+ unsigned char reserved; // padding for alignment
+ unsigned short release;
+
+} SMCVersion;
+
+// a struct to hold the key info data
+typedef struct SMCKeyInfoData
+{
+ IOByteCount dataSize;
+ SMCDataType dataType;
+ SMCDataAttributes dataAttributes;
+
+} SMCKeyInfoData;
+
+// general success / error codes
+enum
+{
+ // a couple error codes
+ kSMCSuccess = 0,
+ kSMCError = 1
+};
+
+// the data struct passed up to the Platform Plugin
+typedef struct SMCPLimitData
+{
+ UInt16 version;
+ UInt16 length;
+ UInt32 cpuPLimit;
+ UInt32 gpuPLimit;
+ UInt32 memPLimit;
+
+} SMCPLimitData;
+
+
+// the struct passed back and forth between the kext and UC
+typedef struct SMCParamStruct
+{
+ SMCKey key;
+
+ SMCVersion vers;
+ SMCPLimitData pLimitData;
+ SMCKeyInfoData keyInfo;
+
+ SMCResult result;
+ UInt8 status;
+
+ UInt8 data8;
+ UInt32 data32;
+ UInt8 bytes[32];
+
+} SMCParamStruct;
+
+
+enum
+{
+ // the user client method name constants
+ kSMCUserClientOpen,
+ kSMCUserClientClose,
+ kSMCHandleYPCEvent,
+
+ kSMCPlaceholder1, // *** LEGACY SUPPORT placeholder
+ kSMCNumberOfMethods,
+
+ // other constants not mapped to individual methods
+ kSMCReadKey,
+ kSMCWriteKey,
+ kSMCGetKeyCount,
+ kSMCGetKeyFromIndex,
+ kSMCGetKeyInfo,
+
+ kSMCFireInterrupt,
+ kSMCGetPLimits,
+ kSMCGetVers,
+ kSMCPlaceholder2, // *** LEGACY SUPPORT placeholder
+
+ kSMCReadStatus,
+ kSMCReadResult,
+
+ kSMCVariableCommand
+};
+
+
+static IOReturn OpenUserClient(io_service_t serviceObject, io_connect_t dataPort);
+static IOReturn CloseUserClient(io_connect_t dataPort);
+static IOReturn callFunction(int which, SMCParamStruct *inputValues, SMCParamStruct *outputValues);
+
+
+/* High Level Interface
+*/
+static CFDictionaryRef gSensorTable = NULL;
+
+static CFArrayRef GetFanDataFor(CFDictionaryRef inKeyDict);
+static void FanDataCollector (const void *key, const void *value, void *context);
+static CFArrayRef GetTempDataFor(CFDictionaryRef inKeyDict);
+static void TempDataCollector (const void *key, const void *value, void *context);
+static CFArrayRef GetVoltDataFor(CFDictionaryRef inKeyDict);
+static void VoltDataCollector (const void *key, const void *value, void *context);
+
+static int GetUInt16ForKey(unsigned char *inKey, UInt16 *outValue);
+//static int GetDoubleFrmFP88ForKey(unsigned char *inKey, double *outValue);
+//static int GetDoubleFrmSP78ForKey(unsigned char *inKey, double *outValue);
+
+static SMCKey makeUInt32Key(char * keyStr);
+
+
+
+
+
+/* Sensor Table
+*/
+
+static CFDictionaryRef CopySensorTableFor(CFStringRef inModel)
+{
+ int fd = 0;
+ char *path = CopyTablePath();
+ char buf[4096];
+ size_t bufLen = 0;
+ CFMutableDataRef tmpData = NULL;
+ CFDictionaryRef modelDict = NULL;
+ CFDictionaryRef fullTable = NULL;
+
+
+ if(path == NULL)
+ {
+ return NULL;
+ }
+ // read in the xml data
+ if((fd = open(path, O_RDONLY | O_NOFOLLOW)) == -1)
+ {
+ fprintf(stderr,"Could not open %s, errno %d\n", path, errno);
+ free(path);
+ return NULL;
+ }
+
+ tmpData = CFDataCreateMutable (kCFAllocatorDefault, 0);
+ while((bufLen = read(fd, buf, sizeof(buf))) > 0)
+ {
+ CFDataAppendBytes (tmpData, (unsigned char*)buf, (CFIndex)bufLen);
+ }
+ close(fd);
+ if(bufLen == -1) // error return
+ {
+ fprintf(stderr,"Read Error: %s, errno %d\n", path, errno);
+ CFRelease(tmpData);
+ free(path);
+ return NULL;
+ }
+
+ // make a plist/dictionary
+ fullTable = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, tmpData, kCFPropertyListImmutable, NULL);
+ if(fullTable == NULL)
+ {
+ fprintf(stderr,"Format Error: %s\n", path);
+ CFRelease(tmpData); free(path);
+ return NULL;
+ }
+ free(path);
+ // look for inModle in the dictionary
+ modelDict = (CFDictionaryRef)CFDictionaryGetValue (fullTable, inModel);
+ if(modelDict != NULL)
+ {
+ CFRetain(modelDict);
+ } else {
+ //fprintf(stderr,"No table found for");
+ //CFShow(inModel);
+ }
+
+ // cleanup
+ CFRelease(fullTable);
+ CFRelease(tmpData);
+ return modelDict;
+}
+
+// must be changed to find the SensorData.xml file
+static char *CopyTablePath(void)
+{
+ char *pathbuf = calloc(1, MAXPATHLEN);
+
+ strlcpy(pathbuf, kSensorTableBasePath, MAXPATHLEN);
+ strlcat(pathbuf, "/", MAXPATHLEN);
+
+ strlcat(pathbuf, kSensorTableFilename, MAXPATHLEN);
+ //fprintf(stderr,"Looking for %s at %s\n", kSensorTableFilename, pathbuf);
+ if(strlen(pathbuf) > MAXPATHLEN-2) // looks like we have a truncation error
+ {
+ free(pathbuf);
+ return NULL;
+ }
+
+ return pathbuf;
+}
+
+static CFStringRef CopyModelName(void)
+{
+ int mib[4];
+ char strBuffer[64];
+ size_t bufLen = sizeof(strBuffer);
+ CFStringRef result = NULL;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_MODEL;
+
+ memset(strBuffer, 0 , bufLen);
+
+ if (!sysctl(mib, 2, &strBuffer, &bufLen, NULL, 0))
+ {
+ result = CFStringCreateWithCString (kCFAllocatorDefault, strBuffer, kCFStringEncodingUTF8);
+ } else {
+ return NULL;
+ }
+ return result;
+}
+
+/* Low Level SMC Interface
+*/
+
+static IOReturn OpenUserClient(io_service_t serviceObject, io_connect_t dataPort)
+{
+ return IOConnectCallScalarMethod(dataPort, kSMCUserClientOpen, NULL, 0, NULL, NULL);
+}
+
+static IOReturn CloseUserClient(io_connect_t dataPort)
+{
+ return IOConnectCallScalarMethod(dataPort, kSMCUserClientOpen, NULL, 0, NULL, NULL);
+}
+
+static IOReturn callFunction(int which, SMCParamStruct *inputValues, SMCParamStruct *outputValues)
+{
+ mach_port_t masterPort;
+ io_service_t serviceObject;
+ io_connect_t dataPort;
+ io_iterator_t iterator;
+
+ CFDictionaryRef classToMatch;
+
+ IOReturn result = kIOReturnSuccess, retval = kIOReturnSuccess;
+
+ // returns the mach port used to initiate communication with IOKit
+ retval = IOMasterPort(MACH_PORT_NULL, &masterPort);
+ if(retval != kIOReturnSuccess)
+ {
+ //printf("ASMCF::callFunction ERROR - IOMasterPort returned %s\n", printIOReturn(retval));
+ return retval;
+ }
+
+ // find the entry in the IORegistry
+ classToMatch = IOServiceMatching(kMyDriversIOKitClassName);
+ if(classToMatch == NULL)
+ {
+ //printf("ASMCF::callFunction ERROR - IOServiceMatching returned a NULL dictionary\n");
+ return kIOReturnError;
+ }
+
+ // this creates an io_iterator_t of all instances of our drivers class that exist in the IORegistry
+ retval = IOServiceGetMatchingServices(masterPort, classToMatch, &iterator);
+ if(retval != kIOReturnSuccess)
+ {
+ //printf("ASMCF::callFunction ERROR - IOServiceGetMatchingServices returned %s\n", printIOReturn(retval));
+ return retval;
+ }
+
+ // get the first item in the iterator
+ serviceObject = IOIteratorNext(iterator);
+
+ // release the iterator since there's only 1 object
+ IOObjectRelease(iterator);
+
+ if(serviceObject)
+ {
+ // this call will cause the user client to be instantiated
+ retval = IOServiceOpen(serviceObject, mach_task_self(), 1, &dataPort);
+ IOObjectRelease(serviceObject);
+
+ if(retval != kIOReturnSuccess)
+ {
+ //printf("ASMCF::callFunction ERROR - IOServiceOpen returned %s\n", printIOReturn(retval));
+ return retval;
+ }
+
+ retval = OpenUserClient(serviceObject, dataPort);
+ if(retval != kIOReturnSuccess)
+ {
+ //printf("ASMCF::callFunction ERROR - OpenUserClient returned %s\n", printIOReturn(retval));
+
+ IOServiceClose(dataPort);
+ return retval;
+ }
+
+ //printf("ASMCF::callFunction which == %d\n", which);
+
+ size_t inStructSize = sizeof(SMCParamStruct);
+ size_t outStructSize = sizeof(SMCParamStruct);;
+
+ retval = IOConnectCallStructMethod
+ (
+ dataPort, // an io_connect_t returned from IOServiceOpen()
+ which, // an index to the function in the Kernel
+ inputValues, // the struct input parameter
+ inStructSize, // the size of the struct input paramter
+ outputValues, // the struct output parameter
+ &outStructSize // the size of the struct output paramter
+ );
+
+ //printf("### ASMCF::callFunction - retval = %s\n", printIOReturn(retval));
+
+ result = retval;
+ //if(retval != kIOReturnSuccess) { printf("ASMCF::callFunction ERROR - IOConnectMethod returned %s\n", printIOReturn(retval)); }
+
+ retval = CloseUserClient(dataPort);
+ //if(retval != kIOReturnSuccess) { printf("ASMCF::callFunction ERROR - CloseUserClient returned %s\n", printIOReturn(retval)); }
+
+ retval = IOServiceClose(dataPort);
+ //if(retval != kIOReturnSuccess) { printf("ASMCF::callFunction ERROR - IOServiceClose returned %s\n", printIOReturn(retval)); }
+ }
+ else
+ {
+ // release the io_service_t now that we're done with it
+ IOObjectRelease(serviceObject);
+ //printf("ASMCF::callFunction ERROR - couldn't find the driver!\n");
+ result = kIOReturnError;
+ }
+
+ return result;
+}
+
+
+/* High Level Routines
+*/
+
+static int InitSMCDataCollection(void)
+{
+ IOReturn result = 0;
+ CFStringRef modelName = CopyModelName();
+ char buffer[128];
+
+ CFDictionaryRef tmpDict = CopySensorTableFor(modelName);
+
+ if(tmpDict == NULL)
+ {
+ if((modelName != NULL) && (CFStringGetCString(modelName, buffer, sizeof(buffer), kCFStringEncodingUTF8)))
+ {
+ fprintf(stderr,"Couldn't find a table entry for the model name %s\n", buffer);
+ } else {
+ fprintf(stderr,"Couldn't find a table entry for this model\n");
+ }
+ if(modelName != NULL)
+ CFRelease(modelName);
+ return -1;
+ } else {
+ gSensorTable = tmpDict;
+ }
+ if(modelName != NULL)
+ CFRelease(modelName);
+ return result;
+}
+
+static int GetSMCSensorData(CFArrayRef *outRef, CFStringRef inKey)
+{
+ CFArrayRef valueArray = NULL;
+ CFDictionaryRef keyDict = NULL;
+ int result = 0;
+
+ if(gSensorTable == NULL)
+ {
+ return -1;
+ }
+
+
+ if((outRef == NULL) || (*outRef != NULL))
+ {
+ return -1;
+ }
+
+ keyDict = (CFDictionaryRef) CFDictionaryGetValue (gSensorTable, inKey);
+ if(keyDict == NULL)
+ {
+ return -1;
+ }
+
+ //CFShow(keyDict);
+
+ // figure out the type of the data
+ if(CFStringCompare(kFanDataKey, inKey, 0) == kCFCompareEqualTo)
+ {
+ valueArray = GetFanDataFor(keyDict);
+ } else if(CFStringCompare(kTempDataKey, inKey, 0) == kCFCompareEqualTo)
+ {
+ valueArray = GetTempDataFor(keyDict);
+ } else if(CFStringCompare(kVoltDataKey, inKey, 0) == kCFCompareEqualTo)
+ {
+ valueArray = GetVoltDataFor(keyDict);
+ } else {
+ return -1;
+ }
+
+ //CFShow(valueArray);
+ *outRef = valueArray;
+
+ return result;
+}
+
+/*
+ create the results array, apply a function to the dictionary to fill the array, return it
+*/
+static CFArrayRef GetFanDataFor(CFDictionaryRef inKeyDict)
+{
+ CFMutableArrayRef results = NULL;
+ results = CFArrayCreateMutable(kCFAllocatorDefault, CFDictionaryGetCount(inKeyDict), &kCFTypeArrayCallBacks);
+ if(results != NULL)
+ {
+ CFDictionaryApplyFunction (inKeyDict, (CFDictionaryApplierFunction)FanDataCollector, (void *)results);
+ }
+ return results;
+}
+
+static void FanDataCollector (const void *key, const void *value, void *context)
+{
+ CFStringRef keyVal =(CFStringRef)key;
+ CFStringRef description =(CFStringRef)value;
+ CFMutableArrayRef resultsArray = (CFMutableArrayRef)context;
+ unsigned char keyBuf[5];
+ CFMutableDictionaryRef itemDictionary = NULL;
+ CFNumberRef tmpNum = NULL;
+ UInt16 dummy_16 = 0;
+ UInt32 dummy_32 = 0;
+ IOReturn result = 0;
+
+ if(CFStringGetCString (keyVal, (char *)keyBuf, sizeof(keyBuf), kCFStringEncodingUTF8))
+ {
+ result = GetUInt16ForKey(keyBuf, &dummy_16);
+ if(result != kSMCSuccess)
+ {
+ return;
+ }
+ itemDictionary = CFDictionaryCreateMutable (kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ dummy_32 = dummy_16;
+ tmpNum = CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &dummy_32);
+ CFDictionaryAddValue (itemDictionary, kCurrentValueKey, tmpNum);
+ CFDictionaryAddValue (itemDictionary, kDescriptionKey, description);
+
+ CFArrayAppendValue(resultsArray, itemDictionary);
+ CFRelease(tmpNum);
+ CFRelease(itemDictionary);
+ }
+}
+
+
+static CFArrayRef GetTempDataFor(CFDictionaryRef inKeyDict)
+{
+ CFMutableArrayRef results = NULL;
+ results = CFArrayCreateMutable(kCFAllocatorDefault, CFDictionaryGetCount(inKeyDict), &kCFTypeArrayCallBacks);
+ if(results != NULL)
+ {
+ CFDictionaryApplyFunction (inKeyDict, (CFDictionaryApplierFunction)TempDataCollector, (void *)results);
+ }
+ return results;
+}
+
+// need to convert sp78 to a CFNumber
+static void TempDataCollector (const void *key, const void *value, void *context)
+{
+ CFStringRef keyVal =(CFStringRef)key;
+ CFStringRef description =(CFStringRef)value;
+ CFMutableArrayRef resultsArray = (CFMutableArrayRef)context;
+ unsigned char keyBuf[5];
+ CFMutableDictionaryRef itemDictionary = NULL;
+ CFNumberRef tmpNum = NULL;
+ UInt16 dummy_16 = 0;
+ UInt32 dummy_32 = 0;
+ IOReturn result = 0;
+
+ if(CFStringGetCString (keyVal, (char *)keyBuf, sizeof(keyBuf), kCFStringEncodingUTF8))
+ {
+ result = GetUInt16ForKey(keyBuf, &dummy_16);
+ if(result != kSMCSuccess)
+ {
+ return;
+ }
+ itemDictionary = CFDictionaryCreateMutable (kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ dummy_32 = dummy_16; // do the conversion here
+ tmpNum = CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &dummy_32);
+ CFDictionaryAddValue (itemDictionary, kCurrentValueKey, tmpNum);
+ CFDictionaryAddValue (itemDictionary, kDescriptionKey, description);
+
+ CFArrayAppendValue(resultsArray, itemDictionary);
+ CFRelease(tmpNum);
+ CFRelease(itemDictionary);
+ }
+}
+
+
+
+static CFArrayRef GetVoltDataFor(CFDictionaryRef inKeyDict)
+{
+ CFMutableArrayRef results = NULL;
+ results = CFArrayCreateMutable(kCFAllocatorDefault, CFDictionaryGetCount(inKeyDict), &kCFTypeArrayCallBacks);
+ if(results != NULL)
+ {
+ CFDictionaryApplyFunction (inKeyDict, (CFDictionaryApplierFunction)VoltDataCollector, (void *)results);
+ }
+ return results;
+}
+
+
+// need to convert fp88 to CFNumber
+static void VoltDataCollector (const void *key, const void *value, void *context)
+{
+ CFStringRef keyVal =(CFStringRef)key;
+ CFStringRef description =(CFStringRef)value;
+ CFMutableArrayRef resultsArray = (CFMutableArrayRef)context;
+ unsigned char keyBuf[5];
+ CFMutableDictionaryRef itemDictionary = NULL;
+ CFNumberRef tmpNum = NULL;
+ UInt16 dummy_16 = 0;
+ UInt32 dummy_32 = 0;
+ IOReturn result = 0;
+
+ if(CFStringGetCString (keyVal, (char *)keyBuf, sizeof(keyBuf), kCFStringEncodingUTF8))
+ {
+ result = GetUInt16ForKey(keyBuf, &dummy_16);
+ if(result != kSMCSuccess)
+ {
+ return;
+ }
+ itemDictionary = CFDictionaryCreateMutable (kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ dummy_32 = dummy_16; // do the conversion here
+ tmpNum = CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &dummy_32);
+ CFDictionaryAddValue (itemDictionary, kCurrentValueKey, tmpNum);
+ CFDictionaryAddValue (itemDictionary, kDescriptionKey, description);
+
+ CFArrayAppendValue(resultsArray, itemDictionary);
+ CFRelease(tmpNum);
+ CFRelease(itemDictionary);
+ }
+}
+
+static SMCKey makeUInt32Key(char * keyStr)
+{
+ SMCKey key32 = 0;
+
+ if(keyStr[0] == '-')
+ {
+ if(strlen(keyStr) < 5) { keyStr[4] = 0x20; } // for 3-character keys, we need to input a space in the 4th spot
+ keyStr[5] = 0; // always have 4 characters or less
+
+ key32 = (keyStr[1] << 24);
+ key32 |= (keyStr[2] << 16);
+ key32 |= (keyStr[3] << 8);
+ key32 |= (keyStr[4] << 0);
+ }
+ else
+ {
+ if(strlen(keyStr) < 4) { keyStr[3] = 0x20; } // for 3-character keys, we need to input a space in the 4th spot
+ keyStr[4] = 0; // always have 4 characters or less
+
+ key32 = (keyStr[0] << 24);
+ key32 |= (keyStr[1] << 16);
+ key32 |= (keyStr[2] << 8);
+ key32 |= (keyStr[3] << 0);
+ }
+
+ return key32;
+}
+
+static int GetUInt16ForKey(unsigned char *inKey, UInt16 *outValue)
+{
+ SMCParamStruct inStruct;
+ SMCParamStruct outStruct;
+ IOReturn result = kIOReturnSuccess;
+
+ bzero(&inStruct, sizeof(SMCParamStruct));
+
+ inStruct.data8 = kSMCReadKey;
+ inStruct.keyInfo.dataSize = sizeof(UInt16);
+ inStruct.key = makeUInt32Key((char *)inKey);
+ if(inStruct.key == 0)
+ return 1;
+
+ result = callFunction(kSMCHandleYPCEvent, &inStruct, &outStruct);
+ if(result == kIOReturnSuccess)
+ {
+ result = outStruct.result;
+ *outValue = outStruct.bytes[1] + outStruct.bytes[0] * 256;
+ }
+
+ return result;
+};
+