1/*
2 * Copyright (c) 2007 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <CoreFoundation/CoreFoundation.h>
30#include <SystemConfiguration/SCPrivate.h>
31#include <IOKit/IOReturn.h>
32#include "IOPMLibPrivate.h"
33#include "IOSystemConfiguration.h"
34
35#include <notify.h>
36
37
38#define kMySCIdentity           CFSTR("IOKit Power")
39
40
41static CFStringRef createSCKeyForIOKitString(CFStringRef str)
42{
43    CFStringRef     keyForString = NULL;
44
45    if (CFEqual(str, CFSTR(kIOPMThermalLevelWarningKey)))
46    {
47        keyForString = CFSTR("ThermalWarning");
48    } else if (CFEqual(str, CFSTR(kIOPMCPUPowerLimitsKey))) {
49        keyForString = CFSTR("CPUPower");
50    }
51
52    if (!keyForString)
53        return NULL;
54
55    return SCDynamicStoreKeyCreate(kCFAllocatorDefault,
56                        CFSTR("%@%@/%@"),
57                        _io_kSCDynamicStoreDomainState,
58                        CFSTR("/IOKit/Power"),
59                        keyForString);
60}
61
62
63IOReturn IOPMCopyCPUPowerStatus(CFDictionaryRef *cpuPowerStatus)
64{
65    SCDynamicStoreRef   store = NULL;
66    CFStringRef         cpu_power_key = NULL;
67    IOReturn            ret = kIOReturnError;
68
69    if (!cpuPowerStatus) {
70        ret = kIOReturnBadArgument;
71        goto exit;
72    }
73
74    // Open connection to SCDynamicStore
75    store = SCDynamicStoreCreate(kCFAllocatorDefault,
76                kMySCIdentity, NULL, NULL);
77    if (!store) {
78        goto exit;
79     }
80
81    cpu_power_key = createSCKeyForIOKitString(CFSTR(kIOPMCPUPowerLimitsKey));
82    if (!cpu_power_key) {
83        ret = kIOReturnInternalError;
84        goto exit;
85    }
86
87    *cpuPowerStatus = SCDynamicStoreCopyValue(store, cpu_power_key);
88    if (isA_CFDictionary(*cpuPowerStatus)) {
89        ret = kIOReturnSuccess;
90    } else {
91        if (NULL != *cpuPowerStatus) {
92            CFRelease(*cpuPowerStatus);
93            *cpuPowerStatus = NULL;
94        }
95        ret = kIOReturnNotFound;
96    }
97
98exit:
99    if (cpu_power_key)
100        CFRelease(cpu_power_key);
101    if (store)
102        CFRelease(store);
103
104    // Caller to release
105    return ret;
106}
107
108
109IOReturn IOPMGetThermalWarningLevel(uint32_t *thermalLevel)
110{
111    SCDynamicStoreRef   store = NULL;
112    CFStringRef         thermal_key = NULL;
113    CFNumberRef         warning_level_num = NULL;
114    IOReturn            ret = kIOReturnError;
115
116    if (!thermalLevel) {
117        ret =  kIOReturnBadArgument;
118        goto exit;
119    }
120
121    // Open connection to SCDynamicStore
122    store = SCDynamicStoreCreate(kCFAllocatorDefault,
123                kMySCIdentity, NULL, NULL);
124    if (!store) {
125        goto exit;
126     }
127
128    thermal_key = createSCKeyForIOKitString(CFSTR(kIOPMThermalLevelWarningKey));
129    if (!thermal_key) {
130        ret = kIOReturnInternalError;
131        goto exit;
132    }
133
134    warning_level_num = isA_CFNumber(SCDynamicStoreCopyValue(store, thermal_key));
135
136    if (!warning_level_num) {
137        ret = kIOReturnNotFound;
138        goto exit;
139    }
140
141    CFNumberGetValue(warning_level_num, kCFNumberIntType, thermalLevel);
142    ret = kIOReturnSuccess;
143
144exit:
145    if (warning_level_num)
146        CFRelease(warning_level_num);
147    if (thermal_key)
148        CFRelease(thermal_key);
149    if (store)
150        CFRelease(store);
151    return ret;
152}
153
154
155
156