rusty_libimobiledevice/services/
mobile_activation.rs1use std::ffi::CString;
4
5use crate::{
6 bindings as unsafe_bindings, error::MobileActivationError, idevice::Device,
7 services::lockdownd::LockdowndService,
8};
9
10use plist_plus::Plist;
11
12pub struct MobileActivationClient<'a> {
13 pub(crate) pointer: unsafe_bindings::mobileactivation_client_t,
14 phantom: std::marker::PhantomData<&'a Device>,
15}
16
17impl MobileActivationClient<'_> {
18 pub fn new(
27 device: &Device,
28 descriptor: LockdowndService,
29 ) -> Result<Self, MobileActivationError> {
30 let mut client = unsafe { std::mem::zeroed() };
31
32 let result = unsafe {
33 unsafe_bindings::mobileactivation_client_new(
34 device.pointer,
35 descriptor.pointer,
36 &mut client,
37 )
38 }
39 .into();
40
41 if result != MobileActivationError::Success {
42 return Err(result);
43 }
44
45 Ok(MobileActivationClient {
46 pointer: client,
47 phantom: std::marker::PhantomData,
48 })
49 }
50
51 pub fn start_service(
60 device: &Device,
61 label: impl Into<String>,
62 ) -> Result<Self, MobileActivationError> {
63 let label_c_string = CString::new(label.into()).unwrap();
64 let mut client = unsafe { std::mem::zeroed() };
65
66 let result = unsafe {
67 unsafe_bindings::mobileactivation_client_start_service(
68 device.pointer,
69 &mut client,
70 label_c_string.as_ptr(),
71 )
72 }
73 .into();
74
75 if result != MobileActivationError::Success {
76 return Err(result);
77 }
78
79 Ok(MobileActivationClient {
80 pointer: client,
81 phantom: std::marker::PhantomData,
82 })
83 }
84
85 pub fn get_activation_state(&self) -> Result<Plist, MobileActivationError> {
93 let mut plist = unsafe { std::mem::zeroed() };
94
95 let result = unsafe {
96 unsafe_bindings::mobileactivation_get_activation_state(self.pointer, &mut plist)
97 }
98 .into();
99
100 if result != MobileActivationError::Success {
101 return Err(result);
102 }
103
104 Ok(plist.into())
105 }
106
107 pub fn create_activation_session_info(&self) -> Result<Plist, MobileActivationError> {
114 let mut plist = unsafe { std::mem::zeroed() };
115
116 let result = unsafe {
117 unsafe_bindings::mobileactivation_create_activation_session_info(
118 self.pointer,
119 &mut plist,
120 )
121 }
122 .into();
123
124 if result != MobileActivationError::Success {
125 return Err(result);
126 }
127
128 Ok(plist.into())
129 }
130
131 pub fn create_activation_info_with_session(
139 &self,
140 ) -> Result<(Plist, Plist), MobileActivationError> {
141 let plist = unsafe { std::mem::zeroed() };
142 let mut session_plist = unsafe { std::mem::zeroed() };
143
144 let result = unsafe {
145 unsafe_bindings::mobileactivation_create_activation_info_with_session(
146 self.pointer,
147 plist,
148 &mut session_plist,
149 )
150 }
151 .into();
152
153 if result != MobileActivationError::Success {
154 return Err(result);
155 }
156
157 Ok((plist.into(), session_plist.into()))
158 }
159
160 pub fn activate(
169 &self,
170 record: Plist,
171 session: Option<Plist>,
172 ) -> Result<(), MobileActivationError> {
173 let result = unsafe {
174 if let Some(session) = session {
175 unsafe_bindings::mobileactivation_activate_with_session(
176 self.pointer,
177 record.get_pointer(),
178 session.get_pointer(),
179 )
180 } else {
181 unsafe_bindings::mobileactivation_activate(self.pointer, record.get_pointer())
182 }
183 }
184 .into();
185
186 if result != MobileActivationError::Success {
187 return Err(result);
188 }
189
190 Ok(())
191 }
192
193 pub fn deactivate(&self) -> Result<(), MobileActivationError> {
201 let result = unsafe { unsafe_bindings::mobileactivation_deactivate(self.pointer) }.into();
202
203 if result != MobileActivationError::Success {
204 return Err(result);
205 }
206
207 Ok(())
208 }
209}
210
211impl Drop for MobileActivationClient<'_> {
212 fn drop(&mut self) {
213 unsafe {
214 unsafe_bindings::mobileactivation_client_free(self.pointer);
215 }
216 }
217}