1/*
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include <mach/mach_init.h>
25#include <mach/mach_port.h>
26#include <mach/vm_map.h>
27#include <servers/bootstrap.h>
28
29
30#include "IOSystemConfiguration.h"
31#include <CoreFoundation/CoreFoundation.h>
32#include <IOKit/IOKitLib.h>
33#include <IOKit/pwr_mgt/IOPMLib.h>
34#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
35#include "powermanagement_mig.h"
36#include "powermanagement.h"
37
38__private_extern__ IOReturn _copyPMServerObject(int selector, int assertionID, CFTypeRef *objectOut);
39
40/*
41 * SCPreferences file format
42 *     com.apple.AutoWake.xml
43 *
44 * - CFSTR(kIOPMRepeatingPowerOnKey)
45 *      - CFSTR(kIOPMPowerEventTimeKey) = CFNumberRef (kCFNumberIntType)
46 *      - CFSTR(kIOPMDaysOfWeekKey) = CFNumberRef (kCFNumberIntType)
47 *      - CFSTR(kIOPMPowerEventTypeKey) = CFStringRef (kIOPMAutoSleep, kIOPMAutoShutdown, kIOPMAutoPowerOn, kIOPMAutoWake)
48 * - CFSTR(kIOPMRepeatingPowerOffKey)
49 *      - CFSTR(kIOPMPowerEventTimeKey) = CFNumberRef (kCFNumberIntType)
50 *      - CFSTR(kIOPMDaysOfWeekKey) = CFNumberRef (kCFNumberIntType)
51 *      - CFSTR(kIOPMPowerEventTypeKey) = CFStringRef (kIOPMAutoSleep, kIOPMAutoShutdown, kIOPMAutoPowerOn, kIOPMAutoWake)
52 */
53
54IOReturn _pm_connect(mach_port_t *newConnection);
55IOReturn _pm_disconnect(mach_port_t connection);
56
57IOReturn IOPMScheduleRepeatingPowerEvent(CFDictionaryRef events)
58{
59    IOReturn                    ret = kIOReturnError;
60    CFDataRef                   flatPackage = NULL;
61    kern_return_t               rc = KERN_SUCCESS;
62    mach_port_t                 pm_server = MACH_PORT_NULL;
63
64    // Validate our inputs
65    if(!isA_CFDictionary(events)) return kIOReturnBadArgument;
66
67
68    if(kIOReturnSuccess != _pm_connect(&pm_server)) {
69        ret = kIOReturnInternalError;
70        goto exit;
71    }
72
73    flatPackage = CFPropertyListCreateData(0, events,
74                          kCFPropertyListBinaryFormat_v1_0, 0, NULL );
75
76    if ( !flatPackage ) {
77        ret = kIOReturnBadArgument;
78        goto exit;
79    }
80
81    rc = io_pm_schedule_repeat_event(pm_server, (vm_offset_t)CFDataGetBytePtr(flatPackage),
82            CFDataGetLength(flatPackage), 1, &ret);
83
84    if (rc != KERN_SUCCESS)
85        ret = kIOReturnInternalError;
86
87exit:
88
89    if (MACH_PORT_NULL != pm_server) {
90        _pm_disconnect(pm_server);
91    }
92    if(flatPackage) CFRelease(flatPackage);
93
94    return ret;
95}
96
97
98CFDictionaryRef IOPMCopyRepeatingPowerEvents(void)
99{
100    CFMutableDictionaryRef      return_dict = NULL;
101
102    _copyPMServerObject(kIOPMPowerEventsMIGCopyRepeatEvents, 0, (CFTypeRef *)&return_dict);
103    return return_dict;
104}
105
106IOReturn IOPMCancelAllRepeatingPowerEvents(void)
107{
108    IOReturn                    ret = kIOReturnError;
109    kern_return_t               rc = KERN_SUCCESS;
110    mach_port_t                 pm_server = MACH_PORT_NULL;
111
112    if(kIOReturnSuccess != _pm_connect(&pm_server)) {
113        ret = kIOReturnInternalError;
114        goto exit;
115    }
116
117    rc = io_pm_cancel_repeat_events(pm_server, &ret);
118
119    if (rc != KERN_SUCCESS)
120        ret = kIOReturnInternalError;
121
122
123    if (MACH_PORT_NULL != pm_server) {
124        _pm_disconnect(pm_server);
125    }
126
127exit:
128    return ret;
129}
130