]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/power_mgmt.c
ipsec-317.220.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / power_mgmt.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/time.h>
6 #include <unistd.h>
7 #include <errno.h>
8 #include <notify.h>
9 #include <dispatch/dispatch.h>
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
37 IONotificationPortRef notify;
38 io_object_t iterator;
39 io_connect_t gIOPort;
40 CFUserNotificationRef gSleepNotification = NULL;
41 #endif // !kIOPMAcknowledgmentOptionSystemCapabilityRequirements
42
43 time_t slept_at = 0;
44 time_t woke_at = 0;
45 time_t swept_at = 0;
46
47 static int sleeping = 0;
48
49 int check_power_context; // dummy field for dispatch call
50 extern void check_power_mgmt (void*);
51
52 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
53 #define WAKE_CAPS (kIOPMSystemPowerStateCapabilityCPU | kIOPMSystemPowerStateCapabilityNetwork)
54
55 IOPMConnection gPMConnection = NULL;
56
57 static void
58 iosleep_capabilities_notifier(void *param, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities capabilities)
59 {
60 plog(ASL_LEVEL_DEBUG, "received power-mgmt event: capabilities %X%s%s%s%s%s",
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) {
70 plog(ASL_LEVEL_DEBUG,
71 "received power-mgmt event: will sleep\n");
72 sleeping = 1;
73 slept_at = current_time();
74 } else {
75 plog(ASL_LEVEL_DEBUG,
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) {
82 plog(ASL_LEVEL_DEBUG,
83 "received power-mgmt event: will wake(%x)\n", capabilities);
84 sleeping = 0;
85 woke_at = current_time();
86 } else {
87 plog(ASL_LEVEL_DEBUG,
88 "ignored power-mgmt event: wake(%x) while not asleep\n", capabilities);
89 }
90 IOPMConnectionAcknowledgeEvent(connection, token);
91 } else {
92 plog(ASL_LEVEL_DEBUG,
93 "ignored power-mgmt event: capabilities(%x)\n", capabilities);
94 IOPMConnectionAcknowledgeEvent(connection, token);
95 }
96 dispatch_async_f(dispatch_get_main_queue(), &check_power_context, &check_power_mgmt);
97 }
98
99 #else
100
101 static
102 void 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();
108 plog(ASL_LEVEL_DEBUG,
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 */
117 plog(ASL_LEVEL_DEBUG,
118 "received power-mgmt event: will not sleep\n");
119 sleeping = 0;
120 slept_at = 0;
121 break;
122 case kIOMessageSystemWillPowerOn:
123 if (sleeping) {
124 plog(ASL_LEVEL_DEBUG,
125 "received power-mgmt event: will wake\n");
126 sleeping = 0;
127 } else {
128 plog(ASL_LEVEL_DEBUG,
129 "received power-mgmt event: will power-on\n");
130 }
131 break;
132 case kIOMessageSystemHasPoweredOn:
133 woke_at = current_time();
134 if (slept_at) {
135 plog(ASL_LEVEL_DEBUG,
136 "received power-mgmt event: has woken\n");
137 } else {
138 plog(ASL_LEVEL_DEBUG,
139 "received power-mgmt event: has powered-on\n");
140 }
141 break;
142 default:
143 plog(ASL_LEVEL_DEBUG,
144 "received power-mgmt event: %x\n", messageType);
145 break;
146 }
147 dispatch_async_f(dispatch_get_main_queue(), &check_power_context, &check_power_mgmt);
148 }
149 #endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
150
151 int
152 init_power_mgmt (void)
153 {
154 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
155 IOReturn ret;
156
157 ret = IOPMConnectionCreate(CFSTR("racoon power-mgmt"),
158 WAKE_CAPS,
159 &gPMConnection);
160 if (ret != kIOReturnSuccess) {
161 plog(ASL_LEVEL_ERR, "IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
162 return -1;
163 }
164
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);
168 return -1;
169 }
170
171 IOPMConnectionSetDispatchQueue(gPMConnection, dispatch_get_main_queue());
172
173 #else
174 if ((gIOPort = IORegisterForSystemPower(0, &notify, iosleep_notifier, &iterator)) == MACH_PORT_NULL) {
175 plog(ASL_LEVEL_ERR,
176 "IORegisterForSystemPower failed for power-mgmt thread\n");
177 return -1;
178 }
179
180 IONotificationPortSetDispatchQueue(notify, dispatch_get_main_queue());
181
182 #endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
183
184 return 0;
185 }
186
187 void
188 cleanup_power_mgmt (void)
189 {
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
202 }
203
204 void
205 check_power_mgmt (void *context)
206 {
207 if (slept_at && woke_at) {
208 plog(ASL_LEVEL_DEBUG,
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) {
215 plog(ASL_LEVEL_DEBUG,
216 "handling power-mgmt event: power-on\n");
217 woke_at = 0;
218 }
219 }