OpenVPN 3 Core Library
Loading...
Searching...
No Matches
macsleep.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#ifndef OPENVPN_APPLE_MACSLEEP_H
13#define OPENVPN_APPLE_MACSLEEP_H
14
15#include <mach/mach_port.h>
16#include <mach/mach_interface.h>
17#include <mach/mach_init.h>
18
19#include <IOKit/pwr_mgt/IOPMLib.h>
20#include <IOKit/IOMessage.h>
21
23
24namespace openvpn {
26{
27 MacSleep(const MacSleep &) = delete;
28 MacSleep &operator=(const MacSleep &) = delete;
29
30 public:
32 : root_port(0),
33 notifyPortRef(nullptr),
35 {
36 }
37
38 virtual ~MacSleep()
39 {
41 }
42
44 {
45 if (!root_port)
46 {
47 root_port = IORegisterForSystemPower(this, &notifyPortRef, callback_static, &notifierObject);
48 if (!root_port)
49 return false;
50 CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes);
51 }
52 return true;
53 }
54
56 {
57 if (root_port)
58 {
59 // remove the sleep notification port from the application runloop
60 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
61 IONotificationPortGetRunLoopSource(notifyPortRef),
62 kCFRunLoopCommonModes);
63
64 // deregister for system sleep notifications
65 IODeregisterForSystemPower(&notifierObject);
66
67 // IORegisterForSystemPower implicitly opens the Root Power Domain IOService
68 // so we close it here
69 IOServiceClose(root_port);
70
71 // destroy the notification port allocated by IORegisterForSystemPower
72 IONotificationPortDestroy(notifyPortRef);
73
74 // reset object members
75 root_port = 0;
76 notifyPortRef = nullptr;
78 }
79 }
80
81 virtual void notify_sleep() = 0;
82 virtual void notify_wakeup() = 0;
83
84 private:
85 static void callback_static(void *arg, io_service_t service, natural_t messageType, void *messageArgument)
86 {
87 MacSleep *self = (MacSleep *)arg;
88 self->callback(service, messageType, messageArgument);
89 }
90
91 void callback(io_service_t service, natural_t messageType, void *messageArgument)
92 {
93 switch (messageType)
94 {
95 case kIOMessageCanSystemSleep:
96 IOAllowPowerChange(root_port, (long)messageArgument);
97 break;
98 case kIOMessageSystemWillSleep:
100 IOAllowPowerChange(root_port, (long)messageArgument);
101 break;
102 case kIOMessageSystemHasPoweredOn:
104 break;
105 }
106 }
107
108 // a reference to the Root Power Domain IOService
109 io_connect_t root_port;
110
111 // notification port allocated by IORegisterForSystemPower
112 IONotificationPortRef notifyPortRef;
113
114 // notifier object, used to deregister later
115 io_object_t notifierObject;
116};
117} // namespace openvpn
118
119#endif
MacSleep(const MacSleep &)=delete
virtual void notify_wakeup()=0
virtual ~MacSleep()
Definition macsleep.hpp:38
io_object_t notifierObject
Definition macsleep.hpp:115
void mac_sleep_stop()
Definition macsleep.hpp:55
io_connect_t root_port
Definition macsleep.hpp:109
MacSleep & operator=(const MacSleep &)=delete
static void callback_static(void *arg, io_service_t service, natural_t messageType, void *messageArgument)
Definition macsleep.hpp:85
bool mac_sleep_start()
Definition macsleep.hpp:43
virtual void notify_sleep()=0
void callback(io_service_t service, natural_t messageType, void *messageArgument)
Definition macsleep.hpp:91
IONotificationPortRef notifyPortRef
Definition macsleep.hpp:112