]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/power_mgmt.c
ipsec-317.220.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / power_mgmt.c
CommitLineData
e8d9021d
A
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/time.h>
e8d9021d
A
6#include <unistd.h>
7#include <errno.h>
8#include <notify.h>
65c25746 9#include <dispatch/dispatch.h>
e8d9021d
A
10
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>
23
24#include "var.h"
25#include "misc.h"
26#include "vmbuf.h"
27#include "plog.h"
28#include "sockmisc.h"
29#include "schedule.h"
30#include "debug.h"
31
32#include "isakmp_var.h"
33#include "isakmp.h"
34#include "handler.h"
35
36#ifndef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
37IONotificationPortRef notify;
38io_object_t iterator;
39io_connect_t gIOPort;
40CFUserNotificationRef gSleepNotification = NULL;
41#endif // !kIOPMAcknowledgmentOptionSystemCapabilityRequirements
42
e8d9021d
A
43time_t slept_at = 0;
44time_t woke_at = 0;
45time_t swept_at = 0;
46
47static int sleeping = 0;
48
65c25746
A
49int check_power_context; // dummy field for dispatch call
50extern void check_power_mgmt (void*);
51
e8d9021d
A
52#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
53#define WAKE_CAPS (kIOPMSystemPowerStateCapabilityCPU | kIOPMSystemPowerStateCapabilityNetwork)
54
55IOPMConnection gPMConnection = NULL;
56
57static void
58iosleep_capabilities_notifier(void *param, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities capabilities)
59{
65c25746 60 plog(ASL_LEVEL_DEBUG, "received power-mgmt event: capabilities %X%s%s%s%s%s",
e8d9021d
A
61 capabilities,
62 capabilities & kIOPMSystemPowerStateCapabilityCPU ? " CPU" : "",
63 capabilities & kIOPMSystemPowerStateCapabilityVideo ? " Video" : "",
64 capabilities & kIOPMSystemPowerStateCapabilityAudio ? " Audio" : "",
65 capabilities & kIOPMSystemPowerStateCapabilityNetwork ? " Network" : "",
66 capabilities & kIOPMSystemPowerStateCapabilityDisk ? " Disk" : "");
67
68 if ((capabilities & WAKE_CAPS) != WAKE_CAPS) {
69 if (!sleeping) {
65c25746 70 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
71 "received power-mgmt event: will sleep\n");
72 sleeping = 1;
73 slept_at = current_time();
74 } else {
65c25746 75 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
76 "ignored power-mgmt event: sleep(%x) while asleep\n", capabilities);
77 }
78 IOPMConnectionAcknowledgeEvent(connection, token );
79 } else if ((capabilities & WAKE_CAPS) == WAKE_CAPS) {
80 // allow processing of packets
81 if (sleeping) {
65c25746 82 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
83 "received power-mgmt event: will wake(%x)\n", capabilities);
84 sleeping = 0;
85 woke_at = current_time();
86 } else {
65c25746 87 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
88 "ignored power-mgmt event: wake(%x) while not asleep\n", capabilities);
89 }
90 IOPMConnectionAcknowledgeEvent(connection, token);
91 } else {
65c25746 92 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
93 "ignored power-mgmt event: capabilities(%x)\n", capabilities);
94 IOPMConnectionAcknowledgeEvent(connection, token);
95 }
65c25746 96 dispatch_async_f(dispatch_get_main_queue(), &check_power_context, &check_power_mgmt);
e8d9021d
A
97}
98
99#else
100
101static
102void iosleep_notifier(void * x, io_service_t y, natural_t messageType, void *messageArgument)
103{
104 switch ( messageType ) {
105 case kIOMessageSystemWillSleep:
106 sleeping = 1;
107 slept_at = current_time();
65c25746 108 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
109 "received power-mgmt event: will sleep\n");
110 IOAllowPowerChange(gIOPort, (long)messageArgument);
111 break;
112 case kIOMessageCanSystemSleep:
113 IOAllowPowerChange(gIOPort, (long)messageArgument);
114 break;
115 case kIOMessageSystemWillNotSleep:
116 /* someone refused an idle sleep */
65c25746 117 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
118 "received power-mgmt event: will not sleep\n");
119 sleeping = 0;
120 slept_at = 0;
121 break;
122 case kIOMessageSystemWillPowerOn:
123 if (sleeping) {
65c25746 124 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
125 "received power-mgmt event: will wake\n");
126 sleeping = 0;
127 } else {
65c25746 128 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
129 "received power-mgmt event: will power-on\n");
130 }
131 break;
132 case kIOMessageSystemHasPoweredOn:
133 woke_at = current_time();
134 if (slept_at) {
65c25746 135 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
136 "received power-mgmt event: has woken\n");
137 } else {
65c25746 138 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
139 "received power-mgmt event: has powered-on\n");
140 }
141 break;
142 default:
65c25746 143 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
144 "received power-mgmt event: %x\n", messageType);
145 break;
146 }
65c25746 147 dispatch_async_f(dispatch_get_main_queue(), &check_power_context, &check_power_mgmt);
e8d9021d
A
148}
149#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
150
65c25746
A
151int
152init_power_mgmt (void)
e8d9021d
A
153{
154#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
155 IOReturn ret;
156
157 ret = IOPMConnectionCreate(CFSTR("racoon power-mgmt"),
158 WAKE_CAPS,
159 &gPMConnection);
160 if (ret != kIOReturnSuccess) {
65c25746
A
161 plog(ASL_LEVEL_ERR, "IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
162 return -1;
e8d9021d
A
163 }
164
165 ret = IOPMConnectionSetNotification(gPMConnection, NULL, iosleep_capabilities_notifier);
166 if (ret != kIOReturnSuccess) {
65c25746
A
167 plog(ASL_LEVEL_ERR, "IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
168 return -1;
e8d9021d
A
169 }
170
65c25746
A
171 IOPMConnectionSetDispatchQueue(gPMConnection, dispatch_get_main_queue());
172
e8d9021d
A
173#else
174 if ((gIOPort = IORegisterForSystemPower(0, &notify, iosleep_notifier, &iterator)) == MACH_PORT_NULL) {
65c25746 175 plog(ASL_LEVEL_ERR,
e8d9021d 176 "IORegisterForSystemPower failed for power-mgmt thread\n");
65c25746 177 return -1;
e8d9021d 178 }
65c25746
A
179
180 IONotificationPortSetDispatchQueue(notify, dispatch_get_main_queue());
181
e8d9021d
A
182#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
183
65c25746 184 return 0;
e8d9021d
A
185}
186
65c25746
A
187void
188cleanup_power_mgmt (void)
e8d9021d 189{
65c25746
A
190#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
191
192 IOPMConnectionSetDispatchQueue(gPMConnection, NULL);
193 IOPMConnectionRelease(gPMConnection);
194
195#else
196
197 IODeregisterForSystemPower(&iterator);
198 IONotificationPortDestroy(notify);
199
200#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
201
e8d9021d
A
202}
203
204void
65c25746 205check_power_mgmt (void *context)
e8d9021d
A
206{
207 if (slept_at && woke_at) {
65c25746 208 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
209 "handling power-mgmt event: sleep-wake\n");
210 swept_at = current_time();
211 sweep_sleepwake();
212 slept_at = 0;
213 woke_at = 0;
214 } else if (woke_at) {
65c25746 215 plog(ASL_LEVEL_DEBUG,
e8d9021d
A
216 "handling power-mgmt event: power-on\n");
217 woke_at = 0;
218 }
219}