9 #include <dispatch/dispatch.h>
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
47 static int sleeping
= 0;
49 int check_power_context
; // dummy field for dispatch call
50 extern void check_power_mgmt (void*);
52 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
53 #define WAKE_CAPS (kIOPMSystemPowerStateCapabilityCPU | kIOPMSystemPowerStateCapabilityNetwork)
55 IOPMConnection gPMConnection
= NULL
;
58 iosleep_capabilities_notifier(void *param
, IOPMConnection connection
, IOPMConnectionMessageToken token
, IOPMSystemPowerStateCapabilities capabilities
)
60 plog(ASL_LEVEL_DEBUG
, "received power-mgmt event: capabilities %X%s%s%s%s%s",
62 capabilities
& kIOPMSystemPowerStateCapabilityCPU
? " CPU" : "",
63 capabilities
& kIOPMSystemPowerStateCapabilityVideo
? " Video" : "",
64 capabilities
& kIOPMSystemPowerStateCapabilityAudio
? " Audio" : "",
65 capabilities
& kIOPMSystemPowerStateCapabilityNetwork
? " Network" : "",
66 capabilities
& kIOPMSystemPowerStateCapabilityDisk
? " Disk" : "");
68 if ((capabilities
& WAKE_CAPS
) != WAKE_CAPS
) {
71 "received power-mgmt event: will sleep\n");
73 slept_at
= current_time();
76 "ignored power-mgmt event: sleep(%x) while asleep\n", capabilities
);
78 IOPMConnectionAcknowledgeEvent(connection
, token
);
79 } else if ((capabilities
& WAKE_CAPS
) == WAKE_CAPS
) {
80 // allow processing of packets
83 "received power-mgmt event: will wake(%x)\n", capabilities
);
85 woke_at
= current_time();
88 "ignored power-mgmt event: wake(%x) while not asleep\n", capabilities
);
90 IOPMConnectionAcknowledgeEvent(connection
, token
);
93 "ignored power-mgmt event: capabilities(%x)\n", capabilities
);
94 IOPMConnectionAcknowledgeEvent(connection
, token
);
96 dispatch_async_f(dispatch_get_main_queue(), &check_power_context
, &check_power_mgmt
);
102 void iosleep_notifier(void * x
, io_service_t y
, natural_t messageType
, void *messageArgument
)
104 switch ( messageType
) {
105 case kIOMessageSystemWillSleep
:
107 slept_at
= current_time();
108 plog(ASL_LEVEL_DEBUG
,
109 "received power-mgmt event: will sleep\n");
110 IOAllowPowerChange(gIOPort
, (long)messageArgument
);
112 case kIOMessageCanSystemSleep
:
113 IOAllowPowerChange(gIOPort
, (long)messageArgument
);
115 case kIOMessageSystemWillNotSleep
:
116 /* someone refused an idle sleep */
117 plog(ASL_LEVEL_DEBUG
,
118 "received power-mgmt event: will not sleep\n");
122 case kIOMessageSystemWillPowerOn
:
124 plog(ASL_LEVEL_DEBUG
,
125 "received power-mgmt event: will wake\n");
128 plog(ASL_LEVEL_DEBUG
,
129 "received power-mgmt event: will power-on\n");
132 case kIOMessageSystemHasPoweredOn
:
133 woke_at
= current_time();
135 plog(ASL_LEVEL_DEBUG
,
136 "received power-mgmt event: has woken\n");
138 plog(ASL_LEVEL_DEBUG
,
139 "received power-mgmt event: has powered-on\n");
143 plog(ASL_LEVEL_DEBUG
,
144 "received power-mgmt event: %x\n", messageType
);
147 dispatch_async_f(dispatch_get_main_queue(), &check_power_context
, &check_power_mgmt
);
149 #endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
152 init_power_mgmt (void)
154 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
157 ret
= IOPMConnectionCreate(CFSTR("racoon power-mgmt"),
160 if (ret
!= kIOReturnSuccess
) {
161 plog(ASL_LEVEL_ERR
, "IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret
);
165 ret
= IOPMConnectionSetNotification(gPMConnection
, NULL
, iosleep_capabilities_notifier
);
166 if (ret
!= kIOReturnSuccess
) {
167 plog(ASL_LEVEL_ERR
, "IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret
);
171 IOPMConnectionSetDispatchQueue(gPMConnection
, dispatch_get_main_queue());
174 if ((gIOPort
= IORegisterForSystemPower(0, ¬ify
, iosleep_notifier
, &iterator
)) == MACH_PORT_NULL
) {
176 "IORegisterForSystemPower failed for power-mgmt thread\n");
180 IONotificationPortSetDispatchQueue(notify
, dispatch_get_main_queue());
182 #endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
188 cleanup_power_mgmt (void)
190 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
192 IOPMConnectionSetDispatchQueue(gPMConnection
, NULL
);
193 IOPMConnectionRelease(gPMConnection
);
197 IODeregisterForSystemPower(&iterator
);
198 IONotificationPortDestroy(notify
);
200 #endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
205 check_power_mgmt (void *context
)
207 if (slept_at
&& woke_at
) {
208 plog(ASL_LEVEL_DEBUG
,
209 "handling power-mgmt event: sleep-wake\n");
210 swept_at
= current_time();
214 } else if (woke_at
) {
215 plog(ASL_LEVEL_DEBUG
,
216 "handling power-mgmt event: power-on\n");