]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/power_mgmt.c
ipsec-146.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>
6#include <pthread.h>
7#include <unistd.h>
8#include <errno.h>
9#include <notify.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
37IONotificationPortRef notify;
38io_object_t iterator;
39io_connect_t gIOPort;
40CFUserNotificationRef gSleepNotification = NULL;
41#endif // !kIOPMAcknowledgmentOptionSystemCapabilityRequirements
42
43pthread_t power_mgmt_thread;
44time_t slept_at = 0;
45time_t woke_at = 0;
46time_t swept_at = 0;
47
48static int sleeping = 0;
49
50#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
51#define WAKE_CAPS (kIOPMSystemPowerStateCapabilityCPU | kIOPMSystemPowerStateCapabilityNetwork)
52
53IOPMConnection gPMConnection = NULL;
54
55static void
56iosleep_capabilities_notifier(void *param, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities capabilities)
57{
58 plog(LLV_DEBUG, LOCATION, NULL,"received power-mgmt event: capabilities %X%s%s%s%s%s",
59 capabilities,
60 capabilities & kIOPMSystemPowerStateCapabilityCPU ? " CPU" : "",
61 capabilities & kIOPMSystemPowerStateCapabilityVideo ? " Video" : "",
62 capabilities & kIOPMSystemPowerStateCapabilityAudio ? " Audio" : "",
63 capabilities & kIOPMSystemPowerStateCapabilityNetwork ? " Network" : "",
64 capabilities & kIOPMSystemPowerStateCapabilityDisk ? " Disk" : "");
65
66 if ((capabilities & WAKE_CAPS) != WAKE_CAPS) {
67 if (!sleeping) {
68 plog(LLV_DEBUG, LOCATION, NULL,
69 "received power-mgmt event: will sleep\n");
70 sleeping = 1;
71 slept_at = current_time();
72 } else {
73 plog(LLV_DEBUG, LOCATION, NULL,
74 "ignored power-mgmt event: sleep(%x) while asleep\n", capabilities);
75 }
76 IOPMConnectionAcknowledgeEvent(connection, token );
77 } else if ((capabilities & WAKE_CAPS) == WAKE_CAPS) {
78 // allow processing of packets
79 if (sleeping) {
80 plog(LLV_DEBUG, LOCATION, NULL,
81 "received power-mgmt event: will wake(%x)\n", capabilities);
82 sleeping = 0;
83 woke_at = current_time();
84 } else {
85 plog(LLV_DEBUG, LOCATION, NULL,
86 "ignored power-mgmt event: wake(%x) while not asleep\n", capabilities);
87 }
88 IOPMConnectionAcknowledgeEvent(connection, token);
89 } else {
90 plog(LLV_DEBUG, LOCATION, NULL,
91 "ignored power-mgmt event: capabilities(%x)\n", capabilities);
92 IOPMConnectionAcknowledgeEvent(connection, token);
93 }
94}
95
96#else
97
98static
99void iosleep_notifier(void * x, io_service_t y, natural_t messageType, void *messageArgument)
100{
101 switch ( messageType ) {
102 case kIOMessageSystemWillSleep:
103 sleeping = 1;
104 slept_at = current_time();
105 plog(LLV_DEBUG, LOCATION, NULL,
106 "received power-mgmt event: will sleep\n");
107 IOAllowPowerChange(gIOPort, (long)messageArgument);
108 break;
109 case kIOMessageCanSystemSleep:
110 IOAllowPowerChange(gIOPort, (long)messageArgument);
111 break;
112 case kIOMessageSystemWillNotSleep:
113 /* someone refused an idle sleep */
114 plog(LLV_DEBUG, LOCATION, NULL,
115 "received power-mgmt event: will not sleep\n");
116 sleeping = 0;
117 slept_at = 0;
118 break;
119 case kIOMessageSystemWillPowerOn:
120 if (sleeping) {
121 plog(LLV_DEBUG, LOCATION, NULL,
122 "received power-mgmt event: will wake\n");
123 sleeping = 0;
124 } else {
125 plog(LLV_DEBUG, LOCATION, NULL,
126 "received power-mgmt event: will power-on\n");
127 }
128 break;
129 case kIOMessageSystemHasPoweredOn:
130 woke_at = current_time();
131 if (slept_at) {
132 plog(LLV_DEBUG, LOCATION, NULL,
133 "received power-mgmt event: has woken\n");
134 } else {
135 plog(LLV_DEBUG, LOCATION, NULL,
136 "received power-mgmt event: has powered-on\n");
137 }
138 break;
139 default:
140 plog(LLV_DEBUG, LOCATION, NULL,
141 "received power-mgmt event: %x\n", messageType);
142 break;
143 }
144}
145#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
146
147void *
148power_mgmt_thread_func (void *arg)
149{
150#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
151 IOReturn ret;
152
153 ret = IOPMConnectionCreate(CFSTR("racoon power-mgmt"),
154 WAKE_CAPS,
155 &gPMConnection);
156 if (ret != kIOReturnSuccess) {
157 plog(LLV_ERROR, LOCATION, NULL,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
158 return NULL;
159 }
160
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);
164 return NULL;
165 }
166
167 ret = IOPMConnectionScheduleWithRunLoop(gPMConnection, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
168 if (ret != kIOReturnSuccess) {
169 plog(LLV_ERROR, LOCATION, NULL,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
170 return NULL;
171 }
172#else
173 if ((gIOPort = IORegisterForSystemPower(0, &notify, iosleep_notifier, &iterator)) == MACH_PORT_NULL) {
174 plog(LLV_ERROR, LOCATION, NULL,
175 "IORegisterForSystemPower failed for power-mgmt thread\n");
176 return NULL;
177 }
178
179 CFRunLoopAddSource(CFRunLoopGetCurrent(),
180 IONotificationPortGetRunLoopSource(notify),
181 kCFRunLoopDefaultMode);
182#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
183
184 CFRunLoopRun();
185 return NULL;
186}
187
188int
189init_power_mgmt (void)
190{
191 int err;
192
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);
196 return -1;
197 }
198
199 return 0;
200}
201
202void
203check_power_mgmt (void)
204{
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();
209 sweep_sleepwake();
210 slept_at = 0;
211 woke_at = 0;
212 } else if (woke_at) {
213 plog(LLV_DEBUG, LOCATION, NULL,
214 "handling power-mgmt event: power-on\n");
215 woke_at = 0;
216 }
217}