1/*
2 *
3 * @APPLE_LICENSE_HEADER_START@
4 *
5 * This file contains Original Code and/or Modifications of Original Code
6 * as defined in and that are subject to the Apple Public Source License
7 * Version 2.0 (the 'License'). You may not use this file except in
8 * compliance with the License. Please obtain a copy of the License at
9 * http://www.opensource.apple.com/apsl/ and read it before using this
10 * file.
11 *
12 * The Original Code and all software distributed under the License are
13 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
17 * Please see the License for the specific language governing rights and
18 * limitations under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22#include <CoreFoundation/CoreFoundation.h>
23
24#include <mach/mach.h>
25#include <mach/mach_host.h>
26#include <mach/mach_error.h>
27
28#include <libc.h>
29#include <servers/bootstrap.h>
30#include <sysexits.h>
31
32#include <IOKit/IOKitLib.h>
33#include <IOKit/IOKitServer.h>
34#include <IOKit/IOCFURLAccess.h>
35#include <IOKit/IOCFSerialize.h>
36#include <IOKit/IOCFUnserialize.h>
37#include <IOKit/IOMessage.h>
38#include <IOKit/ps/IOPSKeys.h>
39
40#include "IOUPSPrivate.h"
41#include "IOUPSPlugIn.h"
42
43// mig generated header
44#include "ioupspluginmig.h"
45
46Boolean IOUPSMIGServerIsRunning(mach_port_t * bootstrap_port_ref, mach_port_t * upsd_port_ref)
47{
48    mach_port_t     active = MACH_PORT_NULL;
49    kern_return_t   kern_result = KERN_SUCCESS;
50    mach_port_t     bootstrap_port;
51
52    if (bootstrap_port_ref && (*bootstrap_port_ref != MACH_PORT_NULL)) {
53        bootstrap_port = *bootstrap_port_ref;
54    } else {
55        /* Get the bootstrap server port */
56        kern_result = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
57        if (kern_result != KERN_SUCCESS) {
58            return false;
59        }
60        if (bootstrap_port_ref) {
61            *bootstrap_port_ref = bootstrap_port;
62        }
63    }
64
65    /* Check "upsd" server status */
66    kern_result = bootstrap_look_up(
67                        bootstrap_port,
68                        kIOUPSPlugInServerName,
69                        &active);
70
71    if (BOOTSTRAP_SUCCESS == kern_result) {
72        return true;
73    } else {
74        // For any result other than SUCCESS, we presume the server is
75        // not running. We expect the most common failure result to be:
76        // kern_result == BOOTSTRAP_UNKNOWN_SERVICE
77        return false;
78    }
79}
80
81IOReturn IOUPSSendCommand(mach_port_t connect, int upsID, CFDictionaryRef command)
82{
83    IOReturn 		ret;
84    CFDataRef		serializedData;
85
86    if (!connect || !command)
87        return kIOReturnBadArgument;
88
89    serializedData = (CFDataRef)IOCFSerialize( command, kNilOptions );
90
91    if (!serializedData)
92        return kIOReturnError;
93
94    ret = io_ups_send_command(connect, upsID,
95                (vm_offset_t)CFDataGetBytePtr(serializedData),
96                (mach_msg_type_number_t) CFDataGetLength(serializedData));
97
98    CFRelease( serializedData );
99
100    return ret;
101}
102
103IOReturn IOUPSGetEvent(mach_port_t connect, int upsID, CFDictionaryRef *event)
104{
105    IOReturn        ret;
106    void *          buffer = NULL;
107    IOByteCount     bufferSize;
108
109    if (!connect || !event)
110        return kIOReturnBadArgument;
111
112    ret = io_ups_get_event(connect, upsID,
113                (vm_offset_t *)&buffer,
114                (mach_msg_type_number_t *)&bufferSize);
115
116    if ( ret != kIOReturnSuccess )
117        return ret;
118
119    *event = IOCFUnserialize(buffer, kCFAllocatorDefault, kNilOptions, NULL);
120
121    vm_deallocate(mach_task_self(), (vm_address_t)buffer, bufferSize);
122
123    return ret;
124}
125
126IOReturn IOUPSGetCapabilities(mach_port_t connect, int upsID, CFSetRef *capabilities)
127{
128    IOReturn 		ret;
129    void *		buffer = NULL;
130    IOByteCount		bufferSize;
131
132    if (!connect || !capabilities)
133        return kIOReturnBadArgument;
134
135    ret = io_ups_get_capabilities(connect, upsID,
136                (vm_offset_t *)&buffer,
137                (mach_msg_type_number_t *)&bufferSize);
138
139    if ( ret != kIOReturnSuccess )
140        return ret;
141
142    *capabilities = IOCFUnserialize(buffer, kCFAllocatorDefault, kNilOptions, NULL);
143
144    vm_deallocate(mach_task_self(), (vm_address_t)buffer, bufferSize);
145
146    return ret;
147}
148
149