ctru/services/ptm/sysm.rs
1//! PTM SystemMenu service.
2//!
3//! This sub-service of the Power-Time service family is able to control shutdown/sleep functionality and how those states are
4//! communicated to the user (such as via the notification/battery LED).
5#[doc(alias = "sleep")]
6#[doc(alias = "shutdown")]
7#[doc(alias = "led")]
8use std::sync::Mutex;
9use std::time::Duration;
10
11use crate::error::{Result, ResultCode};
12use crate::services::ServiceReference;
13
14static PTMSYSM_ACTIVE: Mutex<()> = Mutex::new(());
15
16/// Handle to the PTM:SysM service.
17pub struct PTMSysM {
18 _service_handler: ServiceReference,
19}
20
21impl PTMSysM {
22 /// Initialize a new service handle.
23 ///
24 /// # Errors
25 ///
26 /// This function will return an error if the service was unable to be initialized.
27 /// Since this service requires no special or elevated permissions, errors are rare in practice.
28 ///
29 /// # Example
30 ///
31 /// ```
32 /// # let _runner = test_runner::GdbRunner::default();
33 /// # use std::error::Error;
34 /// # fn main() -> Result<(), Box<dyn Error>> {
35 /// #
36 /// use ctru::services::ptm::sysm::PTMSysM;
37 ///
38 /// let ptm_sysm = PTMSysM::new()?;
39 /// #
40 /// # Ok(())
41 /// # }
42 /// ```
43 #[doc(alias = "ptmSysmInit")]
44 pub fn new() -> Result<Self> {
45 let handler = ServiceReference::new(
46 &PTMSYSM_ACTIVE,
47 || {
48 ResultCode(unsafe { ctru_sys::ptmSysmInit() })?;
49
50 Ok(())
51 },
52 || unsafe {
53 ctru_sys::ptmSysmExit();
54 },
55 )?;
56
57 Ok(Self {
58 _service_handler: handler,
59 })
60 }
61
62 /// Try putting the console in sleep mode.
63 ///
64 /// # Notes
65 ///
66 /// This request can be denied for various reasons. This does not "force" the console to sleep.
67 ///
68 /// # Example
69 ///
70 /// ```
71 /// # let _runner = test_runner::GdbRunner::default();
72 /// # use std::error::Error;
73 /// # fn main() -> Result<(), Box<dyn Error>> {
74 /// #
75 /// use ctru::services::ptm::sysm::PTMSysM;
76 /// use std::time::Duration;
77 ///
78 /// let ptm_sysm = PTMSysM::new()?;
79 ///
80 /// // Request the activation of sleep mode.
81 /// ptm_sysm.request_sleep().unwrap();
82 /// #
83 /// # Ok(())
84 /// # }
85 /// ```
86 #[doc(alias = "PTMSYSM_RequestSleep")]
87 pub fn request_sleep(&self) -> Result<()> {
88 ResultCode(unsafe { ctru_sys::PTMSYSM_RequestSleep() })?;
89
90 Ok(())
91 }
92
93 /// Request a system shutdown within the given timeout.
94 ///
95 /// # Example
96 ///
97 /// ```
98 /// # let _runner = test_runner::GdbRunner::default();
99 /// # use std::error::Error;
100 /// # fn main() -> Result<(), Box<dyn Error>> {
101 /// #
102 /// use ctru::services::ptm::sysm::PTMSysM;
103 /// use std::time::Duration;
104 ///
105 /// let ptm_sysm = PTMSysM::new()?;
106 ///
107 /// // Shutdown the system (usually the request succeeds immediately).
108 /// ptm_sysm.request_shutdown(Duration::from_nanos(0)).unwrap();
109 /// #
110 /// # Ok(())
111 /// # }
112 /// ```
113 #[doc(alias = "PTMSYSM_ShutdownAsync")]
114 pub fn request_shutdown(&self, timeout: Duration) -> Result<()> {
115 let timeout = timeout.as_nanos() as u64;
116
117 ResultCode(unsafe { ctru_sys::PTMSYSM_ShutdownAsync(timeout) })?;
118
119 Ok(())
120 }
121
122 /// Request a system reboot within the given timeout.
123 ///
124 /// # Example
125 ///
126 /// ```
127 /// # let _runner = test_runner::GdbRunner::default();
128 /// # use std::error::Error;
129 /// # fn main() -> Result<(), Box<dyn Error>> {
130 /// #
131 /// use ctru::services::ptm::sysm::PTMSysM;
132 /// use std::time::Duration;
133 ///
134 /// let ptm_sysm = PTMSysM::new()?;
135 ///
136 /// // Reboot the system.
137 /// ptm_sysm.request_reboot(Duration::from_nanos(0)).unwrap();
138 /// #
139 /// # Ok(())
140 /// # }
141 /// ```
142 #[doc(alias = "PTMSYSM_RebootAsync")]
143 pub fn request_reboot(&self, timeout: Duration) -> Result<()> {
144 let timeout = timeout.as_nanos() as u64;
145
146 ResultCode(unsafe { ctru_sys::PTMSYSM_RebootAsync(timeout) })?;
147
148 Ok(())
149 }
150}