11 #include <CoreFoundation/CoreFoundation.h>
12 #include <CoreFoundation/CFUserNotification.h>
13 #include <mach/mach_port.h>
14 #include <mach/mach_interface.h>
15 #include <mach/mach_init.h>
16 #include <IOKit/IOKitLib.h>
17 #include <IOKit/pwr_mgt/IOPM.h>
18 #include <IOKit/pwr_mgt/IOPMLib.h>
19 #if !TARGET_OS_EMBEDDED
20 #include <IOKit/pwr_mgt/IOPMLibPrivate.h>
21 #endif /* !TARGET_OS_EMBEDDED */
22 #include <IOKit/IOMessage.h>
32 #include "isakmp_var.h"
36 #ifndef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
37 IONotificationPortRef notify
;
40 CFUserNotificationRef gSleepNotification
= NULL
;
41 #endif // !kIOPMAcknowledgmentOptionSystemCapabilityRequirements
43 pthread_t power_mgmt_thread
;
48 static int sleeping
= 0;
50 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
51 #define WAKE_CAPS (kIOPMSystemPowerStateCapabilityCPU | kIOPMSystemPowerStateCapabilityNetwork)
53 IOPMConnection gPMConnection
= NULL
;
56 iosleep_capabilities_notifier(void *param
, IOPMConnection connection
, IOPMConnectionMessageToken token
, IOPMSystemPowerStateCapabilities capabilities
)
58 plog(LLV_DEBUG
, LOCATION
, NULL
,"received power-mgmt event: capabilities %X%s%s%s%s%s",
60 capabilities
& kIOPMSystemPowerStateCapabilityCPU
? " CPU" : "",
61 capabilities
& kIOPMSystemPowerStateCapabilityVideo
? " Video" : "",
62 capabilities
& kIOPMSystemPowerStateCapabilityAudio
? " Audio" : "",
63 capabilities
& kIOPMSystemPowerStateCapabilityNetwork
? " Network" : "",
64 capabilities
& kIOPMSystemPowerStateCapabilityDisk
? " Disk" : "");
66 if ((capabilities
& WAKE_CAPS
) != WAKE_CAPS
) {
68 plog(LLV_DEBUG
, LOCATION
, NULL
,
69 "received power-mgmt event: will sleep\n");
71 slept_at
= current_time();
73 plog(LLV_DEBUG
, LOCATION
, NULL
,
74 "ignored power-mgmt event: sleep(%x) while asleep\n", capabilities
);
76 IOPMConnectionAcknowledgeEvent(connection
, token
);
77 } else if ((capabilities
& WAKE_CAPS
) == WAKE_CAPS
) {
78 // allow processing of packets
80 plog(LLV_DEBUG
, LOCATION
, NULL
,
81 "received power-mgmt event: will wake(%x)\n", capabilities
);
83 woke_at
= current_time();
85 plog(LLV_DEBUG
, LOCATION
, NULL
,
86 "ignored power-mgmt event: wake(%x) while not asleep\n", capabilities
);
88 IOPMConnectionAcknowledgeEvent(connection
, token
);
90 plog(LLV_DEBUG
, LOCATION
, NULL
,
91 "ignored power-mgmt event: capabilities(%x)\n", capabilities
);
92 IOPMConnectionAcknowledgeEvent(connection
, token
);
99 void iosleep_notifier(void * x
, io_service_t y
, natural_t messageType
, void *messageArgument
)
101 switch ( messageType
) {
102 case kIOMessageSystemWillSleep
:
104 slept_at
= current_time();
105 plog(LLV_DEBUG
, LOCATION
, NULL
,
106 "received power-mgmt event: will sleep\n");
107 IOAllowPowerChange(gIOPort
, (long)messageArgument
);
109 case kIOMessageCanSystemSleep
:
110 IOAllowPowerChange(gIOPort
, (long)messageArgument
);
112 case kIOMessageSystemWillNotSleep
:
113 /* someone refused an idle sleep */
114 plog(LLV_DEBUG
, LOCATION
, NULL
,
115 "received power-mgmt event: will not sleep\n");
119 case kIOMessageSystemWillPowerOn
:
121 plog(LLV_DEBUG
, LOCATION
, NULL
,
122 "received power-mgmt event: will wake\n");
125 plog(LLV_DEBUG
, LOCATION
, NULL
,
126 "received power-mgmt event: will power-on\n");
129 case kIOMessageSystemHasPoweredOn
:
130 woke_at
= current_time();
132 plog(LLV_DEBUG
, LOCATION
, NULL
,
133 "received power-mgmt event: has woken\n");
135 plog(LLV_DEBUG
, LOCATION
, NULL
,
136 "received power-mgmt event: has powered-on\n");
140 plog(LLV_DEBUG
, LOCATION
, NULL
,
141 "received power-mgmt event: %x\n", messageType
);
145 #endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
148 power_mgmt_thread_func (void *arg
)
150 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
153 ret
= IOPMConnectionCreate(CFSTR("racoon power-mgmt"),
156 if (ret
!= kIOReturnSuccess
) {
157 plog(LLV_ERROR
, LOCATION
, NULL
,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret
);
161 ret
= IOPMConnectionSetNotification(gPMConnection
, NULL
, iosleep_capabilities_notifier
);
162 if (ret
!= kIOReturnSuccess
) {
163 plog(LLV_ERROR
, LOCATION
, NULL
,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret
);
167 ret
= IOPMConnectionScheduleWithRunLoop(gPMConnection
, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode
);
168 if (ret
!= kIOReturnSuccess
) {
169 plog(LLV_ERROR
, LOCATION
, NULL
,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret
);
173 if ((gIOPort
= IORegisterForSystemPower(0, ¬ify
, iosleep_notifier
, &iterator
)) == MACH_PORT_NULL
) {
174 plog(LLV_ERROR
, LOCATION
, NULL
,
175 "IORegisterForSystemPower failed for power-mgmt thread\n");
179 CFRunLoopAddSource(CFRunLoopGetCurrent(),
180 IONotificationPortGetRunLoopSource(notify
),
181 kCFRunLoopDefaultMode
);
182 #endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
189 init_power_mgmt (void)
193 if ((err
= pthread_create(&power_mgmt_thread
, NULL
, power_mgmt_thread_func
, NULL
))) {
194 plog(LLV_ERROR
, LOCATION
, NULL
,
195 "failed to create power-mgmt thread: %d\n", err
);
203 check_power_mgmt (void)
205 if (slept_at
&& woke_at
) {
206 plog(LLV_DEBUG
, LOCATION
, NULL
,
207 "handling power-mgmt event: sleep-wake\n");
208 swept_at
= current_time();
212 } else if (woke_at
) {
213 plog(LLV_DEBUG
, LOCATION
, NULL
,
214 "handling power-mgmt event: power-on\n");