1//
2//  darktool.h
3//  PowerManagement
4//
5//  Created by Ethan Bold on 9/19/13.
6//
7//
8
9#ifndef PowerManagement_darktool_h
10#define PowerManagement_darktool_h
11
12#include <CoreFoundation/CoreFoundation.h>
13#include <IOKit/pwr_mgt/IOPMLib.h>
14#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
15#include <IOKit/platform/IOPlatformSupportPrivate.h>
16#include <IOKit/IOReturn.h>
17#include <IOKit/ps/IOPowerSources.h>
18#include <IOKit/ps/IOPowerSourcesPrivate.h>
19#include <dispatch/dispatch.h>
20#include <unistd.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <getopt.h>
24#include <unistd.h>
25#include <notify.h>
26
27#define PMTestLog(x...)  do {print_pretty_date(false); printf(x);} while(0);
28#define PMTestPass  printf
29#define PMTestFail  printf
30
31
32#define kSleepIntervalSec               1800
33#define kAssertionTimeoutSec            0
34
35/*
36 * IOKit Assertions - command-line arguments for creating IOKit power assertions.
37 *
38 * callers should pass these strings as an argument to "darktool --createassertion <assertionname>"
39 */
40#define kAssertPushService                              "applepushservice"
41#define kInteractivePushService                         "interactivepush"
42#define kAssertBackground                               "backgroundtask"
43#define kAssertUserIsActive                             "userisactive"
44#define kAssertRemoteUserIsActive                       "remoteuserisactive"
45#define kAssertDisplayWake                              "displaywake"
46#define kAssertInternalPreventSleep                     "internalpreventsleep"
47#define kAssertMaintenanceWake                          "maintenancewake"
48#define kAssertSystemIsActive                           "systemisactive"
49
50struct DTAssertionOption {
51    CFStringRef         assertionType;
52    const char          *arg;
53    const char          *desc;
54};
55typedef struct DTAssertionOption DTAssertionOption;
56
57/*************************************************************************/
58static void usage(void);
59static struct option *long_opts_from_darktool_opts(int *);
60static bool parse_it_all(int argc, char *argv[]);
61static void print_the_plan(void);
62static void print_pretty_date(bool newline);
63static void print_everything_dark(void);
64
65static void bringTheHeat(void);
66static void executeTimedActions(const char *why);
67static void execute_Assertion(CFStringRef type, long timeout);
68static void execute_APICall(const char *callname);
69static void exec_exec(char* run_command);
70static DTAssertionOption *createAssertionOptions(int *);
71
72
73static void createPMConnectionListener(void);
74static void myPMConnectionHandler(
75                                  void *param, IOPMConnection,
76                                  IOPMConnectionMessageToken, IOPMSystemPowerStateCapabilities);
77
78static CFDictionaryRef HandleBackgroundTaskCapabilitiesChanged(
79                                                               IOPMSystemPowerStateCapabilities cap);
80static CFDictionaryRef HandleSleepServiceCapabilitiesChanged(
81                                                             IOPMSystemPowerStateCapabilities cap);
82static CFDictionaryRef HandleMaintenanceCapabilitiesChanged(
83                                                            IOPMSystemPowerStateCapabilities cap);
84
85static void _CFDictionarySetLong(
86                                 CFMutableDictionaryRef d,
87                                 CFStringRef k,
88                                 long val);
89static void _CFDictionarySetDate(
90                                 CFMutableDictionaryRef d,
91                                 CFStringRef k,
92                                 CFAbsoluteTime atime);
93
94static void cacheArgvString(int argc, char *argv[]);
95
96
97/*************************************************************************/
98/*
99 * IOKit SPI/API calls
100 *
101 * callers should pass these strings as arguments to "darktool --call <functionname>"
102 */
103
104#define kCallDeclareUserIsActive                        kAssertUserIsActive
105#define kCallDeclareSystemIsActive                      kAssertSystemIsActive
106#define kCallDeclareNotificationEvent                   "declarenotificationevent"
107
108struct DTCallOption {
109    const char *arg;
110    const char *desc;
111};
112typedef struct DTCallOption DTCallOption;
113
114DTCallOption calls[] = {
115    {kCallDeclareUserIsActive, "IOPMAssertionDeclareUserActivity"},
116    {kCallDeclareSystemIsActive, "IOPMAssertionDeclareSystemActivity"},
117    {kCallDeclareNotificationEvent, "IOPMAssertionDeclareNotificationEvent"},
118    { NULL, NULL}
119};
120
121/*************************************************************************/
122
123typedef enum {
124    kExitIfNextWakeIsNotPushIndex           = 0,
125//  kPrintDarkWakeResidencyTimeIndex,
126    kCreateAssertionIndex,
127    kCallIndex,
128    kBringTheHeatIndex,
129    kTCPKeepaliveOverride,
130    kActionSetTCPWakeQuota, // unused
131    kActionSeTTCPWakeQuota, // unused
132    kDoAckTimeoutIndex,
133    kActionExecIndex,
134    kActionClaimIndex,
135    kActionCreatePowerSourceIndex,
136    kActionsCount   // kActionsCount must always be the last item in this list
137} DarkToolActions;
138
139typedef enum {
140    kIOPMConnectRequestBackgroundIndex,
141    kIOPMConnectRequestSleepServiceIndex,
142    kIOPMConnectRequestMaintenanceIndex,
143    // kRequestWakeCount must always be the last item in this list
144    kRequestWakeCount
145} DarkToolRequests;
146
147typedef enum {
148    kDoItNow                = (1<<0),
149    kDoItUponDarkWake       = (1<<1),
150    kDoItUponUserWake       = (1<<2),
151    kDoItUponACAttach       = (1<<3)
152} DoItWhenOptions;
153
154
155
156
157/*
158 * Options - caller may specify 0 or more
159 */
160#define kOptionSleepInterval                            "sleepinterval"
161#define kOptionAssertionTimeout                         "assertiontimeout"
162#define kOptionDoItNow                                  "now"
163#define kOptionUponDarkWake                             "enterdarkwake"
164#define kOptionUponUserWake                             "enteruserwake"
165#define kOptionUponACAttach                             "acattach"
166#define kOptionSleepServiceCapTimeout                   "sleepservicecap"
167#define kOptionSleepNow                                 "sleepnow"
168#define kOptionIterations                               "iterations"
169#define kOptionStandardSleepIntervals                   "standardsleepintervals"
170
171/*
172 * Actions - caller may specify only one
173 */
174#define kActionGet                                      "get"
175#define kActionCreateAssertion                          "createassertion"
176#define kActionCall                                     "call"
177#define kActionPrintDarkWakeResidency                   "printdarkwakeresidencytime"
178#define kActionExitIfNotPushWake                        "exitifnextwakeisnotpush"
179#define kActionBringTheHeat                             "cpuheater"
180#define kActionRequestBackgroundWake                    "backgroundwake"
181#define kActionRequestSleepServiceWake                  "sleepservicewake"
182#define kActionRequestMaintenanceWake                   "maintenancewake"
183#define kActionSetTCPKeepAliveExpirationTimeout         "tcpkeepaliveexpiration"
184#define kActionSetTCPWakeQuotaInterval                  "tcpwakequotainterval"
185#define kActionSetTCPWakeQuota                          "tcpwakequota"
186#define kActionDoAckTimeout                             "doacktimeout"
187#define kActionExec                                     "exec"
188#define kActionClaim                                    "claim"
189#define kActionCreatePowerSource                        "createPowerSource"
190
191#define kArgIOPMConnection                              "iopmconnection"
192#define kArgIORegisterForSystemPower                    "ioregisterforsystempower"
193
194typedef enum {kNilType, kActionType, kOptionType} DTOptionType;
195
196struct DTOption {
197    struct option   getopt_long;
198    DTOptionType    type;
199    const char      *desc;
200    const char      *required_options[10];
201    const char      *optional_options[10];
202
203};
204typedef struct DTOption DTOption;
205
206
207
208#endif
209