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 +#include +#include +#include +#include + +#include + +/*********************************************************************** + * + * + */ + +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 +#include + +#include +//#include +#include +#include +#include + +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 +#include +#include +#include +//#include + + + +/* 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, kSMCUserClientClose, 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; +}; +