diff options
Diffstat (limited to 'cython')
-rw-r--r-- | cython/Makefile.am | 84 | ||||
-rw-r--r-- | cython/afc.pxi | 337 | ||||
-rw-r--r-- | cython/debugserver.pxi | 252 | ||||
-rw-r--r-- | cython/diagnostics_relay.pxi | 128 | ||||
-rw-r--r-- | cython/file_relay.pxi | 68 | ||||
-rw-r--r-- | cython/heartbeat.pxi | 60 | ||||
-rw-r--r-- | cython/house_arrest.pxi | 84 | ||||
-rw-r--r-- | cython/imobiledevice.pxd | 110 | ||||
-rw-r--r-- | cython/imobiledevice.pyx | 294 | ||||
-rw-r--r-- | cython/installation_proxy.pxi | 304 | ||||
-rw-r--r-- | cython/lockdown.pxi | 351 | ||||
-rw-r--r-- | cython/misagent.pxi | 74 | ||||
-rw-r--r-- | cython/mobile_image_mounter.pxi | 115 | ||||
-rw-r--r-- | cython/mobilebackup.pxi | 110 | ||||
-rw-r--r-- | cython/mobilebackup2.pxi | 123 | ||||
-rw-r--r-- | cython/mobilesync.pxi | 164 | ||||
-rw-r--r-- | cython/notification_proxy.pxi | 110 | ||||
-rw-r--r-- | cython/restore.pxi | 131 | ||||
-rw-r--r-- | cython/sbservices.pxi | 80 | ||||
-rw-r--r-- | cython/screenshotr.pxi | 66 | ||||
-rw-r--r-- | cython/webinspector.pxi | 60 |
21 files changed, 3105 insertions, 0 deletions
diff --git a/cython/Makefile.am b/cython/Makefile.am new file mode 100644 index 0000000..93ea6ed --- /dev/null +++ b/cython/Makefile.am | |||
@@ -0,0 +1,84 @@ | |||
1 | AM_CPPFLAGS = \ | ||
2 | -I$(top_srcdir)/include | ||
3 | |||
4 | AM_CFLAGS = \ | ||
5 | $(GLOBAL_CFLAGS) \ | ||
6 | $(ssl_lib_CFLAGS) \ | ||
7 | $(LFS_CFLAGS) \ | ||
8 | $(PTHREAD_CFLAGS) \ | ||
9 | $(libplist_CFLAGS) | ||
10 | |||
11 | AM_LIBS = \ | ||
12 | $(ssl_lib_LIBS) \ | ||
13 | $(PTHREAD_LIBS) \ | ||
14 | $(libplist_LIBS) | ||
15 | |||
16 | if HAVE_CYTHON | ||
17 | |||
18 | BUILT_SOURCES = imobiledevice.c | ||
19 | PXDINCLUDES = \ | ||
20 | imobiledevice.pxd \ | ||
21 | $(CYTHON_PLIST_INCLUDE_DIR)/plist.pxd | ||
22 | |||
23 | PXIINCLUDES = \ | ||
24 | lockdown.pxi \ | ||
25 | mobilesync.pxi \ | ||
26 | notification_proxy.pxi \ | ||
27 | sbservices.pxi \ | ||
28 | mobilebackup.pxi \ | ||
29 | mobilebackup2.pxi \ | ||
30 | afc.pxi \ | ||
31 | file_relay.pxi \ | ||
32 | screenshotr.pxi \ | ||
33 | installation_proxy.pxi \ | ||
34 | webinspector.pxi \ | ||
35 | heartbeat.pxi \ | ||
36 | diagnostics_relay.pxi \ | ||
37 | misagent.pxi \ | ||
38 | house_arrest.pxi \ | ||
39 | restore.pxi \ | ||
40 | mobile_image_mounter.pxi \ | ||
41 | debugserver.pxi | ||
42 | |||
43 | CLEANFILES = \ | ||
44 | *.pyc \ | ||
45 | *.pyo \ | ||
46 | imobiledevice.c | ||
47 | |||
48 | EXTRA_DIST = \ | ||
49 | imobiledevice.pyx \ | ||
50 | imobiledevice.pxd \ | ||
51 | $(PXIINCLUDES) | ||
52 | |||
53 | imobiledevicedir = $(pyexecdir) | ||
54 | imobiledevice_LTLIBRARIES = imobiledevice.la | ||
55 | imobiledevice_la_SOURCES = imobiledevice.pyx | ||
56 | imobiledevice_la_CFLAGS = \ | ||
57 | -I$(top_srcdir)/include \ | ||
58 | -I$(top_srcdir)/src \ | ||
59 | $(PYTHON_CPPFLAGS) \ | ||
60 | $(AM_CFLAGS) \ | ||
61 | -Wno-shadow \ | ||
62 | -Wno-redundant-decls \ | ||
63 | -Wno-switch-default \ | ||
64 | -Wno-strict-aliasing \ | ||
65 | -Wno-implicit-function-declaration \ | ||
66 | -fvisibility=default \ | ||
67 | $(CYTHON_CFLAGS) | ||
68 | |||
69 | imobiledevice_la_LDFLAGS = \ | ||
70 | -module \ | ||
71 | -avoid-version \ | ||
72 | -L$(libdir) \ | ||
73 | $(PYTHON_LIBS) \ | ||
74 | $(AM_LIBS) \ | ||
75 | -no-undefined | ||
76 | |||
77 | imobiledevice_la_LIBADD = $(top_builddir)/src/libimobiledevice-1.0.la | ||
78 | |||
79 | imobiledevice.c: imobiledevice.pyx $(PXDINCLUDES) $(PXIINCLUDES) | ||
80 | |||
81 | .pyx.c: | ||
82 | $(CYTHON) -I$(CYTHON_PLIST_INCLUDE_DIR) -I$(top_srcdir)/src -o $@ $< | ||
83 | |||
84 | endif | ||
diff --git a/cython/afc.pxi b/cython/afc.pxi new file mode 100644 index 0000000..6bd8182 --- /dev/null +++ b/cython/afc.pxi | |||
@@ -0,0 +1,337 @@ | |||
1 | cdef extern from "libimobiledevice/afc.h": | ||
2 | cdef struct afc_client_private: | ||
3 | pass | ||
4 | ctypedef afc_client_private *afc_client_t | ||
5 | ctypedef enum afc_error_t: | ||
6 | AFC_E_SUCCESS = 0 | ||
7 | AFC_E_UNKNOWN_ERROR = 1 | ||
8 | AFC_E_OP_HEADER_INVALID = 2 | ||
9 | AFC_E_NO_RESOURCES = 3 | ||
10 | AFC_E_READ_ERROR = 4 | ||
11 | AFC_E_WRITE_ERROR = 5 | ||
12 | AFC_E_UNKNOWN_PACKET_TYPE = 6 | ||
13 | AFC_E_INVALID_ARG = 7 | ||
14 | AFC_E_OBJECT_NOT_FOUND = 8 | ||
15 | AFC_E_OBJECT_IS_DIR = 9 | ||
16 | AFC_E_PERM_DENIED = 10 | ||
17 | AFC_E_SERVICE_NOT_CONNECTED = 11 | ||
18 | AFC_E_OP_TIMEOUT = 12 | ||
19 | AFC_E_TOO_MUCH_DATA = 13 | ||
20 | AFC_E_END_OF_DATA = 14 | ||
21 | AFC_E_OP_NOT_SUPPORTED = 15 | ||
22 | AFC_E_OBJECT_EXISTS = 16 | ||
23 | AFC_E_OBJECT_BUSY = 17 | ||
24 | AFC_E_NO_SPACE_LEFT = 18 | ||
25 | AFC_E_OP_WOULD_BLOCK = 19 | ||
26 | AFC_E_IO_ERROR = 20 | ||
27 | AFC_E_OP_INTERRUPTED = 21 | ||
28 | AFC_E_OP_IN_PROGRESS = 22 | ||
29 | AFC_E_INTERNAL_ERROR = 23 | ||
30 | AFC_E_MUX_ERROR = 30 | ||
31 | AFC_E_NO_MEM = 31 | ||
32 | AFC_E_NOT_ENOUGH_DATA = 32 | ||
33 | AFC_E_DIR_NOT_EMPTY = 33 | ||
34 | ctypedef enum afc_file_mode_t: | ||
35 | AFC_FOPEN_RDONLY = 0x00000001 | ||
36 | AFC_FOPEN_RW = 0x00000002 | ||
37 | AFC_FOPEN_WRONLY = 0x00000003 | ||
38 | AFC_FOPEN_WR = 0x00000004 | ||
39 | AFC_FOPEN_APPEND = 0x00000005 | ||
40 | AFC_FOPEN_RDAPPEND = 0x00000006 | ||
41 | ctypedef enum afc_link_type_t: | ||
42 | AFC_HARDLINK = 1 | ||
43 | AFC_SYMLINK = 2 | ||
44 | ctypedef enum afc_lock_op_t: | ||
45 | AFC_LOCK_SH = 1 | 4 | ||
46 | AFC_LOCK_EX = 2 | 4 | ||
47 | AFC_LOCK_UN = 8 | 4 | ||
48 | |||
49 | afc_error_t afc_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, afc_client_t *client) | ||
50 | afc_error_t afc_client_free(afc_client_t client) | ||
51 | afc_error_t afc_get_device_info(afc_client_t client, char ***infos) | ||
52 | afc_error_t afc_read_directory(afc_client_t client, char *dir, char ***list) | ||
53 | afc_error_t afc_get_file_info(afc_client_t client, char *filename, char ***infolist) | ||
54 | afc_error_t afc_remove_path(afc_client_t client, char *path) | ||
55 | afc_error_t afc_remove_path_and_contents(afc_client_t client, char *path) | ||
56 | afc_error_t afc_rename_path(afc_client_t client, char *f, char *to) | ||
57 | afc_error_t afc_make_directory(afc_client_t client, char *dir) | ||
58 | afc_error_t afc_truncate(afc_client_t client, char *path, uint64_t newsize) | ||
59 | afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, char *target, char *linkname) | ||
60 | afc_error_t afc_set_file_time(afc_client_t client, char *path, uint64_t mtime) | ||
61 | |||
62 | afc_error_t afc_file_open(afc_client_t client, char *filename, afc_file_mode_t file_mode, uint64_t *handle) | ||
63 | afc_error_t afc_file_close(afc_client_t client, uint64_t handle) | ||
64 | afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation) | ||
65 | afc_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read) | ||
66 | afc_error_t afc_file_write(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_written) | ||
67 | afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence) | ||
68 | afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position) | ||
69 | afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize) | ||
70 | |||
71 | LOCK_SH = AFC_LOCK_SH | ||
72 | LOCK_EX = AFC_LOCK_EX | ||
73 | LOCK_UN = AFC_LOCK_UN | ||
74 | |||
75 | cdef class AfcError(BaseError): | ||
76 | def __init__(self, *args, **kwargs): | ||
77 | self._lookup_table = { | ||
78 | AFC_E_SUCCESS: "Success", | ||
79 | AFC_E_UNKNOWN_ERROR: "Unknown error", | ||
80 | AFC_E_OP_HEADER_INVALID: "OP header invalid", | ||
81 | AFC_E_NO_RESOURCES: "No resources", | ||
82 | AFC_E_READ_ERROR: "Read error", | ||
83 | AFC_E_WRITE_ERROR: "Write error", | ||
84 | AFC_E_UNKNOWN_PACKET_TYPE: "Unknown packet type", | ||
85 | AFC_E_INVALID_ARG: "Invalid argument", | ||
86 | AFC_E_OBJECT_NOT_FOUND: "Object not found", | ||
87 | AFC_E_OBJECT_IS_DIR: "Object is directory", | ||
88 | AFC_E_PERM_DENIED: "Permission denied", | ||
89 | AFC_E_SERVICE_NOT_CONNECTED: "Service not connected", | ||
90 | AFC_E_OP_TIMEOUT: "OP timeout", | ||
91 | AFC_E_TOO_MUCH_DATA: "Too much data", | ||
92 | AFC_E_END_OF_DATA: "End of data", | ||
93 | AFC_E_OP_NOT_SUPPORTED: "OP not supported", | ||
94 | AFC_E_OBJECT_EXISTS: "Object exists", | ||
95 | AFC_E_OBJECT_BUSY: "Object busy", | ||
96 | AFC_E_NO_SPACE_LEFT: "No space left", | ||
97 | AFC_E_OP_WOULD_BLOCK: "OP would block", | ||
98 | AFC_E_IO_ERROR: "IO error", | ||
99 | AFC_E_OP_INTERRUPTED: "OP interrupted", | ||
100 | AFC_E_OP_IN_PROGRESS: "OP in progress", | ||
101 | AFC_E_INTERNAL_ERROR: "Internal error", | ||
102 | AFC_E_MUX_ERROR: "MUX error", | ||
103 | AFC_E_NO_MEM: "No memory", | ||
104 | AFC_E_NOT_ENOUGH_DATA: "Not enough data", | ||
105 | AFC_E_DIR_NOT_EMPTY: "Directory not empty" | ||
106 | } | ||
107 | BaseError.__init__(self, *args, **kwargs) | ||
108 | |||
109 | # forward declaration of AfcClient | ||
110 | cdef class AfcClient(BaseService) | ||
111 | |||
112 | cdef class AfcFile(Base): | ||
113 | cdef uint64_t _c_handle | ||
114 | cdef AfcClient _client | ||
115 | cdef bytes _filename | ||
116 | |||
117 | def __init__(self, *args, **kwargs): | ||
118 | raise TypeError("AfcFile cannot be instantiated") | ||
119 | |||
120 | def __enter__(self): | ||
121 | return self | ||
122 | |||
123 | def __exit__(self, type, value, traceback): | ||
124 | self.close() | ||
125 | |||
126 | cpdef close(self): | ||
127 | self.handle_error(afc_file_close(self._client._c_client, self._c_handle)) | ||
128 | |||
129 | cpdef lock(self, int operation): | ||
130 | self.handle_error(afc_file_lock(self._client._c_client, self._c_handle, <afc_lock_op_t>operation)) | ||
131 | |||
132 | cpdef seek(self, int64_t offset, int whence): | ||
133 | self.handle_error(afc_file_seek(self._client._c_client, self._c_handle, offset, whence)) | ||
134 | |||
135 | cpdef uint64_t tell(self): | ||
136 | cdef uint64_t position | ||
137 | self.handle_error(afc_file_tell(self._client._c_client, self._c_handle, &position)) | ||
138 | return position | ||
139 | |||
140 | cpdef truncate(self, uint64_t newsize): | ||
141 | self.handle_error(afc_file_truncate(self._client._c_client, self._c_handle, newsize)) | ||
142 | |||
143 | cpdef bytes read(self, uint32_t size): | ||
144 | cdef: | ||
145 | uint32_t bytes_read | ||
146 | char* c_data = <char *>malloc(size) | ||
147 | bytes result | ||
148 | try: | ||
149 | self.handle_error(afc_file_read(self._client._c_client, self._c_handle, c_data, size, &bytes_read)) | ||
150 | result = c_data[:bytes_read] | ||
151 | return result | ||
152 | except BaseError, e: | ||
153 | raise | ||
154 | finally: | ||
155 | free(c_data) | ||
156 | |||
157 | cpdef uint32_t write(self, bytes data): | ||
158 | cdef: | ||
159 | uint32_t bytes_written | ||
160 | char* c_data = data | ||
161 | try: | ||
162 | self.handle_error(afc_file_write(self._client._c_client, self._c_handle, c_data, len(data), &bytes_written)) | ||
163 | except BaseError, e: | ||
164 | raise | ||
165 | |||
166 | return bytes_written | ||
167 | |||
168 | cdef inline BaseError _error(self, int16_t ret): | ||
169 | return AfcError(ret) | ||
170 | |||
171 | cdef class AfcClient(BaseService): | ||
172 | __service_name__ = "com.apple.afc" | ||
173 | cdef afc_client_t _c_client | ||
174 | |||
175 | def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs): | ||
176 | if (device is not None and descriptor is not None): | ||
177 | self.handle_error(afc_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client))) | ||
178 | |||
179 | def __dealloc__(self): | ||
180 | cdef afc_error_t err | ||
181 | if self._c_client is not NULL: | ||
182 | err = afc_client_free(self._c_client) | ||
183 | self.handle_error(err) | ||
184 | |||
185 | cdef BaseError _error(self, int16_t ret): | ||
186 | return AfcError(ret) | ||
187 | |||
188 | cpdef list get_device_info(self): | ||
189 | cdef: | ||
190 | afc_error_t err | ||
191 | char** infos = NULL | ||
192 | bytes info | ||
193 | int i = 0 | ||
194 | list result = [] | ||
195 | err = afc_get_device_info(self._c_client, &infos) | ||
196 | try: | ||
197 | self.handle_error(err) | ||
198 | except BaseError, e: | ||
199 | raise | ||
200 | finally: | ||
201 | if infos != NULL: | ||
202 | while infos[i]: | ||
203 | info = infos[i] | ||
204 | result.append(info) | ||
205 | free(infos[i]) | ||
206 | i = i + 1 | ||
207 | free(infos) | ||
208 | |||
209 | return result | ||
210 | |||
211 | cpdef list read_directory(self, bytes directory): | ||
212 | cdef: | ||
213 | afc_error_t err | ||
214 | char** dir_list = NULL | ||
215 | bytes f | ||
216 | int i = 0 | ||
217 | list result = [] | ||
218 | err = afc_read_directory(self._c_client, directory, &dir_list) | ||
219 | try: | ||
220 | self.handle_error(err) | ||
221 | except BaseError, e: | ||
222 | raise | ||
223 | finally: | ||
224 | if dir_list != NULL: | ||
225 | while dir_list[i]: | ||
226 | f = dir_list[i] | ||
227 | result.append(f) | ||
228 | free(dir_list[i]) | ||
229 | i = i + 1 | ||
230 | free(dir_list) | ||
231 | |||
232 | return result | ||
233 | |||
234 | cpdef AfcFile open(self, bytes filename, bytes mode=b'r'): | ||
235 | cdef: | ||
236 | afc_file_mode_t c_mode | ||
237 | uint64_t handle | ||
238 | AfcFile f | ||
239 | if mode == b'r': | ||
240 | c_mode = AFC_FOPEN_RDONLY | ||
241 | elif mode == b'r+': | ||
242 | c_mode = AFC_FOPEN_RW | ||
243 | elif mode == b'w': | ||
244 | c_mode = AFC_FOPEN_WRONLY | ||
245 | elif mode == b'w+': | ||
246 | c_mode = AFC_FOPEN_WR | ||
247 | elif mode == b'a': | ||
248 | c_mode = AFC_FOPEN_APPEND | ||
249 | elif mode == b'a+': | ||
250 | c_mode = AFC_FOPEN_RDAPPEND | ||
251 | else: | ||
252 | raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'") | ||
253 | |||
254 | self.handle_error(afc_file_open(self._c_client, filename, c_mode, &handle)) | ||
255 | f = AfcFile.__new__(AfcFile) | ||
256 | f._c_handle = handle | ||
257 | f._client = self | ||
258 | f._filename = filename | ||
259 | |||
260 | return f | ||
261 | |||
262 | cpdef list get_file_info(self, bytes path): | ||
263 | cdef: | ||
264 | list result = [] | ||
265 | char** c_result = NULL | ||
266 | int i = 0 | ||
267 | bytes info | ||
268 | try: | ||
269 | self.handle_error(afc_get_file_info(self._c_client, path, &c_result)) | ||
270 | except BaseError, e: | ||
271 | raise | ||
272 | finally: | ||
273 | if c_result != NULL: | ||
274 | while c_result[i]: | ||
275 | info = c_result[i] | ||
276 | result.append(info) | ||
277 | free(c_result[i]) | ||
278 | i = i + 1 | ||
279 | free(c_result) | ||
280 | |||
281 | return result | ||
282 | |||
283 | cpdef remove_path(self, bytes path): | ||
284 | self.handle_error(afc_remove_path(self._c_client, path)) | ||
285 | |||
286 | cpdef remove_path_and_contents(self, bytes path): | ||
287 | self.handle_error(afc_remove_path_and_contents(self._c_client, path)) | ||
288 | |||
289 | cpdef rename_path(self, bytes f, bytes t): | ||
290 | self.handle_error(afc_rename_path(self._c_client, f, t)) | ||
291 | |||
292 | cpdef make_directory(self, bytes d): | ||
293 | self.handle_error(afc_make_directory(self._c_client, d)) | ||
294 | |||
295 | cpdef truncate(self, bytes path, uint64_t newsize): | ||
296 | self.handle_error(afc_truncate(self._c_client, path, newsize)) | ||
297 | |||
298 | cpdef link(self, bytes source, bytes link_name): | ||
299 | self.handle_error(afc_make_link(self._c_client, AFC_HARDLINK, source, link_name)) | ||
300 | |||
301 | cpdef symlink(self, bytes source, bytes link_name): | ||
302 | self.handle_error(afc_make_link(self._c_client, AFC_SYMLINK, source, link_name)) | ||
303 | |||
304 | cpdef set_file_time(self, bytes path, uint64_t mtime): | ||
305 | self.handle_error(afc_set_file_time(self._c_client, path, mtime)) | ||
306 | |||
307 | cdef class Afc2Client(AfcClient): | ||
308 | __service_name__ = "com.apple.afc2" | ||
309 | |||
310 | cpdef AfcFile open(self, bytes filename, bytes mode=b'r'): | ||
311 | cdef: | ||
312 | afc_file_mode_t c_mode | ||
313 | uint64_t handle | ||
314 | AfcFile f | ||
315 | if mode == b'r': | ||
316 | c_mode = AFC_FOPEN_RDONLY | ||
317 | elif mode == b'r+': | ||
318 | c_mode = AFC_FOPEN_RW | ||
319 | elif mode == b'w': | ||
320 | c_mode = AFC_FOPEN_WRONLY | ||
321 | elif mode == b'w+': | ||
322 | c_mode = AFC_FOPEN_WR | ||
323 | elif mode == b'a': | ||
324 | c_mode = AFC_FOPEN_APPEND | ||
325 | elif mode == b'a+': | ||
326 | c_mode = AFC_FOPEN_RDAPPEND | ||
327 | else: | ||
328 | raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'") | ||
329 | |||
330 | self.handle_error(afc_file_open(self._c_client, filename, c_mode, &handle)) | ||
331 | f = AfcFile.__new__(AfcFile) | ||
332 | f._c_handle = handle | ||
333 | f._client = <AfcClient>self | ||
334 | f._filename = filename | ||
335 | |||
336 | return f | ||
337 | |||
diff --git a/cython/debugserver.pxi b/cython/debugserver.pxi new file mode 100644 index 0000000..a3b7d1e --- /dev/null +++ b/cython/debugserver.pxi | |||
@@ -0,0 +1,252 @@ | |||
1 | cdef extern from "libimobiledevice/debugserver.h": | ||
2 | cdef struct debugserver_client_private: | ||
3 | pass | ||
4 | ctypedef debugserver_client_private *debugserver_client_t | ||
5 | cdef struct debugserver_command_private: | ||
6 | pass | ||
7 | ctypedef debugserver_command_private *debugserver_command_t | ||
8 | ctypedef enum debugserver_error_t: | ||
9 | DEBUGSERVER_E_SUCCESS = 0 | ||
10 | DEBUGSERVER_E_INVALID_ARG = -1 | ||
11 | DEBUGSERVER_E_MUX_ERROR = -2 | ||
12 | DEBUGSERVER_E_SSL_ERROR = -3 | ||
13 | DEBUGSERVER_E_RESPONSE_ERROR = -4 | ||
14 | DEBUGSERVER_E_UNKNOWN_ERROR = -256 | ||
15 | |||
16 | debugserver_error_t debugserver_client_new(idevice_t device, lockdownd_service_descriptor_t service, debugserver_client_t * client) | ||
17 | debugserver_error_t debugserver_client_free(debugserver_client_t client) | ||
18 | |||
19 | debugserver_error_t debugserver_client_send(debugserver_client_t client, const char* data, uint32_t size, uint32_t *sent) | ||
20 | debugserver_error_t debugserver_client_send_command(debugserver_client_t client, debugserver_command_t command, char** response, size_t* response_size) | ||
21 | debugserver_error_t debugserver_client_receive(debugserver_client_t client, char *data, uint32_t size, uint32_t *received) | ||
22 | debugserver_error_t debugserver_client_receive_with_timeout(debugserver_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout) | ||
23 | debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response, size_t* response_size) | ||
24 | debugserver_error_t debugserver_client_set_argv(debugserver_client_t client, int argc, char* argv[], char** response) | ||
25 | debugserver_error_t debugserver_client_set_environment_hex_encoded(debugserver_client_t client, const char* env, char** response) | ||
26 | |||
27 | debugserver_error_t debugserver_command_new(const char* name, int argc, const char* argv[], debugserver_command_t* command) | ||
28 | debugserver_error_t debugserver_command_free(debugserver_command_t command) | ||
29 | void debugserver_encode_string(const char* buffer, char** encoded_buffer, uint32_t* encoded_length) | ||
30 | void debugserver_decode_string(const char *encoded_buffer, size_t encoded_length, char** buffer) | ||
31 | |||
32 | |||
33 | cdef class DebugServerError(BaseError): | ||
34 | def __init__(self, *args, **kwargs): | ||
35 | self._lookup_table = { | ||
36 | DEBUGSERVER_E_SUCCESS: "Success", | ||
37 | DEBUGSERVER_E_INVALID_ARG: "Invalid argument", | ||
38 | DEBUGSERVER_E_MUX_ERROR: "MUX error", | ||
39 | DEBUGSERVER_E_SSL_ERROR: "SSL error", | ||
40 | DEBUGSERVER_E_RESPONSE_ERROR: "Response error", | ||
41 | DEBUGSERVER_E_UNKNOWN_ERROR: "Unknown error", | ||
42 | } | ||
43 | BaseError.__init__(self, *args, **kwargs) | ||
44 | |||
45 | |||
46 | # from http://stackoverflow.com/a/17511714 | ||
47 | # https://github.com/libimobiledevice/libimobiledevice/pull/198 | ||
48 | from cpython cimport PY_MAJOR_VERSION | ||
49 | if PY_MAJOR_VERSION <= 2: | ||
50 | from cpython.string cimport PyString_AsString | ||
51 | else: | ||
52 | from cpython.bytes cimport PyBytes_AsString as PyString_AsString | ||
53 | cdef char ** to_cstring_array(list_str): | ||
54 | if not list_str: | ||
55 | return NULL | ||
56 | cdef char **ret = <char **>malloc(len(list_str) * sizeof(char *)) | ||
57 | for i in xrange(len(list_str)): | ||
58 | ret[i] = PyString_AsString(list_str[i]) | ||
59 | return ret | ||
60 | |||
61 | |||
62 | cdef class DebugServerCommand(Base): | ||
63 | cdef debugserver_command_t _c_command | ||
64 | |||
65 | def __init__(self, bytes name, int argc = 0, argv = None, *args, **kwargs): | ||
66 | cdef: | ||
67 | char* c_name = name | ||
68 | char** c_argv = to_cstring_array(argv) | ||
69 | |||
70 | try: | ||
71 | self.handle_error(debugserver_command_new(c_name, argc, c_argv, &self._c_command)) | ||
72 | except BaseError, e: | ||
73 | raise | ||
74 | finally: | ||
75 | free(c_argv) | ||
76 | |||
77 | def __enter__(self): | ||
78 | return self | ||
79 | |||
80 | def __exit__(self, type, value, traceback): | ||
81 | self.free() | ||
82 | |||
83 | cdef free(self): | ||
84 | cdef debugserver_error_t err | ||
85 | if self._c_command is not NULL: | ||
86 | err = debugserver_command_free(self._c_command) | ||
87 | self.handle_error(err) | ||
88 | |||
89 | cdef inline BaseError _error(self, int16_t ret): | ||
90 | return DebugServerError(ret) | ||
91 | |||
92 | |||
93 | cdef class DebugServerClient(BaseService): | ||
94 | __service_name__ = "com.apple.debugserver" | ||
95 | cdef debugserver_client_t _c_client | ||
96 | |||
97 | def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs): | ||
98 | if (device is not None and descriptor is not None): | ||
99 | self.handle_error(debugserver_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client))) | ||
100 | |||
101 | def __dealloc__(self): | ||
102 | cdef debugserver_error_t err | ||
103 | if self._c_client is not NULL: | ||
104 | err = debugserver_client_free(self._c_client) | ||
105 | self.handle_error(err) | ||
106 | |||
107 | cdef BaseError _error(self, int16_t ret): | ||
108 | return DebugServerError(ret) | ||
109 | |||
110 | cpdef uint32_t send(self, bytes data): | ||
111 | cdef: | ||
112 | uint32_t bytes_send | ||
113 | char* c_data = data | ||
114 | try: | ||
115 | self.handle_error(debugserver_client_send(self._c_client, c_data, len(data), &bytes_send)) | ||
116 | except BaseError, e: | ||
117 | raise | ||
118 | |||
119 | return bytes_send | ||
120 | |||
121 | cpdef bytes send_command(self, DebugServerCommand command): | ||
122 | cdef: | ||
123 | char* c_response = NULL | ||
124 | bytes result | ||
125 | |||
126 | try: | ||
127 | self.handle_error(debugserver_client_send_command(self._c_client, command._c_command, &c_response, NULL)) | ||
128 | if c_response: | ||
129 | result = c_response | ||
130 | return result | ||
131 | else: | ||
132 | return None | ||
133 | except BaseError, e: | ||
134 | raise | ||
135 | finally: | ||
136 | free(c_response) | ||
137 | |||
138 | cpdef bytes receive(self, uint32_t size): | ||
139 | cdef: | ||
140 | uint32_t bytes_received | ||
141 | char* c_data = <char *>malloc(size) | ||
142 | bytes result | ||
143 | |||
144 | try: | ||
145 | self.handle_error(debugserver_client_receive(self._c_client, c_data, size, &bytes_received)) | ||
146 | result = c_data[:bytes_received] | ||
147 | return result | ||
148 | except BaseError, e: | ||
149 | raise | ||
150 | finally: | ||
151 | free(c_data) | ||
152 | |||
153 | cpdef bytes receive_with_timeout(self, uint32_t size, unsigned int timeout): | ||
154 | cdef: | ||
155 | uint32_t bytes_received | ||
156 | char* c_data = <char *>malloc(size) | ||
157 | bytes result | ||
158 | |||
159 | try: | ||
160 | self.handle_error(debugserver_client_receive_with_timeout(self._c_client, c_data, size, &bytes_received, timeout)) | ||
161 | result = c_data[:bytes_received] | ||
162 | return result | ||
163 | except BaseError, e: | ||
164 | raise | ||
165 | finally: | ||
166 | free(c_data) | ||
167 | |||
168 | cpdef bytes receive_response(self): | ||
169 | cdef: | ||
170 | char* c_response = NULL | ||
171 | bytes result | ||
172 | |||
173 | try: | ||
174 | self.handle_error(debugserver_client_receive_response(self._c_client, &c_response, NULL)) | ||
175 | if c_response: | ||
176 | result = c_response | ||
177 | return result | ||
178 | else: | ||
179 | return None | ||
180 | except BaseError, e: | ||
181 | raise | ||
182 | finally: | ||
183 | free(c_response) | ||
184 | |||
185 | cpdef bytes set_argv(self, int argc, argv): | ||
186 | cdef: | ||
187 | char** c_argv = to_cstring_array(argv) | ||
188 | char* c_response = NULL | ||
189 | bytes result | ||
190 | |||
191 | try: | ||
192 | self.handle_error(debugserver_client_set_argv(self._c_client, argc, c_argv, &c_response)) | ||
193 | if c_response: | ||
194 | result = c_response | ||
195 | return result | ||
196 | else: | ||
197 | return None | ||
198 | except BaseError, e: | ||
199 | raise | ||
200 | finally: | ||
201 | free(c_argv) | ||
202 | free(c_response) | ||
203 | |||
204 | cpdef bytes set_environment_hex_encoded(self, bytes env): | ||
205 | cdef: | ||
206 | char* c_env = env | ||
207 | char* c_response = NULL | ||
208 | bytes result | ||
209 | |||
210 | try: | ||
211 | self.handle_error(debugserver_client_set_environment_hex_encoded(self._c_client, c_env, &c_response)) | ||
212 | if c_response: | ||
213 | result = c_response | ||
214 | return result | ||
215 | else: | ||
216 | return None | ||
217 | except BaseError, e: | ||
218 | raise | ||
219 | finally: | ||
220 | free(c_response) | ||
221 | |||
222 | cpdef bytes encode_string(self, bytes buffer): | ||
223 | cdef: | ||
224 | char *c_buffer = buffer | ||
225 | uint32_t encoded_length = len(c_buffer) * 2 + 0x3 + 1 | ||
226 | char* c_encoded_buffer = <char *>malloc(encoded_length) | ||
227 | bytes result | ||
228 | |||
229 | try: | ||
230 | debugserver_encode_string(c_buffer, &c_encoded_buffer, &encoded_length) | ||
231 | result = c_encoded_buffer[:encoded_length] | ||
232 | return result | ||
233 | except BaseError, e: | ||
234 | raise | ||
235 | finally: | ||
236 | free(c_encoded_buffer) | ||
237 | |||
238 | cpdef bytes decode_string(self, bytes encoded_buffer): | ||
239 | cdef: | ||
240 | char* c_encoded_buffer = encoded_buffer | ||
241 | uint32_t encoded_length = len(c_encoded_buffer) | ||
242 | char *c_buffer = <char *>malloc(encoded_length) | ||
243 | bytes result | ||
244 | |||
245 | try: | ||
246 | debugserver_decode_string(c_encoded_buffer, encoded_length, &c_buffer) | ||
247 | result = c_buffer | ||
248 | return result | ||
249 | except BaseError, e: | ||
250 | raise | ||
251 | finally: | ||
252 | free(c_buffer) | ||
diff --git a/cython/diagnostics_relay.pxi b/cython/diagnostics_relay.pxi new file mode 100644 index 0000000..0e6bd20 --- /dev/null +++ b/cython/diagnostics_relay.pxi | |||
@@ -0,0 +1,128 @@ | |||
1 | REQUEST_TYPE_ALL = "All" | ||
2 | REQUEST_TYPE_WIFI = "WiFi" | ||
3 | REQUEST_TYPE_GAS_GAUGE = "GasGauge" | ||
4 | REQUEST_TYPE_NAND = "NAND" | ||
5 | |||
6 | cdef extern from "libimobiledevice/diagnostics_relay.h": | ||
7 | cdef struct diagnostics_relay_client_private: | ||
8 | pass | ||
9 | ctypedef diagnostics_relay_client_private *diagnostics_relay_client_t | ||
10 | |||
11 | ctypedef enum diagnostics_relay_error_t: | ||
12 | DIAGNOSTICS_RELAY_E_SUCCESS = 0 | ||
13 | DIAGNOSTICS_RELAY_E_INVALID_ARG = -1 | ||
14 | DIAGNOSTICS_RELAY_E_PLIST_ERROR = -2 | ||
15 | DIAGNOSTICS_RELAY_E_MUX_ERROR = -3 | ||
16 | DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST = -4 | ||
17 | DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR = -256 | ||
18 | ctypedef enum diagnostics_relay_action_t: | ||
19 | DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT = (1 << 1) | ||
20 | DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS = (1 << 2) | ||
21 | DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL = (1 << 3) | ||
22 | |||
23 | diagnostics_relay_error_t diagnostics_relay_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, diagnostics_relay_client_t * client) | ||
24 | diagnostics_relay_error_t diagnostics_relay_client_free(diagnostics_relay_client_t client) | ||
25 | |||
26 | diagnostics_relay_error_t diagnostics_relay_goodbye(diagnostics_relay_client_t client) | ||
27 | diagnostics_relay_error_t diagnostics_relay_sleep(diagnostics_relay_client_t client) | ||
28 | diagnostics_relay_error_t diagnostics_relay_restart(diagnostics_relay_client_t client, diagnostics_relay_action_t flags) | ||
29 | diagnostics_relay_error_t diagnostics_relay_shutdown(diagnostics_relay_client_t client, diagnostics_relay_action_t flags) | ||
30 | diagnostics_relay_error_t diagnostics_relay_request_diagnostics(diagnostics_relay_client_t client, char* type, plist.plist_t* diagnostics) | ||
31 | diagnostics_relay_error_t diagnostics_relay_query_mobilegestalt(diagnostics_relay_client_t client, plist.plist_t keys, plist.plist_t* result) | ||
32 | diagnostics_relay_error_t diagnostics_relay_query_ioregistry_entry(diagnostics_relay_client_t client, char* name, char* class_name, plist.plist_t* result) | ||
33 | diagnostics_relay_error_t diagnostics_relay_query_ioregistry_plane(diagnostics_relay_client_t client, char* plane, plist.plist_t* result) | ||
34 | |||
35 | cdef class DiagnosticsRelayError(BaseError): | ||
36 | def __init__(self, *args, **kwargs): | ||
37 | self._lookup_table = { | ||
38 | DIAGNOSTICS_RELAY_E_SUCCESS: "Success", | ||
39 | DIAGNOSTICS_RELAY_E_INVALID_ARG: "Invalid argument", | ||
40 | DIAGNOSTICS_RELAY_E_PLIST_ERROR: "Property list error", | ||
41 | DIAGNOSTICS_RELAY_E_MUX_ERROR: "MUX error", | ||
42 | DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST: "Unknown request", | ||
43 | DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR: "Unknown error" | ||
44 | } | ||
45 | BaseError.__init__(self, *args, **kwargs) | ||
46 | |||
47 | cdef class DiagnosticsRelayClient(PropertyListService): | ||
48 | __service_name__ = "com.apple.mobile.diagnostics_relay" | ||
49 | cdef diagnostics_relay_client_t _c_client | ||
50 | |||
51 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
52 | self.handle_error(diagnostics_relay_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
53 | |||
54 | def __dealloc__(self): | ||
55 | cdef diagnostics_relay_error_t err | ||
56 | if self._c_client is not NULL: | ||
57 | err = diagnostics_relay_client_free(self._c_client) | ||
58 | self.handle_error(err) | ||
59 | |||
60 | cdef inline BaseError _error(self, int16_t ret): | ||
61 | return DiagnosticsRelayError(ret) | ||
62 | |||
63 | cpdef goodbye(self): | ||
64 | self.handle_error(diagnostics_relay_goodbye(self._c_client)) | ||
65 | |||
66 | cpdef sleep(self): | ||
67 | self.handle_error(diagnostics_relay_sleep(self._c_client)) | ||
68 | |||
69 | cpdef restart(self, diagnostics_relay_action_t flags): | ||
70 | self.handle_error(diagnostics_relay_restart(self._c_client, flags)) | ||
71 | |||
72 | cpdef shutdown(self, diagnostics_relay_action_t flags): | ||
73 | self.handle_error(diagnostics_relay_shutdown(self._c_client, flags)) | ||
74 | |||
75 | cpdef plist.Node request_diagnostics(self, bytes type): | ||
76 | cdef: | ||
77 | plist.plist_t c_node = NULL | ||
78 | diagnostics_relay_error_t err | ||
79 | err = diagnostics_relay_request_diagnostics(self._c_client, type, &c_node) | ||
80 | try: | ||
81 | self.handle_error(err) | ||
82 | return plist.plist_t_to_node(c_node) | ||
83 | except BaseError, e: | ||
84 | if c_node != NULL: | ||
85 | plist.plist_free(c_node) | ||
86 | raise | ||
87 | |||
88 | cpdef plist.Node query_mobilegestalt(self, plist.Node keys = None): | ||
89 | cdef: | ||
90 | plist.plist_t c_node = NULL | ||
91 | diagnostics_relay_error_t err | ||
92 | plist.plist_t keys_c_node = NULL | ||
93 | if keys is not None: | ||
94 | keys_c_node = keys._c_node | ||
95 | err = diagnostics_relay_query_mobilegestalt(self._c_client, keys_c_node, &c_node) | ||
96 | try: | ||
97 | self.handle_error(err) | ||
98 | return plist.plist_t_to_node(c_node) | ||
99 | except BaseError, e: | ||
100 | if c_node != NULL: | ||
101 | plist.plist_free(c_node) | ||
102 | raise | ||
103 | |||
104 | cpdef plist.Node query_ioregistry_entry(self, bytes name, bytes class_name): | ||
105 | cdef: | ||
106 | plist.plist_t c_node = NULL | ||
107 | diagnostics_relay_error_t err | ||
108 | err = diagnostics_relay_query_ioregistry_entry(self._c_client, name, class_name, &c_node) | ||
109 | try: | ||
110 | self.handle_error(err) | ||
111 | return plist.plist_t_to_node(c_node) | ||
112 | except BaseError, e: | ||
113 | if c_node != NULL: | ||
114 | plist.plist_free(c_node) | ||
115 | raise | ||
116 | |||
117 | cpdef plist.Node query_ioregistry_plane(self, bytes plane = None): | ||
118 | cdef: | ||
119 | plist.plist_t c_node = NULL | ||
120 | diagnostics_relay_error_t err | ||
121 | err = diagnostics_relay_query_ioregistry_plane(self._c_client, plane, &c_node) | ||
122 | try: | ||
123 | self.handle_error(err) | ||
124 | return plist.plist_t_to_node(c_node) | ||
125 | except BaseError, e: | ||
126 | if c_node != NULL: | ||
127 | plist.plist_free(c_node) | ||
128 | raise | ||
diff --git a/cython/file_relay.pxi b/cython/file_relay.pxi new file mode 100644 index 0000000..5e9cbbe --- /dev/null +++ b/cython/file_relay.pxi | |||
@@ -0,0 +1,68 @@ | |||
1 | cdef extern from "libimobiledevice/file_relay.h": | ||
2 | cdef struct file_relay_client_private: | ||
3 | pass | ||
4 | ctypedef file_relay_client_private *file_relay_client_t | ||
5 | ctypedef char** const_sources_t "const char**" | ||
6 | |||
7 | ctypedef enum file_relay_error_t: | ||
8 | FILE_RELAY_E_SUCCESS = 0 | ||
9 | FILE_RELAY_E_INVALID_ARG = -1 | ||
10 | FILE_RELAY_E_PLIST_ERROR = -2 | ||
11 | FILE_RELAY_E_MUX_ERROR = -3 | ||
12 | FILE_RELAY_E_INVALID_SOURCE = -4 | ||
13 | FILE_RELAY_E_STAGING_EMPTY = -5 | ||
14 | FILE_RELAY_E_PERMISSION_DENIED = -6 | ||
15 | FILE_RELAY_E_UNKNOWN_ERROR = -256 | ||
16 | |||
17 | file_relay_error_t file_relay_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, file_relay_client_t *client) | ||
18 | file_relay_error_t file_relay_client_free(file_relay_client_t client) | ||
19 | |||
20 | file_relay_error_t file_relay_request_sources(file_relay_client_t client, const_sources_t sources, idevice_connection_t *connection) | ||
21 | |||
22 | cdef class FileRelayError(BaseError): | ||
23 | def __init__(self, *args, **kwargs): | ||
24 | self._lookup_table = { | ||
25 | FILE_RELAY_E_SUCCESS: "Success", | ||
26 | FILE_RELAY_E_INVALID_ARG: "Invalid argument", | ||
27 | FILE_RELAY_E_PLIST_ERROR: "Property list error", | ||
28 | FILE_RELAY_E_MUX_ERROR: "MUX error", | ||
29 | FILE_RELAY_E_INVALID_SOURCE: "Invalid source", | ||
30 | FILE_RELAY_E_STAGING_EMPTY: "Staging empty", | ||
31 | FILE_RELAY_E_PERMISSION_DENIED: "Permission denied", | ||
32 | FILE_RELAY_E_UNKNOWN_ERROR: "Unknown error" | ||
33 | } | ||
34 | BaseError.__init__(self, *args, **kwargs) | ||
35 | |||
36 | from libc.stdlib cimport * | ||
37 | |||
38 | cdef class FileRelayClient(PropertyListService): | ||
39 | __service_name__ = "com.apple.mobile.file_relay" | ||
40 | cdef file_relay_client_t _c_client | ||
41 | |||
42 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
43 | self.handle_error(file_relay_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
44 | |||
45 | def __dealloc__(self): | ||
46 | cdef file_relay_error_t err | ||
47 | if self._c_client is not NULL: | ||
48 | err = file_relay_client_free(self._c_client) | ||
49 | self.handle_error(err) | ||
50 | |||
51 | cpdef iDeviceConnection request_sources(self, list sources): | ||
52 | cdef: | ||
53 | file_relay_error_t err | ||
54 | Py_ssize_t count = len(sources) | ||
55 | char** c_sources = <char**>malloc(sizeof(char*) * (count + 1)) | ||
56 | iDeviceConnection conn = iDeviceConnection.__new__(iDeviceConnection) | ||
57 | |||
58 | for i, value in enumerate(sources): | ||
59 | c_sources[i] = value | ||
60 | c_sources[count] = NULL | ||
61 | |||
62 | err = file_relay_request_sources(self._c_client, <const_sources_t>c_sources, &conn._c_connection) | ||
63 | free(c_sources) | ||
64 | self.handle_error(err) | ||
65 | return conn | ||
66 | |||
67 | cdef inline BaseError _error(self, int16_t ret): | ||
68 | return FileRelayError(ret) | ||
diff --git a/cython/heartbeat.pxi b/cython/heartbeat.pxi new file mode 100644 index 0000000..2f58909 --- /dev/null +++ b/cython/heartbeat.pxi | |||
@@ -0,0 +1,60 @@ | |||
1 | cdef extern from "libimobiledevice/heartbeat.h": | ||
2 | cdef struct heartbeat_client_private: | ||
3 | pass | ||
4 | ctypedef heartbeat_client_private *heartbeat_client_t | ||
5 | |||
6 | ctypedef enum heartbeat_error_t: | ||
7 | HEARTBEAT_E_SUCCESS = 0 | ||
8 | HEARTBEAT_E_INVALID_ARG = -1 | ||
9 | HEARTBEAT_E_PLIST_ERROR = -2 | ||
10 | HEARTBEAT_E_MUX_ERROR = -3 | ||
11 | HEARTBEAT_E_SSL_ERROR = -4 | ||
12 | HEARTBEAT_E_NOT_ENOUGH_DATA = -5 | ||
13 | HEARTBEAT_E_TIMEOUT = -6 | ||
14 | HEARTBEAT_E_UNKNOWN_ERROR = -256 | ||
15 | |||
16 | heartbeat_error_t heartbeat_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, heartbeat_client_t * client) | ||
17 | heartbeat_error_t heartbeat_client_free(heartbeat_client_t client) | ||
18 | |||
19 | heartbeat_error_t heartbeat_send(heartbeat_client_t client, plist.plist_t plist) | ||
20 | heartbeat_error_t heartbeat_receive(heartbeat_client_t client, plist.plist_t * plist) | ||
21 | heartbeat_error_t heartbeat_receive_with_timeout(heartbeat_client_t client, plist.plist_t * plist, uint32_t timeout_ms) | ||
22 | |||
23 | cdef class HeartbeatError(BaseError): | ||
24 | def __init__(self, *args, **kwargs): | ||
25 | self._lookup_table = { | ||
26 | HEARTBEAT_E_SUCCESS: "Success", | ||
27 | HEARTBEAT_E_INVALID_ARG: "Invalid argument", | ||
28 | HEARTBEAT_E_PLIST_ERROR: "Property list error", | ||
29 | HEARTBEAT_E_MUX_ERROR: "MUX error", | ||
30 | HEARTBEAT_E_SSL_ERROR: "SSL Error", | ||
31 | HEARTBEAT_E_NOT_ENOUGH_DATA: 'Not enough data', | ||
32 | HEARTBEAT_E_TIMEOUT: 'Connection timeout', | ||
33 | HEARTBEAT_E_UNKNOWN_ERROR: "Unknown error" | ||
34 | } | ||
35 | BaseError.__init__(self, *args, **kwargs) | ||
36 | |||
37 | cdef class HeartbeatClient(PropertyListService): | ||
38 | __service_name__ = "com.apple.heartbeat" | ||
39 | cdef heartbeat_client_t _c_client | ||
40 | |||
41 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
42 | self.handle_error(heartbeat_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
43 | |||
44 | def __dealloc__(self): | ||
45 | cdef heartbeat_error_t err | ||
46 | if self._c_client is not NULL: | ||
47 | err = heartbeat_client_free(self._c_client) | ||
48 | self.handle_error(err) | ||
49 | |||
50 | cdef inline int16_t _send(self, plist.plist_t node): | ||
51 | return heartbeat_send(self._c_client, node) | ||
52 | |||
53 | cdef inline int16_t _receive(self, plist.plist_t* node): | ||
54 | return heartbeat_receive(self._c_client, node) | ||
55 | |||
56 | cdef inline int16_t _receive_with_timeout(self, plist.plist_t* node, int timeout_ms): | ||
57 | return heartbeat_receive_with_timeout(self._c_client, node, timeout_ms) | ||
58 | |||
59 | cdef inline BaseError _error(self, int16_t ret): | ||
60 | return HeartbeatError(ret) | ||
diff --git a/cython/house_arrest.pxi b/cython/house_arrest.pxi new file mode 100644 index 0000000..54eebc1 --- /dev/null +++ b/cython/house_arrest.pxi | |||
@@ -0,0 +1,84 @@ | |||
1 | cdef extern from "libimobiledevice/house_arrest.h": | ||
2 | cdef struct house_arrest_client_private: | ||
3 | pass | ||
4 | ctypedef house_arrest_client_private *house_arrest_client_t | ||
5 | |||
6 | ctypedef enum house_arrest_error_t: | ||
7 | HOUSE_ARREST_E_SUCCESS = 0 | ||
8 | HOUSE_ARREST_E_INVALID_ARG = -1 | ||
9 | HOUSE_ARREST_E_PLIST_ERROR = -2 | ||
10 | HOUSE_ARREST_E_CONN_FAILED = -3 | ||
11 | HOUSE_ARREST_E_INVALID_MODE = -4 | ||
12 | HOUSE_ARREST_E_UNKNOWN_ERROR = -256 | ||
13 | |||
14 | house_arrest_error_t house_arrest_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, house_arrest_client_t * client) | ||
15 | house_arrest_error_t house_arrest_client_free(house_arrest_client_t client) | ||
16 | |||
17 | house_arrest_error_t house_arrest_send_request(house_arrest_client_t client, plist.plist_t dict) | ||
18 | house_arrest_error_t house_arrest_send_command(house_arrest_client_t client, char *command, char *appid) | ||
19 | house_arrest_error_t house_arrest_get_result(house_arrest_client_t client, plist.plist_t *dict) | ||
20 | |||
21 | afc_error_t afc_client_new_from_house_arrest_client(house_arrest_client_t client, afc_client_t *afc_client) | ||
22 | |||
23 | cdef class HouseArrestError(BaseError): | ||
24 | def __init__(self, *args, **kwargs): | ||
25 | self._lookup_table = { | ||
26 | HOUSE_ARREST_E_SUCCESS: "Success", | ||
27 | HOUSE_ARREST_E_INVALID_ARG: "Invalid argument", | ||
28 | HOUSE_ARREST_E_PLIST_ERROR: "Property list error", | ||
29 | HOUSE_ARREST_E_CONN_FAILED: "Connection failed", | ||
30 | HOUSE_ARREST_E_INVALID_MODE: "Invalid mode", | ||
31 | HOUSE_ARREST_E_UNKNOWN_ERROR: "Unknown error" | ||
32 | } | ||
33 | BaseError.__init__(self, *args, **kwargs) | ||
34 | |||
35 | cdef class HouseArrestClient(PropertyListService): | ||
36 | __service_name__ = "com.apple.mobile.house_arrest" | ||
37 | cdef house_arrest_client_t _c_client | ||
38 | |||
39 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
40 | self.handle_error(house_arrest_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
41 | |||
42 | def __dealloc__(self): | ||
43 | cdef house_arrest_error_t err | ||
44 | if self._c_client is not NULL: | ||
45 | err = house_arrest_client_free(self._c_client) | ||
46 | self.handle_error(err) | ||
47 | |||
48 | cdef inline BaseError _error(self, int16_t ret): | ||
49 | return HouseArrestError(ret) | ||
50 | |||
51 | cpdef send_request(self, plist.Node message): | ||
52 | self.handle_error(house_arrest_send_request(self._c_client, message._c_node)) | ||
53 | |||
54 | cpdef send_command(self, bytes command, bytes appid): | ||
55 | self.handle_error(house_arrest_send_command(self._c_client, command, appid)) | ||
56 | |||
57 | cpdef plist.Node get_result(self): | ||
58 | cdef: | ||
59 | plist.plist_t c_node = NULL | ||
60 | house_arrest_error_t err | ||
61 | err = house_arrest_get_result(self._c_client, &c_node) | ||
62 | try: | ||
63 | self.handle_error(err) | ||
64 | return plist.plist_t_to_node(c_node) | ||
65 | except BaseError, e: | ||
66 | if c_node != NULL: | ||
67 | plist.plist_free(c_node) | ||
68 | raise | ||
69 | |||
70 | cpdef AfcClient to_afc_client(self): | ||
71 | cdef: | ||
72 | afc_client_t c_afc_client = NULL | ||
73 | AfcClient result | ||
74 | afc_error_t err | ||
75 | err = afc_client_new_from_house_arrest_client(self._c_client, &c_afc_client) | ||
76 | try: | ||
77 | result = AfcClient.__new__(AfcClient) | ||
78 | result._c_client = c_afc_client | ||
79 | result.handle_error(err) | ||
80 | return result | ||
81 | except BaseError, e: | ||
82 | if c_afc_client != NULL: | ||
83 | afc_client_free(c_afc_client); | ||
84 | raise | ||
diff --git a/cython/imobiledevice.pxd b/cython/imobiledevice.pxd new file mode 100644 index 0000000..238df68 --- /dev/null +++ b/cython/imobiledevice.pxd | |||
@@ -0,0 +1,110 @@ | |||
1 | #!python | ||
2 | #cython: language_level=3str | ||
3 | |||
4 | cimport plist | ||
5 | |||
6 | from libc.stdint cimport * | ||
7 | |||
8 | cdef extern from "pyerrors.h": | ||
9 | ctypedef class __builtin__.Exception [object PyBaseExceptionObject]: | ||
10 | pass | ||
11 | |||
12 | cdef class BaseError(Exception): | ||
13 | cdef dict _lookup_table | ||
14 | cdef int16_t _c_errcode | ||
15 | |||
16 | cdef class Base: | ||
17 | cdef inline int handle_error(self, int16_t ret) except -1 | ||
18 | cdef BaseError _error(self, int16_t ret) | ||
19 | |||
20 | cdef class iDeviceError(BaseError): pass | ||
21 | |||
22 | cdef extern from "libimobiledevice/libimobiledevice.h": | ||
23 | cdef struct idevice_private: | ||
24 | pass | ||
25 | ctypedef idevice_private* idevice_t | ||
26 | cdef struct idevice_connection_private: | ||
27 | pass | ||
28 | ctypedef idevice_connection_private* idevice_connection_t | ||
29 | cdef enum idevice_connection_type: | ||
30 | CONNECTION_USBMUXD = 1 | ||
31 | CONNECTION_NETWORK | ||
32 | cdef enum idevice_event_type: | ||
33 | IDEVICE_DEVICE_ADD = 1 | ||
34 | IDEVICE_DEVICE_REMOVE | ||
35 | IDEVICE_DEVICE_PAIRED | ||
36 | ctypedef struct idevice_event_t: | ||
37 | idevice_event_type event | ||
38 | char *udid | ||
39 | idevice_connection_type conn_type | ||
40 | ctypedef idevice_event_t* const_idevice_event_t "const idevice_event_t*" | ||
41 | |||
42 | cdef class iDeviceEvent: | ||
43 | cdef const_idevice_event_t _c_event | ||
44 | |||
45 | cdef class iDeviceConnection(Base): | ||
46 | cdef idevice_connection_t _c_connection | ||
47 | |||
48 | cpdef bytes receive_timeout(self, uint32_t max_len, unsigned int timeout) | ||
49 | cpdef bytes receive(self, max_len) | ||
50 | cpdef disconnect(self) | ||
51 | |||
52 | cdef class iDevice(Base): | ||
53 | cdef idevice_t _c_dev | ||
54 | |||
55 | cpdef iDeviceConnection connect(self, uint16_t port) | ||
56 | |||
57 | cdef class BaseService(Base): | ||
58 | pass | ||
59 | |||
60 | cdef class PropertyListService(BaseService): | ||
61 | cpdef send(self, plist.Node node) | ||
62 | cpdef object receive(self) | ||
63 | cpdef object receive_with_timeout(self, int timeout_ms) | ||
64 | cdef int16_t _send(self, plist.plist_t node) | ||
65 | cdef int16_t _receive(self, plist.plist_t* c_node) | ||
66 | cdef int16_t _receive_with_timeout(self, plist.plist_t* c_node, int timeout_ms) | ||
67 | |||
68 | cdef extern from "libimobiledevice/lockdown.h": | ||
69 | cdef struct lockdownd_client_private: | ||
70 | pass | ||
71 | ctypedef lockdownd_client_private *lockdownd_client_t | ||
72 | cdef struct lockdownd_pair_record: | ||
73 | char *device_certificate | ||
74 | char *host_certificate | ||
75 | char *host_id | ||
76 | char *root_certificate | ||
77 | ctypedef lockdownd_pair_record *lockdownd_pair_record_t | ||
78 | cdef struct lockdownd_service_descriptor: | ||
79 | uint16_t port | ||
80 | uint8_t ssl_enabled | ||
81 | ctypedef lockdownd_service_descriptor *lockdownd_service_descriptor_t | ||
82 | |||
83 | cdef class LockdownError(BaseError): pass | ||
84 | |||
85 | cdef class LockdownPairRecord: | ||
86 | cdef lockdownd_pair_record_t _c_record | ||
87 | |||
88 | cdef class LockdownServiceDescriptor(Base): | ||
89 | cdef lockdownd_service_descriptor_t _c_service_descriptor | ||
90 | |||
91 | cdef class LockdownClient(PropertyListService): | ||
92 | cdef lockdownd_client_t _c_client | ||
93 | cdef readonly iDevice device | ||
94 | |||
95 | cpdef bytes query_type(self) | ||
96 | cpdef plist.Node get_value(self, bytes domain=*, bytes key=*) | ||
97 | cpdef set_value(self, bytes domain, bytes key, object value) | ||
98 | cpdef remove_value(self, bytes domain, bytes key) | ||
99 | cpdef object start_service(self, object service) | ||
100 | cpdef object get_service_client(self, object service_class) | ||
101 | cpdef tuple start_session(self, bytes host_id) | ||
102 | cpdef stop_session(self, bytes session_id) | ||
103 | cpdef pair(self, object pair_record=*) | ||
104 | cpdef validate_pair(self, object pair_record=*) | ||
105 | cpdef unpair(self, object pair_record=*) | ||
106 | cpdef activate(self, plist.Node activation_record) | ||
107 | cpdef deactivate(self) | ||
108 | cpdef enter_recovery(self) | ||
109 | cpdef goodbye(self) | ||
110 | cpdef list get_sync_data_classes(self) | ||
diff --git a/cython/imobiledevice.pyx b/cython/imobiledevice.pyx new file mode 100644 index 0000000..8da2296 --- /dev/null +++ b/cython/imobiledevice.pyx | |||
@@ -0,0 +1,294 @@ | |||
1 | cdef class BaseError(Exception): | ||
2 | def __cinit__(self, int16_t errcode): | ||
3 | self._c_errcode = errcode | ||
4 | |||
5 | def __nonzero__(self): | ||
6 | return self._c_errcode != 0 | ||
7 | |||
8 | property message: | ||
9 | def __get__(self): | ||
10 | if self._c_errcode in self._lookup_table: | ||
11 | return self._lookup_table[self._c_errcode] | ||
12 | else: | ||
13 | return "Unknown error ({0})".format(self._c_errcode) | ||
14 | |||
15 | property code: | ||
16 | def __get__(self): | ||
17 | return self._c_errcode | ||
18 | |||
19 | def __str__(self): | ||
20 | return '%s (%s)' % (self.message, self.code) | ||
21 | |||
22 | def __repr__(self): | ||
23 | return self.__str__() | ||
24 | |||
25 | cdef class Base: | ||
26 | cdef inline int handle_error(self, int16_t ret) except -1: | ||
27 | if ret == 0: | ||
28 | return 0 | ||
29 | cdef BaseError err = self._error(ret) | ||
30 | raise err | ||
31 | |||
32 | cdef BaseError _error(self, int16_t ret): pass | ||
33 | |||
34 | cdef extern from "libimobiledevice/libimobiledevice.h": | ||
35 | ctypedef enum idevice_error_t: | ||
36 | IDEVICE_E_SUCCESS = 0 | ||
37 | IDEVICE_E_INVALID_ARG = -1 | ||
38 | IDEVICE_E_UNKNOWN_ERROR = -2 | ||
39 | IDEVICE_E_NO_DEVICE = -3 | ||
40 | IDEVICE_E_NOT_ENOUGH_DATA = -4 | ||
41 | IDEVICE_E_SSL_ERROR = -6 | ||
42 | IDEVICE_E_TIMEOUT = -7 | ||
43 | cdef enum idevice_options: | ||
44 | IDEVICE_LOOKUP_USBMUX = 1 << 1 | ||
45 | IDEVICE_LOOKUP_NETWORK = 1 << 2 | ||
46 | IDEVICE_LOOKUP_PREFER_NETWORK = 1 << 3 | ||
47 | ctypedef void (*idevice_event_cb_t) (const_idevice_event_t event, void *user_data) | ||
48 | cdef extern idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data) | ||
49 | cdef extern idevice_error_t idevice_event_unsubscribe() | ||
50 | idevice_error_t idevice_get_device_list(char ***devices, int *count) | ||
51 | idevice_error_t idevice_device_list_free(char **devices) | ||
52 | void idevice_set_debug_level(int level) | ||
53 | idevice_error_t idevice_new(idevice_t *device, char *udid) | ||
54 | idevice_error_t idevice_new_with_options(idevice_t *device, const char *udid, idevice_options options); | ||
55 | idevice_error_t idevice_free(idevice_t device) | ||
56 | idevice_error_t idevice_get_udid(idevice_t device, char** udid) | ||
57 | idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle) | ||
58 | idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection) | ||
59 | idevice_error_t idevice_disconnect(idevice_connection_t connection) | ||
60 | idevice_error_t idevice_connection_send(idevice_connection_t connection, char *data, uint32_t len, uint32_t *sent_bytes) | ||
61 | idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) | ||
62 | idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) | ||
63 | |||
64 | cdef class iDeviceError(BaseError): | ||
65 | def __init__(self, *args, **kwargs): | ||
66 | self._lookup_table = { | ||
67 | IDEVICE_E_SUCCESS: 'Success', | ||
68 | IDEVICE_E_INVALID_ARG: 'Invalid argument', | ||
69 | IDEVICE_E_UNKNOWN_ERROR: 'Unknown error', | ||
70 | IDEVICE_E_NO_DEVICE: 'No device', | ||
71 | IDEVICE_E_NOT_ENOUGH_DATA: 'Not enough data', | ||
72 | IDEVICE_E_SSL_ERROR: 'SSL Error', | ||
73 | IDEVICE_E_TIMEOUT: 'Connection timeout' | ||
74 | } | ||
75 | BaseError.__init__(self, *args, **kwargs) | ||
76 | |||
77 | def set_debug_level(int level): | ||
78 | idevice_set_debug_level(level) | ||
79 | |||
80 | cdef class iDeviceEvent: | ||
81 | def __init__(self, *args, **kwargs): | ||
82 | raise TypeError("iDeviceEvent cannot be instantiated") | ||
83 | |||
84 | def __str__(self): | ||
85 | return 'iDeviceEvent: %s (%s)' % (self.event == IDEVICE_DEVICE_ADD and 'Add' or 'Remove', self.udid) | ||
86 | |||
87 | property event: | ||
88 | def __get__(self): | ||
89 | return self._c_event.event | ||
90 | property udid: | ||
91 | def __get__(self): | ||
92 | return self._c_event.udid | ||
93 | property conn_type: | ||
94 | def __get__(self): | ||
95 | return self._c_event.conn_type | ||
96 | |||
97 | cdef void idevice_event_cb(const_idevice_event_t c_event, void *user_data) noexcept: | ||
98 | cdef iDeviceEvent event = iDeviceEvent.__new__(iDeviceEvent) | ||
99 | event._c_event = c_event | ||
100 | (<object>user_data)(event) | ||
101 | |||
102 | def event_subscribe(object callback): | ||
103 | cdef iDeviceError err = iDeviceError(idevice_event_subscribe(idevice_event_cb, <void*>callback)) | ||
104 | if err: raise err | ||
105 | |||
106 | def event_unsubscribe(): | ||
107 | cdef iDeviceError err = iDeviceError(idevice_event_unsubscribe()) | ||
108 | if err: raise err | ||
109 | |||
110 | def get_device_list(): | ||
111 | cdef: | ||
112 | char** devices = NULL | ||
113 | int count | ||
114 | list result | ||
115 | bytes device | ||
116 | iDeviceError err = iDeviceError(idevice_get_device_list(&devices, &count)) | ||
117 | |||
118 | if err: | ||
119 | if devices != NULL: | ||
120 | idevice_device_list_free(devices) | ||
121 | raise err | ||
122 | |||
123 | result = [] | ||
124 | for i from 0 <= i < count: | ||
125 | device = devices[i] | ||
126 | result.append(device) | ||
127 | |||
128 | err = iDeviceError(idevice_device_list_free(devices)) | ||
129 | if err: raise err | ||
130 | return result | ||
131 | |||
132 | cdef class iDeviceConnection(Base): | ||
133 | def __init__(self, *args, **kwargs): | ||
134 | raise TypeError("iDeviceConnection cannot be instantiated. Please use iDevice.connect()") | ||
135 | |||
136 | cpdef bytes receive_timeout(self, uint32_t max_len, unsigned int timeout): | ||
137 | cdef: | ||
138 | uint32_t bytes_received | ||
139 | char* c_data = <char *>malloc(max_len) | ||
140 | bytes result | ||
141 | |||
142 | try: | ||
143 | self.handle_error(idevice_connection_receive_timeout(self._c_connection, c_data, max_len, &bytes_received, timeout)) | ||
144 | result = c_data[:bytes_received] | ||
145 | return result | ||
146 | except BaseError, e: | ||
147 | raise | ||
148 | finally: | ||
149 | free(c_data) | ||
150 | |||
151 | cpdef bytes receive(self, max_len): | ||
152 | cdef: | ||
153 | uint32_t bytes_received | ||
154 | char* c_data = <char *>malloc(max_len) | ||
155 | bytes result | ||
156 | |||
157 | try: | ||
158 | self.handle_error(idevice_connection_receive(self._c_connection, c_data, max_len, &bytes_received)) | ||
159 | result = c_data[:bytes_received] | ||
160 | return result | ||
161 | except BaseError, e: | ||
162 | raise | ||
163 | finally: | ||
164 | free(c_data) | ||
165 | |||
166 | cpdef disconnect(self): | ||
167 | cdef idevice_error_t err | ||
168 | err = idevice_disconnect(self._c_connection) | ||
169 | self.handle_error(err) | ||
170 | |||
171 | cdef BaseError _error(self, int16_t ret): | ||
172 | return iDeviceError(ret) | ||
173 | |||
174 | from libc.stdlib cimport * | ||
175 | |||
176 | cdef class iDevice(Base): | ||
177 | def __cinit__(self, object udid=None, *args, **kwargs): | ||
178 | cdef char* c_udid = NULL | ||
179 | if isinstance(udid, (str, bytes)): | ||
180 | c_udid = <bytes>udid | ||
181 | elif udid is not None: | ||
182 | raise TypeError("iDevice's constructor takes a string or None as the udid argument") | ||
183 | self.handle_error(idevice_new(&self._c_dev, c_udid)) | ||
184 | |||
185 | def __dealloc__(self): | ||
186 | if self._c_dev is not NULL: | ||
187 | self.handle_error(idevice_free(self._c_dev)) | ||
188 | |||
189 | cdef BaseError _error(self, int16_t ret): | ||
190 | return iDeviceError(ret) | ||
191 | |||
192 | cpdef iDeviceConnection connect(self, uint16_t port): | ||
193 | cdef: | ||
194 | idevice_error_t err | ||
195 | idevice_connection_t c_conn = NULL | ||
196 | iDeviceConnection conn | ||
197 | err = idevice_connect(self._c_dev, port, &c_conn) | ||
198 | try: | ||
199 | self.handle_error(err) | ||
200 | |||
201 | conn = iDeviceConnection.__new__(iDeviceConnection) | ||
202 | conn._c_connection = c_conn | ||
203 | |||
204 | return conn | ||
205 | except Exception, e: | ||
206 | if c_conn != NULL: | ||
207 | idevice_disconnect(c_conn) | ||
208 | |||
209 | property udid: | ||
210 | def __get__(self): | ||
211 | cdef: | ||
212 | char* udid | ||
213 | idevice_error_t err | ||
214 | err = idevice_get_udid(self._c_dev, &udid) | ||
215 | try: | ||
216 | self.handle_error(err) | ||
217 | return udid | ||
218 | except Exception, e: | ||
219 | if udid != NULL: | ||
220 | free(udid) | ||
221 | property handle: | ||
222 | def __get__(self): | ||
223 | cdef uint32_t handle | ||
224 | self.handle_error(idevice_get_handle(self._c_dev, &handle)) | ||
225 | return handle | ||
226 | |||
227 | cdef extern from *: | ||
228 | ctypedef char* const_char_ptr "const char*" | ||
229 | |||
230 | cdef class BaseService(Base): | ||
231 | __service_name__ = None | ||
232 | |||
233 | cdef class PropertyListService(BaseService): | ||
234 | cpdef send(self, plist.Node node): | ||
235 | self.handle_error(self._send(node._c_node)) | ||
236 | |||
237 | cpdef object receive(self): | ||
238 | cdef: | ||
239 | plist.plist_t c_node = NULL | ||
240 | int16_t err | ||
241 | err = self._receive(&c_node) | ||
242 | try: | ||
243 | self.handle_error(err) | ||
244 | |||
245 | return plist.plist_t_to_node(c_node) | ||
246 | except BaseError, e: | ||
247 | if c_node != NULL: | ||
248 | plist.plist_free(c_node) | ||
249 | raise | ||
250 | |||
251 | cpdef object receive_with_timeout(self, int timeout_ms): | ||
252 | cdef: | ||
253 | plist.plist_t c_node = NULL | ||
254 | int16_t err | ||
255 | err = self._receive_with_timeout(&c_node, timeout_ms) | ||
256 | try: | ||
257 | self.handle_error(err) | ||
258 | |||
259 | return plist.plist_t_to_node(c_node) | ||
260 | except BaseError, e: | ||
261 | if c_node != NULL: | ||
262 | plist.plist_free(c_node) | ||
263 | raise | ||
264 | |||
265 | cdef int16_t _send(self, plist.plist_t node): | ||
266 | raise NotImplementedError("send is not implemented") | ||
267 | |||
268 | cdef int16_t _receive(self, plist.plist_t* c_node): | ||
269 | raise NotImplementedError("receive is not implemented") | ||
270 | |||
271 | cdef int16_t _receive_with_timeout(self, plist.plist_t* c_node, int timeout_ms): | ||
272 | raise NotImplementedError("receive_with_timeout is not implemented") | ||
273 | |||
274 | cdef class DeviceLinkService(PropertyListService): | ||
275 | pass | ||
276 | |||
277 | include "lockdown.pxi" | ||
278 | include "mobilesync.pxi" | ||
279 | include "notification_proxy.pxi" | ||
280 | include "sbservices.pxi" | ||
281 | include "mobilebackup.pxi" | ||
282 | include "mobilebackup2.pxi" | ||
283 | include "afc.pxi" | ||
284 | include "file_relay.pxi" | ||
285 | include "screenshotr.pxi" | ||
286 | include "installation_proxy.pxi" | ||
287 | include "mobile_image_mounter.pxi" | ||
288 | include "webinspector.pxi" | ||
289 | include "heartbeat.pxi" | ||
290 | include "diagnostics_relay.pxi" | ||
291 | include "misagent.pxi" | ||
292 | include "house_arrest.pxi" | ||
293 | include "restore.pxi" | ||
294 | include "debugserver.pxi" | ||
diff --git a/cython/installation_proxy.pxi b/cython/installation_proxy.pxi new file mode 100644 index 0000000..1d3e323 --- /dev/null +++ b/cython/installation_proxy.pxi | |||
@@ -0,0 +1,304 @@ | |||
1 | cdef extern from "libimobiledevice/installation_proxy.h": | ||
2 | cdef struct instproxy_client_private: | ||
3 | pass | ||
4 | ctypedef instproxy_client_private *instproxy_client_t | ||
5 | ctypedef void (*instproxy_status_cb_t) (plist.plist_t command, plist.plist_t status, void *user_data) | ||
6 | |||
7 | ctypedef enum instproxy_error_t: | ||
8 | INSTPROXY_E_SUCCESS = 0 | ||
9 | INSTPROXY_E_INVALID_ARG = -1 | ||
10 | INSTPROXY_E_PLIST_ERROR = -2 | ||
11 | INSTPROXY_E_CONN_FAILED = -3 | ||
12 | INSTPROXY_E_OP_IN_PROGRESS = -4 | ||
13 | INSTPROXY_E_OP_FAILED = -5 | ||
14 | INSTPROXY_E_UNKNOWN_ERROR = -256 | ||
15 | |||
16 | instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, instproxy_client_t *client) | ||
17 | instproxy_error_t instproxy_client_free(instproxy_client_t client) | ||
18 | instproxy_error_t instproxy_client_get_path_for_bundle_identifier(instproxy_client_t client, const char* bundle_id, char** path) | ||
19 | |||
20 | instproxy_error_t instproxy_browse(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result) | ||
21 | instproxy_error_t instproxy_install(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
22 | instproxy_error_t instproxy_upgrade(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
23 | instproxy_error_t instproxy_uninstall(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
24 | |||
25 | instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result) | ||
26 | instproxy_error_t instproxy_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
27 | instproxy_error_t instproxy_restore(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
28 | instproxy_error_t instproxy_remove_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
29 | |||
30 | cdef void instproxy_notify_cb(plist.plist_t command, plist.plist_t status, void *py_callback) noexcept: | ||
31 | (<object>py_callback)(plist.plist_t_to_node(command, False), plist.plist_t_to_node(status, False)) | ||
32 | |||
33 | cdef class InstallationProxyError(BaseError): | ||
34 | def __init__(self, *args, **kwargs): | ||
35 | self._lookup_table = { | ||
36 | INSTPROXY_E_SUCCESS: "Success", | ||
37 | INSTPROXY_E_INVALID_ARG: "Invalid argument", | ||
38 | INSTPROXY_E_PLIST_ERROR: "Property list error", | ||
39 | INSTPROXY_E_CONN_FAILED: "Connection failed", | ||
40 | INSTPROXY_E_OP_IN_PROGRESS: "Operation in progress", | ||
41 | INSTPROXY_E_OP_FAILED: "Operation failed", | ||
42 | INSTPROXY_E_UNKNOWN_ERROR: "Unknown error" | ||
43 | } | ||
44 | BaseError.__init__(self, *args, **kwargs) | ||
45 | |||
46 | cdef class InstallationProxyClient(PropertyListService): | ||
47 | __service_name__ = "com.apple.mobile.installation_proxy" | ||
48 | cdef instproxy_client_t _c_client | ||
49 | |||
50 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
51 | cdef: | ||
52 | iDevice dev = device | ||
53 | instproxy_error_t err | ||
54 | err = instproxy_client_new(dev._c_dev, descriptor._c_service_descriptor, &self._c_client) | ||
55 | self.handle_error(err) | ||
56 | |||
57 | def __dealloc__(self): | ||
58 | cdef instproxy_error_t err | ||
59 | if self._c_client is not NULL: | ||
60 | err = instproxy_client_free(self._c_client) | ||
61 | self.handle_error(err) | ||
62 | |||
63 | cpdef get_path_for_bundle_identifier(self, bytes bundle_id): | ||
64 | cdef: | ||
65 | char* c_bundle_id = bundle_id | ||
66 | char* c_path = NULL | ||
67 | bytes result | ||
68 | |||
69 | try: | ||
70 | self.handle_error(instproxy_client_get_path_for_bundle_identifier(self._c_client, c_bundle_id, &c_path)) | ||
71 | if c_path != NULL: | ||
72 | result = c_path | ||
73 | return result | ||
74 | else: | ||
75 | return None | ||
76 | except BaseError, e: | ||
77 | raise | ||
78 | finally: | ||
79 | free(c_path) | ||
80 | |||
81 | cpdef plist.Node browse(self, object client_options): | ||
82 | cdef: | ||
83 | plist.Node options | ||
84 | plist.plist_t c_options | ||
85 | plist.plist_t c_result = NULL | ||
86 | bint free_options = False | ||
87 | instproxy_error_t err | ||
88 | if isinstance(client_options, plist.Dict): | ||
89 | options = client_options | ||
90 | c_options = options._c_node | ||
91 | elif isinstance(client_options, dict): | ||
92 | c_options = plist.native_to_plist_t(client_options) | ||
93 | free_options = True | ||
94 | else: | ||
95 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
96 | err = instproxy_browse(self._c_client, c_options, &c_result) | ||
97 | |||
98 | try: | ||
99 | self.handle_error(err) | ||
100 | return plist.plist_t_to_node(c_result) | ||
101 | except Exception, e: | ||
102 | if c_result != NULL: | ||
103 | plist.plist_free(c_result) | ||
104 | raise | ||
105 | finally: | ||
106 | if free_options: | ||
107 | plist.plist_free(c_options) | ||
108 | |||
109 | cpdef install(self, bytes pkg_path, object client_options, object callback=None): | ||
110 | cdef: | ||
111 | plist.Node options | ||
112 | plist.plist_t c_options | ||
113 | bint free_options = False | ||
114 | instproxy_error_t err | ||
115 | if isinstance(client_options, plist.Dict): | ||
116 | options = client_options | ||
117 | c_options = options._c_node | ||
118 | elif isinstance(client_options, dict): | ||
119 | c_options = plist.native_to_plist_t(client_options) | ||
120 | free_options = True | ||
121 | else: | ||
122 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
123 | if callback is None: | ||
124 | err = instproxy_install(self._c_client, pkg_path, c_options, NULL, NULL) | ||
125 | else: | ||
126 | err = instproxy_install(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback) | ||
127 | |||
128 | try: | ||
129 | self.handle_error(err) | ||
130 | except Exception, e: | ||
131 | raise | ||
132 | finally: | ||
133 | if free_options: | ||
134 | plist.plist_free(c_options) | ||
135 | |||
136 | cpdef upgrade(self, bytes pkg_path, object client_options, object callback=None): | ||
137 | cdef: | ||
138 | plist.Node options | ||
139 | plist.plist_t c_options | ||
140 | bint free_options = False | ||
141 | instproxy_error_t err | ||
142 | if isinstance(client_options, plist.Dict): | ||
143 | options = client_options | ||
144 | c_options = options._c_node | ||
145 | elif isinstance(client_options, dict): | ||
146 | c_options = plist.native_to_plist_t(client_options) | ||
147 | free_options = True | ||
148 | else: | ||
149 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
150 | if callback is None: | ||
151 | err = instproxy_upgrade(self._c_client, pkg_path, c_options, NULL, NULL) | ||
152 | else: | ||
153 | err = instproxy_upgrade(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback) | ||
154 | try: | ||
155 | self.handle_error(err) | ||
156 | except Exception, e: | ||
157 | raise | ||
158 | finally: | ||
159 | if free_options: | ||
160 | plist.plist_free(c_options) | ||
161 | |||
162 | cpdef uninstall(self, bytes appid, object client_options, object callback=None): | ||
163 | cdef: | ||
164 | plist.Node options | ||
165 | plist.plist_t c_options | ||
166 | instproxy_error_t err | ||
167 | bint free_options = False | ||
168 | if isinstance(client_options, plist.Dict): | ||
169 | options = client_options | ||
170 | c_options = options._c_node | ||
171 | elif isinstance(client_options, dict): | ||
172 | c_options = plist.native_to_plist_t(client_options) | ||
173 | free_options = True | ||
174 | else: | ||
175 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
176 | |||
177 | if callback is None: | ||
178 | err = instproxy_uninstall(self._c_client, appid, c_options, NULL, NULL) | ||
179 | else: | ||
180 | err = instproxy_uninstall(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
181 | |||
182 | try: | ||
183 | self.handle_error(err) | ||
184 | except Exception, e: | ||
185 | raise | ||
186 | finally: | ||
187 | if free_options: | ||
188 | plist.plist_free(c_options) | ||
189 | |||
190 | cpdef plist.Node lookup_archives(self, object client_options): | ||
191 | cdef: | ||
192 | plist.Node options | ||
193 | plist.plist_t c_options | ||
194 | plist.plist_t c_node = NULL | ||
195 | instproxy_error_t err | ||
196 | bint free_options = False | ||
197 | if isinstance(client_options, plist.Dict): | ||
198 | options = client_options | ||
199 | c_options = options._c_node | ||
200 | elif isinstance(client_options, dict): | ||
201 | c_options = plist.native_to_plist_t(client_options) | ||
202 | free_options = True | ||
203 | else: | ||
204 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
205 | |||
206 | err = instproxy_lookup_archives(self._c_client, c_options, &c_node) | ||
207 | |||
208 | try: | ||
209 | self.handle_error(err) | ||
210 | return plist.plist_t_to_node(c_node) | ||
211 | except Exception, e: | ||
212 | if c_node != NULL: | ||
213 | plist.plist_free(c_node) | ||
214 | raise | ||
215 | finally: | ||
216 | if free_options: | ||
217 | plist.plist_free(c_options) | ||
218 | |||
219 | cpdef archive(self, bytes appid, object client_options, object callback=None): | ||
220 | cdef: | ||
221 | plist.Node options | ||
222 | plist.plist_t c_options | ||
223 | bint free_options = False | ||
224 | instproxy_error_t err | ||
225 | if isinstance(client_options, plist.Dict): | ||
226 | options = client_options | ||
227 | c_options = options._c_node | ||
228 | elif isinstance(client_options, dict): | ||
229 | c_options = plist.native_to_plist_t(client_options) | ||
230 | free_options = True | ||
231 | else: | ||
232 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
233 | |||
234 | if callback is None: | ||
235 | err = instproxy_archive(self._c_client, appid, c_options, NULL, NULL) | ||
236 | else: | ||
237 | err = instproxy_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
238 | |||
239 | try: | ||
240 | self.handle_error(err) | ||
241 | except Exception, e: | ||
242 | raise | ||
243 | finally: | ||
244 | if free_options: | ||
245 | plist.plist_free(c_options) | ||
246 | |||
247 | cpdef restore(self, bytes appid, object client_options, object callback=None): | ||
248 | cdef: | ||
249 | plist.Node options | ||
250 | plist.plist_t c_options | ||
251 | bint free_options = False | ||
252 | instproxy_error_t err | ||
253 | if isinstance(client_options, plist.Dict): | ||
254 | options = client_options | ||
255 | c_options = options._c_node | ||
256 | elif isinstance(client_options, dict): | ||
257 | c_options = plist.native_to_plist_t(client_options) | ||
258 | free_options = True | ||
259 | else: | ||
260 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
261 | |||
262 | if callback is None: | ||
263 | err = instproxy_restore(self._c_client, appid, c_options, NULL, NULL) | ||
264 | else: | ||
265 | err = instproxy_restore(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
266 | |||
267 | try: | ||
268 | self.handle_error(err) | ||
269 | except Exception, e: | ||
270 | raise | ||
271 | finally: | ||
272 | if free_options: | ||
273 | plist.plist_free(c_options) | ||
274 | |||
275 | cpdef remove_archive(self, bytes appid, object client_options, object callback=None): | ||
276 | cdef: | ||
277 | plist.Node options | ||
278 | plist.plist_t c_options | ||
279 | bint free_options = False | ||
280 | instproxy_error_t err | ||
281 | if isinstance(client_options, plist.Dict): | ||
282 | options = client_options | ||
283 | c_options = options._c_node | ||
284 | elif isinstance(client_options, dict): | ||
285 | c_options = plist.native_to_plist_t(client_options) | ||
286 | free_options = True | ||
287 | else: | ||
288 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
289 | |||
290 | if callback is None: | ||
291 | err = instproxy_remove_archive(self._c_client, appid, c_options, NULL, NULL) | ||
292 | else: | ||
293 | err = instproxy_remove_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
294 | |||
295 | try: | ||
296 | self.handle_error(err) | ||
297 | except Exception, e: | ||
298 | raise | ||
299 | finally: | ||
300 | if free_options: | ||
301 | plist.plist_free(c_options) | ||
302 | |||
303 | cdef inline BaseError _error(self, int16_t ret): | ||
304 | return InstallationProxyError(ret) | ||
diff --git a/cython/lockdown.pxi b/cython/lockdown.pxi new file mode 100644 index 0000000..25edb4c --- /dev/null +++ b/cython/lockdown.pxi | |||
@@ -0,0 +1,351 @@ | |||
1 | cdef extern from "libimobiledevice/lockdown.h": | ||
2 | ctypedef enum lockdownd_error_t: | ||
3 | LOCKDOWN_E_SUCCESS | ||
4 | LOCKDOWN_E_INVALID_ARG | ||
5 | LOCKDOWN_E_INVALID_CONF | ||
6 | LOCKDOWN_E_PLIST_ERROR | ||
7 | LOCKDOWN_E_PAIRING_FAILED | ||
8 | LOCKDOWN_E_SSL_ERROR | ||
9 | LOCKDOWN_E_DICT_ERROR | ||
10 | LOCKDOWN_E_RECEIVE_TIMEOUT | ||
11 | LOCKDOWN_E_SET_VALUE_PROHIBITED | ||
12 | LOCKDOWN_E_GET_VALUE_PROHIBITED | ||
13 | LOCKDOWN_E_MUX_ERROR | ||
14 | LOCKDOWN_E_NO_RUNNING_SESSION | ||
15 | LOCKDOWN_E_INVALID_RESPONSE | ||
16 | LOCKDOWN_E_MISSING_KEY | ||
17 | LOCKDOWN_E_MISSING_VALUE | ||
18 | LOCKDOWN_E_GET_PROHIBITED | ||
19 | LOCKDOWN_E_SET_PROHIBITED | ||
20 | LOCKDOWN_E_REMOVE_PROHIBITED | ||
21 | LOCKDOWN_E_IMMUTABLE_VALUE | ||
22 | LOCKDOWN_E_PASSWORD_PROTECTED | ||
23 | LOCKDOWN_E_USER_DENIED_PAIRING | ||
24 | LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING | ||
25 | LOCKDOWN_E_MISSING_HOST_ID | ||
26 | LOCKDOWN_E_INVALID_HOST_ID | ||
27 | LOCKDOWN_E_SESSION_ACTIVE | ||
28 | LOCKDOWN_E_SESSION_INACTIVE | ||
29 | LOCKDOWN_E_MISSING_SESSION_ID | ||
30 | LOCKDOWN_E_INVALID_SESSION_ID | ||
31 | LOCKDOWN_E_MISSING_SERVICE | ||
32 | LOCKDOWN_E_INVALID_SERVICE | ||
33 | LOCKDOWN_E_SERVICE_LIMIT | ||
34 | LOCKDOWN_E_MISSING_PAIR_RECORD | ||
35 | LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED | ||
36 | LOCKDOWN_E_INVALID_PAIR_RECORD | ||
37 | LOCKDOWN_E_INVALID_ACTIVATION_RECORD | ||
38 | LOCKDOWN_E_MISSING_ACTIVATION_RECORD | ||
39 | LOCKDOWN_E_SERVICE_PROHIBITED | ||
40 | LOCKDOWN_E_ESCROW_LOCKED | ||
41 | LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION | ||
42 | LOCKDOWN_E_FMIP_PROTECTED | ||
43 | LOCKDOWN_E_MC_PROTECTED | ||
44 | LOCKDOWN_E_MC_CHALLENGE_REQUIRED | ||
45 | LOCKDOWN_E_UNKNOWN_ERROR | ||
46 | |||
47 | lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, char *label) | ||
48 | lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, char *label) | ||
49 | lockdownd_error_t lockdownd_client_free(lockdownd_client_t client) | ||
50 | |||
51 | lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **tp) | ||
52 | lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t *value) | ||
53 | lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t value) | ||
54 | lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, char *domain, char *key) | ||
55 | lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, char *identifier, lockdownd_service_descriptor_t *service) | ||
56 | lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, char *host_id, char **session_id, int *ssl_enabled) | ||
57 | lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, char *session_id) | ||
58 | lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist.plist_t plist) | ||
59 | lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist.plist_t *plist) | ||
60 | lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record) | ||
61 | lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record) | ||
62 | lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record) | ||
63 | lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist.plist_t activation_record) | ||
64 | lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client) | ||
65 | lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client) | ||
66 | lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client) | ||
67 | lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count) | ||
68 | lockdownd_error_t lockdownd_data_classes_free(char **classes) | ||
69 | lockdownd_error_t lockdownd_service_descriptor_free(lockdownd_service_descriptor_t service) | ||
70 | |||
71 | cdef class LockdownError(BaseError): | ||
72 | def __init__(self, *args, **kwargs): | ||
73 | self._lookup_table = { | ||
74 | LOCKDOWN_E_SUCCESS: "Success", | ||
75 | LOCKDOWN_E_INVALID_ARG: "Invalid argument", | ||
76 | LOCKDOWN_E_INVALID_CONF: "Invalid configuration", | ||
77 | LOCKDOWN_E_PLIST_ERROR: "Property list error", | ||
78 | LOCKDOWN_E_PAIRING_FAILED: "Pairing failed", | ||
79 | LOCKDOWN_E_SSL_ERROR: "SSL error", | ||
80 | LOCKDOWN_E_DICT_ERROR: "Dictionary error", | ||
81 | LOCKDOWN_E_RECEIVE_TIMEOUT: "Receive timeout", | ||
82 | LOCKDOWN_E_MUX_ERROR: "Mux Protocol Error", | ||
83 | LOCKDOWN_E_NO_RUNNING_SESSION: "No running session", | ||
84 | LOCKDOWN_E_INVALID_RESPONSE: "Invalid response", | ||
85 | LOCKDOWN_E_MISSING_KEY: "Missing key", | ||
86 | LOCKDOWN_E_MISSING_VALUE: "Missing value", | ||
87 | LOCKDOWN_E_GET_PROHIBITED: "Get value prohibited", | ||
88 | LOCKDOWN_E_SET_PROHIBITED: "Set value prohibited", | ||
89 | LOCKDOWN_E_REMOVE_PROHIBITED: "Remove value prohibited", | ||
90 | LOCKDOWN_E_IMMUTABLE_VALUE: "Immutable value", | ||
91 | LOCKDOWN_E_PASSWORD_PROTECTED: "Password protected", | ||
92 | LOCKDOWN_E_USER_DENIED_PAIRING: "User denied pairing", | ||
93 | LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING: "Pairing dialog response pending", | ||
94 | LOCKDOWN_E_MISSING_HOST_ID: "Missing host ID", | ||
95 | LOCKDOWN_E_INVALID_HOST_ID: "Invalid host ID", | ||
96 | LOCKDOWN_E_SESSION_ACTIVE: "Session active", | ||
97 | LOCKDOWN_E_SESSION_INACTIVE: "Session inactive", | ||
98 | LOCKDOWN_E_MISSING_SESSION_ID: "Missing session ID", | ||
99 | LOCKDOWN_E_INVALID_SESSION_ID: "Invalid session ID", | ||
100 | LOCKDOWN_E_MISSING_SERVICE: "Missing service", | ||
101 | LOCKDOWN_E_INVALID_SERVICE: "Invalid service", | ||
102 | LOCKDOWN_E_SERVICE_LIMIT: "Service limit reached", | ||
103 | LOCKDOWN_E_MISSING_PAIR_RECORD: "Missing pair record", | ||
104 | LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED: "Saving pair record failed", | ||
105 | LOCKDOWN_E_INVALID_PAIR_RECORD: "Invalid pair record", | ||
106 | LOCKDOWN_E_INVALID_ACTIVATION_RECORD: "Invalid activation record", | ||
107 | LOCKDOWN_E_MISSING_ACTIVATION_RECORD: "Missing activation record", | ||
108 | LOCKDOWN_E_SERVICE_PROHIBITED: "Service prohibited", | ||
109 | LOCKDOWN_E_ESCROW_LOCKED: "Escrow locked", | ||
110 | LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION: "Pairing prohibited over this connection", | ||
111 | LOCKDOWN_E_FMIP_PROTECTED: "Find My iPhone/iPod/iPad protected", | ||
112 | LOCKDOWN_E_MC_PROTECTED: "MC protected", | ||
113 | LOCKDOWN_E_MC_CHALLENGE_REQUIRED: "MC challenge required", | ||
114 | LOCKDOWN_E_UNKNOWN_ERROR: "Unknown error" | ||
115 | } | ||
116 | BaseError.__init__(self, *args, **kwargs) | ||
117 | |||
118 | cdef class LockdownPairRecord: | ||
119 | #def __cinit__(self, bytes device_certificate, bytes host_certificate, bytes host_id, bytes root_certificate, *args, **kwargs): | ||
120 | property device_certificate: | ||
121 | def __get__(self): | ||
122 | cdef bytes result = self._c_record.device_certificate | ||
123 | return result | ||
124 | property host_certificate: | ||
125 | def __get__(self): | ||
126 | cdef bytes result = self._c_record.host_certificate | ||
127 | return result | ||
128 | property host_id: | ||
129 | def __get__(self): | ||
130 | cdef bytes result = self._c_record.host_id | ||
131 | return result | ||
132 | property root_certificate: | ||
133 | def __get__(self): | ||
134 | cdef bytes result = self._c_record.root_certificate | ||
135 | return result | ||
136 | |||
137 | cdef class LockdownServiceDescriptor(Base): | ||
138 | #def __cinit__(self, uint16_t port, uint8_t ssl_enabled, *args, **kwargs): | ||
139 | def __dealloc__(self): | ||
140 | cdef lockdownd_error_t err | ||
141 | if self._c_service_descriptor is not NULL: | ||
142 | err = lockdownd_service_descriptor_free(self._c_service_descriptor) | ||
143 | self._c_service_descriptor = NULL | ||
144 | self.handle_error(err) | ||
145 | property port: | ||
146 | def __get__(self): | ||
147 | return self._c_service_descriptor.port | ||
148 | property ssl_enabled: | ||
149 | def __get__(self): | ||
150 | return self._c_service_descriptor.ssl_enabled | ||
151 | |||
152 | cdef class LockdownClient(PropertyListService): | ||
153 | def __cinit__(self, iDevice device not None, bytes label=b'', bint handshake=True, *args, **kwargs): | ||
154 | cdef: | ||
155 | lockdownd_error_t err | ||
156 | char* c_label = NULL | ||
157 | if label: | ||
158 | c_label = label | ||
159 | if handshake: | ||
160 | err = lockdownd_client_new_with_handshake(device._c_dev, &self._c_client, c_label) | ||
161 | else: | ||
162 | err = lockdownd_client_new(device._c_dev, &self._c_client, c_label) | ||
163 | self.handle_error(err) | ||
164 | |||
165 | self.device = device | ||
166 | |||
167 | def __dealloc__(self): | ||
168 | cdef lockdownd_error_t err | ||
169 | if self._c_client is not NULL: | ||
170 | err = lockdownd_client_free(self._c_client) | ||
171 | self.handle_error(err) | ||
172 | |||
173 | cpdef bytes query_type(self): | ||
174 | cdef: | ||
175 | lockdownd_error_t err | ||
176 | char* c_type = NULL | ||
177 | bytes result | ||
178 | err = lockdownd_query_type(self._c_client, &c_type) | ||
179 | try: | ||
180 | self.handle_error(err) | ||
181 | result = c_type | ||
182 | |||
183 | return result | ||
184 | except BaseError, e: | ||
185 | raise | ||
186 | finally: | ||
187 | if c_type != NULL: | ||
188 | free(c_type) | ||
189 | |||
190 | cpdef plist.Node get_value(self, bytes domain=None, bytes key=None): | ||
191 | cdef: | ||
192 | lockdownd_error_t err | ||
193 | plist.plist_t c_node = NULL | ||
194 | char* c_domain = NULL | ||
195 | char* c_key = NULL | ||
196 | if domain is not None: | ||
197 | c_domain = domain | ||
198 | if key is not None: | ||
199 | c_key = key | ||
200 | |||
201 | err = lockdownd_get_value(self._c_client, c_domain, c_key, &c_node) | ||
202 | |||
203 | try: | ||
204 | self.handle_error(err) | ||
205 | |||
206 | return plist.plist_t_to_node(c_node) | ||
207 | except BaseError, e: | ||
208 | if c_node != NULL: | ||
209 | plist.plist_free(c_node) | ||
210 | raise | ||
211 | |||
212 | cpdef set_value(self, bytes domain, bytes key, object value): | ||
213 | cdef: | ||
214 | plist.plist_t c_node = NULL | ||
215 | char* c_domain = NULL | ||
216 | char* c_key = NULL | ||
217 | |||
218 | c_node = plist.native_to_plist_t(value) | ||
219 | if domain is not None: | ||
220 | c_domain = domain | ||
221 | if key is not None: | ||
222 | c_key = key | ||
223 | try: | ||
224 | self.handle_error(lockdownd_set_value(self._c_client, c_domain, c_key, c_node)) | ||
225 | except BaseError, e: | ||
226 | raise | ||
227 | finally: | ||
228 | if c_node != NULL: | ||
229 | c_node = NULL | ||
230 | |||
231 | cpdef remove_value(self, bytes domain, bytes key): | ||
232 | self.handle_error(lockdownd_remove_value(self._c_client, domain, key)) | ||
233 | |||
234 | cpdef object start_service(self, object service): | ||
235 | cdef: | ||
236 | char* c_service_name = NULL | ||
237 | lockdownd_service_descriptor_t c_descriptor = NULL | ||
238 | LockdownServiceDescriptor result | ||
239 | |||
240 | if issubclass(service, BaseService) and \ | ||
241 | service.__service_name__ is not None \ | ||
242 | and isinstance(service.__service_name__, (str, bytes)): | ||
243 | c_service_name_str = service.__service_name__.encode('utf-8') | ||
244 | elif isinstance(service, (str, bytes)): | ||
245 | c_service_name_str = service.encode('utf-8') | ||
246 | else: | ||
247 | raise TypeError("LockdownClient.start_service() takes a BaseService or string as its first argument") | ||
248 | c_service_name = c_service_name_str | ||
249 | |||
250 | try: | ||
251 | self.handle_error(lockdownd_start_service(self._c_client, c_service_name, &c_descriptor)) | ||
252 | |||
253 | result = LockdownServiceDescriptor.__new__(LockdownServiceDescriptor) | ||
254 | result._c_service_descriptor = c_descriptor | ||
255 | |||
256 | return result | ||
257 | except BaseError, e: | ||
258 | raise | ||
259 | |||
260 | cpdef object get_service_client(self, object service_class): | ||
261 | cdef: | ||
262 | LockdownServiceDescriptor descriptor | ||
263 | |||
264 | if not hasattr(service_class, '__service_name__') and \ | ||
265 | not service_class.__service_name__ is not None \ | ||
266 | and not isinstance(service_class.__service_name__, (str, bytes)): | ||
267 | raise TypeError("LockdownClient.get_service_client() takes a BaseService as its first argument") | ||
268 | |||
269 | descriptor = self.start_service(service_class) | ||
270 | return service_class(self.device, descriptor) | ||
271 | |||
272 | cpdef tuple start_session(self, bytes host_id): | ||
273 | cdef: | ||
274 | lockdownd_error_t err | ||
275 | char* c_session_id = NULL | ||
276 | bint ssl_enabled | ||
277 | bytes session_id | ||
278 | err = lockdownd_start_session(self._c_client, host_id, &c_session_id, <int *>&ssl_enabled) | ||
279 | try: | ||
280 | self.handle_error(err) | ||
281 | |||
282 | session_id = c_session_id | ||
283 | return (session_id, ssl_enabled) | ||
284 | except BaseError, e: | ||
285 | raise | ||
286 | finally: | ||
287 | if c_session_id != NULL: | ||
288 | free(c_session_id) | ||
289 | |||
290 | cpdef stop_session(self, bytes session_id): | ||
291 | self.handle_error(lockdownd_stop_session(self._c_client, session_id)) | ||
292 | |||
293 | cpdef pair(self, object pair_record=None): | ||
294 | cdef lockdownd_pair_record_t c_pair_record = NULL | ||
295 | if pair_record is not None: | ||
296 | c_pair_record = (<LockdownPairRecord>pair_record)._c_record | ||
297 | self.handle_error(lockdownd_pair(self._c_client, c_pair_record)) | ||
298 | |||
299 | cpdef validate_pair(self, object pair_record=None): | ||
300 | cdef lockdownd_pair_record_t c_pair_record = NULL | ||
301 | if pair_record is not None: | ||
302 | c_pair_record = (<LockdownPairRecord>pair_record)._c_record | ||
303 | self.handle_error(lockdownd_validate_pair(self._c_client, c_pair_record)) | ||
304 | |||
305 | cpdef unpair(self, object pair_record=None): | ||
306 | cdef lockdownd_pair_record_t c_pair_record = NULL | ||
307 | if pair_record is not None: | ||
308 | c_pair_record = (<LockdownPairRecord>pair_record)._c_record | ||
309 | self.handle_error(lockdownd_unpair(self._c_client, c_pair_record)) | ||
310 | |||
311 | cpdef activate(self, plist.Node activation_record): | ||
312 | self.handle_error(lockdownd_activate(self._c_client, activation_record._c_node)) | ||
313 | |||
314 | cpdef deactivate(self): | ||
315 | self.handle_error(lockdownd_deactivate(self._c_client)) | ||
316 | |||
317 | cpdef enter_recovery(self): | ||
318 | self.handle_error(lockdownd_enter_recovery(self._c_client)) | ||
319 | |||
320 | cpdef goodbye(self): | ||
321 | self.handle_error(lockdownd_goodbye(self._c_client)) | ||
322 | |||
323 | cpdef list get_sync_data_classes(self): | ||
324 | cdef: | ||
325 | char **classes = NULL | ||
326 | int count = 0 | ||
327 | list result = [] | ||
328 | bytes data_class | ||
329 | |||
330 | try: | ||
331 | self.handle_error(lockdownd_get_sync_data_classes(self._c_client, &classes, &count)) | ||
332 | |||
333 | for i from 0 <= i < count: | ||
334 | data_class = classes[i] | ||
335 | result.append(data_class) | ||
336 | |||
337 | return result | ||
338 | except Exception, e: | ||
339 | raise | ||
340 | finally: | ||
341 | if classes != NULL: | ||
342 | lockdownd_data_classes_free(classes) | ||
343 | |||
344 | cdef inline int16_t _send(self, plist.plist_t node): | ||
345 | return lockdownd_send(self._c_client, node) | ||
346 | |||
347 | cdef inline int16_t _receive(self, plist.plist_t* node): | ||
348 | return lockdownd_receive(self._c_client, node) | ||
349 | |||
350 | cdef inline BaseError _error(self, int16_t ret): | ||
351 | return LockdownError(ret) | ||
diff --git a/cython/misagent.pxi b/cython/misagent.pxi new file mode 100644 index 0000000..1fee4b9 --- /dev/null +++ b/cython/misagent.pxi | |||
@@ -0,0 +1,74 @@ | |||
1 | cdef extern from "libimobiledevice/misagent.h": | ||
2 | cdef struct misagent_client_private: | ||
3 | pass | ||
4 | ctypedef misagent_client_private *misagent_client_t | ||
5 | |||
6 | ctypedef enum misagent_error_t: | ||
7 | MISAGENT_E_SUCCESS = 0 | ||
8 | MISAGENT_E_INVALID_ARG = -1 | ||
9 | MISAGENT_E_PLIST_ERROR = -2 | ||
10 | MISAGENT_E_CONN_FAILED = -3 | ||
11 | MISAGENT_E_REQUEST_FAILED = -4 | ||
12 | MISAGENT_E_UNKNOWN_ERROR = -256 | ||
13 | |||
14 | misagent_error_t misagent_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, misagent_client_t * client) | ||
15 | misagent_error_t misagent_client_free(misagent_client_t client) | ||
16 | |||
17 | misagent_error_t misagent_install(misagent_client_t client, plist.plist_t profile) | ||
18 | misagent_error_t misagent_copy(misagent_client_t client, plist.plist_t* profiles) | ||
19 | misagent_error_t misagent_remove(misagent_client_t client, char* profileID) | ||
20 | int misagent_get_status_code(misagent_client_t client) | ||
21 | |||
22 | cdef class MisagentError(BaseError): | ||
23 | def __init__(self, *args, **kwargs): | ||
24 | self._lookup_table = { | ||
25 | MISAGENT_E_SUCCESS: "Success", | ||
26 | MISAGENT_E_INVALID_ARG: "Invalid argument", | ||
27 | MISAGENT_E_PLIST_ERROR: "Property list error", | ||
28 | MISAGENT_E_CONN_FAILED: "Connection failed", | ||
29 | MISAGENT_E_REQUEST_FAILED: "Request failed", | ||
30 | MISAGENT_E_UNKNOWN_ERROR: "Unknown error" | ||
31 | } | ||
32 | BaseError.__init__(self, *args, **kwargs) | ||
33 | |||
34 | cdef class MisagentClient(PropertyListService): | ||
35 | __service_name__ = "com.apple.misagent" | ||
36 | cdef misagent_client_t _c_client | ||
37 | |||
38 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
39 | self.handle_error(misagent_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
40 | |||
41 | def __dealloc__(self): | ||
42 | cdef misagent_error_t err | ||
43 | if self._c_client is not NULL: | ||
44 | err = misagent_client_free(self._c_client) | ||
45 | self.handle_error(err) | ||
46 | |||
47 | cdef inline BaseError _error(self, int16_t ret): | ||
48 | return MisagentError(ret) | ||
49 | |||
50 | cpdef install(self, plist.Node profile): | ||
51 | cdef misagent_error_t err | ||
52 | err = misagent_install(self._c_client, profile._c_node) | ||
53 | self.handle_error(err) | ||
54 | |||
55 | cpdef plist.Node copy(self): | ||
56 | cdef: | ||
57 | plist.plist_t c_node = NULL | ||
58 | misagent_error_t err | ||
59 | err = misagent_copy(self._c_client, &c_node) | ||
60 | try: | ||
61 | self.handle_error(err) | ||
62 | return plist.plist_t_to_node(c_node) | ||
63 | except BaseError, e: | ||
64 | if c_node != NULL: | ||
65 | plist.plist_free(c_node) | ||
66 | raise | ||
67 | |||
68 | cpdef remove(self, bytes profile_id): | ||
69 | cdef misagent_error_t err | ||
70 | err = misagent_remove(self._c_client, profile_id) | ||
71 | self.handle_error(err) | ||
72 | |||
73 | cpdef int get_status_code(self): | ||
74 | return misagent_get_status_code(self._c_client) | ||
diff --git a/cython/mobile_image_mounter.pxi b/cython/mobile_image_mounter.pxi new file mode 100644 index 0000000..d9d40d5 --- /dev/null +++ b/cython/mobile_image_mounter.pxi | |||
@@ -0,0 +1,115 @@ | |||
1 | cdef extern from "libimobiledevice/mobile_image_mounter.h": | ||
2 | cdef struct mobile_image_mounter_client_private: | ||
3 | pass | ||
4 | ctypedef mobile_image_mounter_client_private *mobile_image_mounter_client_t | ||
5 | |||
6 | ctypedef enum mobile_image_mounter_error_t: | ||
7 | MOBILE_IMAGE_MOUNTER_E_SUCCESS = 0 | ||
8 | MOBILE_IMAGE_MOUNTER_E_INVALID_ARG = -1 | ||
9 | MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR = -2 | ||
10 | MOBILE_IMAGE_MOUNTER_E_CONN_FAILED = -3 | ||
11 | MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR = -256 | ||
12 | |||
13 | mobile_image_mounter_error_t mobile_image_mounter_new(idevice_t device, lockdownd_service_descriptor_t descriptor, mobile_image_mounter_client_t *client) | ||
14 | mobile_image_mounter_error_t mobile_image_mounter_free(mobile_image_mounter_client_t client) | ||
15 | mobile_image_mounter_error_t mobile_image_mounter_lookup_image(mobile_image_mounter_client_t client, char *image_type, plist.plist_t *result) | ||
16 | mobile_image_mounter_error_t mobile_image_mounter_mount_image_with_options(mobile_image_mounter_client_t client, char *image_path, const unsigned char *signature, unsigned int signature_length, char *image_type, plist.plist_t options, plist.plist_t *result) | ||
17 | mobile_image_mounter_error_t mobile_image_mounter_mount_image(mobile_image_mounter_client_t client, char *image_path, const unsigned char *signature, unsigned int signature_length, char *image_type, plist.plist_t *result) | ||
18 | mobile_image_mounter_error_t mobile_image_mounter_unmount_image(mobile_image_mounter_client_t client, const char *mount_path); | ||
19 | mobile_image_mounter_error_t mobile_image_mounter_hangup(mobile_image_mounter_client_t client) | ||
20 | |||
21 | cdef class MobileImageMounterError(BaseError): | ||
22 | def __init__(self, *args, **kwargs): | ||
23 | self._lookup_table = { | ||
24 | MOBILE_IMAGE_MOUNTER_E_SUCCESS: "Success", | ||
25 | MOBILE_IMAGE_MOUNTER_E_INVALID_ARG: "Invalid argument", | ||
26 | MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR: "Property list error", | ||
27 | MOBILE_IMAGE_MOUNTER_E_CONN_FAILED: "Connection failed", | ||
28 | MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR: "Unknown error" | ||
29 | } | ||
30 | BaseError.__init__(self, *args, **kwargs) | ||
31 | |||
32 | cdef class MobileImageMounterClient(PropertyListService): | ||
33 | __service_name__ = "com.apple.mobile.mobile_image_mounter" | ||
34 | cdef mobile_image_mounter_client_t _c_client | ||
35 | |||
36 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
37 | self.handle_error(mobile_image_mounter_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
38 | |||
39 | def __dealloc__(self): | ||
40 | cdef mobile_image_mounter_error_t err | ||
41 | if self._c_client is not NULL: | ||
42 | err = mobile_image_mounter_free(self._c_client) | ||
43 | self.handle_error(err) | ||
44 | |||
45 | cdef inline BaseError _error(self, int16_t ret): | ||
46 | return MobileImageMounterError(ret) | ||
47 | |||
48 | cpdef plist.Node lookup_image(self, bytes image_type): | ||
49 | cdef: | ||
50 | plist.plist_t c_node = NULL | ||
51 | mobile_image_mounter_error_t err | ||
52 | err = mobile_image_mounter_lookup_image(self._c_client, image_type, &c_node) | ||
53 | |||
54 | try: | ||
55 | self.handle_error(err) | ||
56 | |||
57 | return plist.plist_t_to_node(c_node) | ||
58 | except Exception, e: | ||
59 | if c_node != NULL: | ||
60 | plist.plist_free(c_node) | ||
61 | |||
62 | cpdef plist.Node mount_image_with_options(self, bytes image_path, bytes signature, bytes image_type, object options): | ||
63 | cdef: | ||
64 | plist.Node n_options | ||
65 | plist.plist_t c_options | ||
66 | plist.plist_t c_result = NULL | ||
67 | bint free_options = False | ||
68 | plist.plist_t c_node = NULL | ||
69 | mobile_image_mounter_error_t err | ||
70 | if isinstance(options, plist.Dict): | ||
71 | n_options = options | ||
72 | c_options = n_options._c_node | ||
73 | elif isinstance(options, dict): | ||
74 | c_options = plist.native_to_plist_t(options) | ||
75 | free_options = True | ||
76 | else: | ||
77 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
78 | err = mobile_image_mounter_mount_image_with_options(self._c_client, image_path, signature, len(signature), | ||
79 | image_type, c_options, &c_node) | ||
80 | if free_options: | ||
81 | plist.plist_free(c_options) | ||
82 | try: | ||
83 | self.handle_error(err) | ||
84 | |||
85 | return plist.plist_t_to_node(c_node) | ||
86 | except Exception, e: | ||
87 | if c_node != NULL: | ||
88 | plist.plist_free(c_node) | ||
89 | |||
90 | cpdef plist.Node mount_image(self, bytes image_path, bytes signature, bytes image_type): | ||
91 | cdef: | ||
92 | plist.plist_t c_node = NULL | ||
93 | mobile_image_mounter_error_t err | ||
94 | err = mobile_image_mounter_mount_image(self._c_client, image_path, signature, len(signature), | ||
95 | image_type, &c_node) | ||
96 | |||
97 | try: | ||
98 | self.handle_error(err) | ||
99 | |||
100 | return plist.plist_t_to_node(c_node) | ||
101 | except Exception, e: | ||
102 | if c_node != NULL: | ||
103 | plist.plist_free(c_node) | ||
104 | |||
105 | cpdef unmount_image(self, bytes mount_path): | ||
106 | cdef: | ||
107 | mobile_image_mounter_error_t err | ||
108 | err = mobile_image_mounter_unmount_image(self._c_client, mount_path) | ||
109 | |||
110 | self.handle_error(err) | ||
111 | |||
112 | cpdef hangup(self): | ||
113 | cdef mobile_image_mounter_error_t err | ||
114 | err = mobile_image_mounter_hangup(self._c_client) | ||
115 | self.handle_error(err) | ||
diff --git a/cython/mobilebackup.pxi b/cython/mobilebackup.pxi new file mode 100644 index 0000000..f2d58d4 --- /dev/null +++ b/cython/mobilebackup.pxi | |||
@@ -0,0 +1,110 @@ | |||
1 | cdef extern from "libimobiledevice/mobilebackup.h": | ||
2 | cdef struct mobilebackup_client_private: | ||
3 | pass | ||
4 | ctypedef mobilebackup_client_private *mobilebackup_client_t | ||
5 | |||
6 | ctypedef enum mobilebackup_error_t: | ||
7 | MOBILEBACKUP_E_SUCCESS = 0 | ||
8 | MOBILEBACKUP_E_INVALID_ARG = -1 | ||
9 | MOBILEBACKUP_E_PLIST_ERROR = -2 | ||
10 | MOBILEBACKUP_E_MUX_ERROR = -3 | ||
11 | MOBILEBACKUP_E_SSL_ERROR = -4 | ||
12 | MOBILEBACKUP_E_RECEIVE_TIMEOUT = -5 | ||
13 | MOBILEBACKUP_E_BAD_VERSION = -6 | ||
14 | MOBILEBACKUP_E_REPLY_NOT_OK = -7 | ||
15 | MOBILEBACKUP_E_UNKNOWN_ERROR = -256 | ||
16 | |||
17 | ctypedef enum mobilebackup_flags_t: | ||
18 | MB_RESTORE_NOTIFY_SPRINGBOARD = (1 << 0) | ||
19 | MB_RESTORE_PRESERVE_SETTINGS = (1 << 1) | ||
20 | MB_RESTORE_PRESERVE_CAMERA_ROLL = (1 << 2) | ||
21 | |||
22 | mobilebackup_error_t mobilebackup_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, mobilebackup_client_t * client) | ||
23 | mobilebackup_error_t mobilebackup_client_free(mobilebackup_client_t client) | ||
24 | mobilebackup_error_t mobilebackup_receive(mobilebackup_client_t client, plist.plist_t *plist) | ||
25 | mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist.plist_t plist) | ||
26 | mobilebackup_error_t mobilebackup_request_backup(mobilebackup_client_t client, plist.plist_t backup_manifest, char *base_path, char *proto_version) | ||
27 | mobilebackup_error_t mobilebackup_send_backup_file_received(mobilebackup_client_t client) | ||
28 | mobilebackup_error_t mobilebackup_request_restore(mobilebackup_client_t client, plist.plist_t backup_manifest, mobilebackup_flags_t flags, char *proto_version) | ||
29 | mobilebackup_error_t mobilebackup_receive_restore_file_received(mobilebackup_client_t client, plist.plist_t *result) | ||
30 | mobilebackup_error_t mobilebackup_receive_restore_application_received(mobilebackup_client_t client, plist.plist_t *result) | ||
31 | mobilebackup_error_t mobilebackup_send_restore_complete(mobilebackup_client_t client) | ||
32 | mobilebackup_error_t mobilebackup_send_error(mobilebackup_client_t client, char *reason) | ||
33 | |||
34 | cdef class MobileBackupError(BaseError): | ||
35 | def __init__(self, *args, **kwargs): | ||
36 | self._lookup_table = { | ||
37 | MOBILEBACKUP_E_SUCCESS: "Success", | ||
38 | MOBILEBACKUP_E_INVALID_ARG: "Invalid argument", | ||
39 | MOBILEBACKUP_E_PLIST_ERROR: "Property list error", | ||
40 | MOBILEBACKUP_E_MUX_ERROR: "MUX error", | ||
41 | MOBILEBACKUP_E_SSL_ERROR: "SSL error", | ||
42 | MOBILEBACKUP_E_RECEIVE_TIMEOUT: "Receive timeout", | ||
43 | MOBILEBACKUP_E_BAD_VERSION: "Bad version", | ||
44 | MOBILEBACKUP_E_REPLY_NOT_OK: "Reply not OK", | ||
45 | MOBILEBACKUP_E_UNKNOWN_ERROR: "Unknown error" | ||
46 | } | ||
47 | BaseError.__init__(self, *args, **kwargs) | ||
48 | |||
49 | cdef class MobileBackupClient(PropertyListService): | ||
50 | __service_name__ = "com.apple.mobilebackup" | ||
51 | cdef mobilebackup_client_t _c_client | ||
52 | |||
53 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
54 | self.handle_error(mobilebackup_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
55 | |||
56 | def __dealloc__(self): | ||
57 | cdef mobilebackup_error_t err | ||
58 | if self._c_client is not NULL: | ||
59 | err = mobilebackup_client_free(self._c_client) | ||
60 | self.handle_error(err) | ||
61 | |||
62 | cdef inline BaseError _error(self, int16_t ret): | ||
63 | return MobileBackupError(ret) | ||
64 | |||
65 | cdef inline int16_t _send(self, plist.plist_t node): | ||
66 | return mobilebackup_send(self._c_client, node) | ||
67 | |||
68 | cdef inline int16_t _receive(self, plist.plist_t* node): | ||
69 | return mobilebackup_receive(self._c_client, node) | ||
70 | |||
71 | cdef request_backup(self, plist.Node backup_manifest, bytes base_path, bytes proto_version): | ||
72 | self.handle_error(mobilebackup_request_backup(self._c_client, backup_manifest._c_node, base_path, proto_version)) | ||
73 | |||
74 | cdef send_backup_file_received(self): | ||
75 | self.handle_error(mobilebackup_send_backup_file_received(self._c_client)) | ||
76 | |||
77 | cdef request_restore(self, plist.Node backup_manifest, int flags, proto_version): | ||
78 | self.handle_error(mobilebackup_request_restore(self._c_client, backup_manifest._c_node, <mobilebackup_flags_t>flags, proto_version)) | ||
79 | |||
80 | cpdef plist.Node receive_restore_file_received(self): | ||
81 | cdef: | ||
82 | plist.plist_t c_node = NULL | ||
83 | mobilebackup_error_t err | ||
84 | err = mobilebackup_receive_restore_file_received(self._c_client, &c_node) | ||
85 | try: | ||
86 | self.handle_error(err) | ||
87 | return plist.plist_t_to_node(c_node) | ||
88 | except BaseError, e: | ||
89 | if c_node != NULL: | ||
90 | plist.plist_free(c_node) | ||
91 | raise | ||
92 | |||
93 | cpdef plist.Node receive_restore_application_received(self): | ||
94 | cdef: | ||
95 | plist.plist_t c_node = NULL | ||
96 | mobilebackup_error_t err | ||
97 | err = mobilebackup_receive_restore_application_received(self._c_client, &c_node) | ||
98 | try: | ||
99 | self.handle_error(err) | ||
100 | return plist.plist_t_to_node(c_node) | ||
101 | except BaseError, e: | ||
102 | if c_node != NULL: | ||
103 | plist.plist_free(c_node) | ||
104 | raise | ||
105 | |||
106 | cdef send_restore_complete(self): | ||
107 | self.handle_error(mobilebackup_send_restore_complete(self._c_client)) | ||
108 | |||
109 | cdef send_error(self, bytes reason): | ||
110 | self.handle_error(mobilebackup_send_error(self._c_client, reason)) | ||
diff --git a/cython/mobilebackup2.pxi b/cython/mobilebackup2.pxi new file mode 100644 index 0000000..4b47e5b --- /dev/null +++ b/cython/mobilebackup2.pxi | |||
@@ -0,0 +1,123 @@ | |||
1 | cdef extern from "libimobiledevice/mobilebackup2.h": | ||
2 | cdef struct mobilebackup2_client_private: | ||
3 | pass | ||
4 | ctypedef mobilebackup2_client_private *mobilebackup2_client_t | ||
5 | |||
6 | ctypedef enum mobilebackup2_error_t: | ||
7 | MOBILEBACKUP2_E_SUCCESS = 0 | ||
8 | MOBILEBACKUP2_E_INVALID_ARG = -1 | ||
9 | MOBILEBACKUP2_E_PLIST_ERROR = -2 | ||
10 | MOBILEBACKUP2_E_MUX_ERROR = -3 | ||
11 | MOBILEBACKUP2_E_SSL_ERROR = -4 | ||
12 | MOBILEBACKUP2_E_RECEIVE_TIMEOUT = -5 | ||
13 | MOBILEBACKUP2_E_BAD_VERSION = -6 | ||
14 | MOBILEBACKUP2_E_REPLY_NOT_OK = -7 | ||
15 | MOBILEBACKUP2_E_NO_COMMON_VERSION = -8 | ||
16 | MOBILEBACKUP2_E_UNKNOWN_ERROR = -256 | ||
17 | |||
18 | mobilebackup2_error_t mobilebackup2_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, mobilebackup2_client_t * client) | ||
19 | mobilebackup2_error_t mobilebackup2_client_free(mobilebackup2_client_t client) | ||
20 | |||
21 | mobilebackup2_error_t mobilebackup2_send_message(mobilebackup2_client_t client, char *message, plist.plist_t options) | ||
22 | mobilebackup2_error_t mobilebackup2_receive_message(mobilebackup2_client_t client, plist.plist_t *msg_plist, char **dlmessage) | ||
23 | mobilebackup2_error_t mobilebackup2_send_raw(mobilebackup2_client_t client, char *data, uint32_t length, uint32_t *bytes) | ||
24 | mobilebackup2_error_t mobilebackup2_receive_raw(mobilebackup2_client_t client, char *data, uint32_t length, uint32_t *bytes) | ||
25 | mobilebackup2_error_t mobilebackup2_version_exchange(mobilebackup2_client_t client, double local_versions[], char count, double *remote_version) | ||
26 | mobilebackup2_error_t mobilebackup2_send_request(mobilebackup2_client_t client, char *request, char *target_identifier, char *source_identifier, plist.plist_t options) | ||
27 | mobilebackup2_error_t mobilebackup2_send_status_response(mobilebackup2_client_t client, int status_code, char *status1, plist.plist_t status2) | ||
28 | |||
29 | cdef class MobileBackup2Error(BaseError): | ||
30 | def __init__(self, *args, **kwargs): | ||
31 | self._lookup_table = { | ||
32 | MOBILEBACKUP2_E_SUCCESS: "Success", | ||
33 | MOBILEBACKUP2_E_INVALID_ARG: "Invalid argument", | ||
34 | MOBILEBACKUP2_E_PLIST_ERROR: "Property list error", | ||
35 | MOBILEBACKUP2_E_MUX_ERROR: "MUX error", | ||
36 | MOBILEBACKUP2_E_SSL_ERROR: "SSL error", | ||
37 | MOBILEBACKUP2_E_RECEIVE_TIMEOUT: "Receive timeout", | ||
38 | MOBILEBACKUP2_E_BAD_VERSION: "Bad version", | ||
39 | MOBILEBACKUP2_E_REPLY_NOT_OK: "Reply not OK", | ||
40 | MOBILEBACKUP2_E_NO_COMMON_VERSION: "No common version", | ||
41 | MOBILEBACKUP2_E_UNKNOWN_ERROR: "Unknown error" | ||
42 | } | ||
43 | BaseError.__init__(self, *args, **kwargs) | ||
44 | |||
45 | cdef class MobileBackup2Client(PropertyListService): | ||
46 | __service_name__ = "com.apple.mobilebackup2" | ||
47 | cdef mobilebackup2_client_t _c_client | ||
48 | |||
49 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
50 | self.handle_error(mobilebackup2_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
51 | |||
52 | def __dealloc__(self): | ||
53 | cdef mobilebackup2_error_t err | ||
54 | if self._c_client is not NULL: | ||
55 | err = mobilebackup2_client_free(self._c_client) | ||
56 | self.handle_error(err) | ||
57 | |||
58 | cdef inline BaseError _error(self, int16_t ret): | ||
59 | return MobileBackup2Error(ret) | ||
60 | |||
61 | cpdef send_message(self, bytes message, plist.Node options): | ||
62 | self.handle_error(mobilebackup2_send_message(self._c_client, message, options._c_node)) | ||
63 | |||
64 | cpdef tuple receive_message(self): | ||
65 | cdef: | ||
66 | char* dlmessage = NULL | ||
67 | plist.plist_t c_node = NULL | ||
68 | mobilebackup2_error_t err | ||
69 | err = mobilebackup2_receive_message(self._c_client, &c_node, &dlmessage) | ||
70 | try: | ||
71 | self.handle_error(err) | ||
72 | return (plist.plist_t_to_node(c_node), <bytes>dlmessage) | ||
73 | except BaseError, e: | ||
74 | if c_node != NULL: | ||
75 | plist.plist_free(c_node) | ||
76 | if dlmessage != NULL: | ||
77 | free(dlmessage) | ||
78 | raise | ||
79 | |||
80 | cpdef int send_raw(self, bytes data, int length): | ||
81 | cdef: | ||
82 | uint32_t bytes_recvd = 0 | ||
83 | mobilebackup2_error_t err | ||
84 | err = mobilebackup2_send_raw(self._c_client, data, length, &bytes_recvd) | ||
85 | try: | ||
86 | self.handle_error(err) | ||
87 | return <bint>bytes_recvd | ||
88 | except BaseError, e: | ||
89 | raise | ||
90 | |||
91 | cpdef int receive_raw(self, bytearray data, int length): | ||
92 | cdef: | ||
93 | uint32_t bytes_recvd = 0 | ||
94 | mobilebackup2_error_t err | ||
95 | err = mobilebackup2_receive_raw(self._c_client, data, length, &bytes_recvd) | ||
96 | |||
97 | # Throwing an exception when we test if theres more data to read is excessive | ||
98 | if err == -1 and bytes_recvd == 0: | ||
99 | return 0 | ||
100 | |||
101 | try: | ||
102 | self.handle_error(err) | ||
103 | return <bint>bytes_recvd | ||
104 | except BaseError, e: | ||
105 | raise | ||
106 | |||
107 | cpdef float version_exchange(self, double[::1] local_versions): | ||
108 | cdef: | ||
109 | double[::1] temp = None | ||
110 | double remote_version = 0.0 | ||
111 | mobilebackup2_error_t err | ||
112 | err = mobilebackup2_version_exchange(self._c_client, &local_versions[0], len(local_versions), &remote_version) | ||
113 | try: | ||
114 | self.handle_error(err) | ||
115 | return <float>remote_version | ||
116 | except BaseError, e: | ||
117 | raise | ||
118 | |||
119 | cpdef send_request(self, bytes request, bytes target_identifier, bytes source_identifier, plist.Node options): | ||
120 | self.handle_error(mobilebackup2_send_request(self._c_client, request, target_identifier, source_identifier, options._c_node)) | ||
121 | |||
122 | cpdef send_status_response(self, int status_code, bytes status1, plist.Node status2): | ||
123 | self.handle_error(mobilebackup2_send_status_response(self._c_client, status_code, status1, status2._c_node)) | ||
diff --git a/cython/mobilesync.pxi b/cython/mobilesync.pxi new file mode 100644 index 0000000..23f0005 --- /dev/null +++ b/cython/mobilesync.pxi | |||
@@ -0,0 +1,164 @@ | |||
1 | cdef extern from "libimobiledevice/mobilesync.h": | ||
2 | cdef struct mobilesync_client_private: | ||
3 | pass | ||
4 | ctypedef mobilesync_client_private *mobilesync_client_t | ||
5 | ctypedef enum mobilesync_error_t: | ||
6 | MOBILESYNC_E_SUCCESS = 0 | ||
7 | MOBILESYNC_E_INVALID_ARG = -1 | ||
8 | MOBILESYNC_E_PLIST_ERROR = -2 | ||
9 | MOBILESYNC_E_MUX_ERROR = -3 | ||
10 | MOBILESYNC_E_SSL_ERROR = -4 | ||
11 | MOBILESYNC_E_RECEIVE_TIMEOUT = -5 | ||
12 | MOBILESYNC_E_BAD_VERSION = -6 | ||
13 | MOBILESYNC_E_SYNC_REFUSED = -7 | ||
14 | MOBILESYNC_E_CANCELLED = -8 | ||
15 | MOBILESYNC_E_WRONG_DIRECTION = -9 | ||
16 | MOBILESYNC_E_NOT_READY = -10 | ||
17 | MOBILESYNC_E_UNKNOWN_ERROR = -256 | ||
18 | |||
19 | ctypedef enum mobilesync_sync_type_t: | ||
20 | MOBILESYNC_SYNC_TYPE_FAST | ||
21 | MOBILESYNC_SYNC_TYPE_SLOW | ||
22 | MOBILESYNC_SYNC_TYPE_RESET | ||
23 | |||
24 | ctypedef struct mobilesync_anchors: | ||
25 | char *device_anchor | ||
26 | char *host_anchor | ||
27 | ctypedef mobilesync_anchors *mobilesync_anchors_t | ||
28 | |||
29 | mobilesync_error_t mobilesync_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilesync_client_t * client) | ||
30 | mobilesync_error_t mobilesync_client_free(mobilesync_client_t client) | ||
31 | mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist.plist_t *plist) | ||
32 | mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist.plist_t plist) | ||
33 | |||
34 | mobilesync_error_t mobilesync_start(mobilesync_client_t client, char *data_class, mobilesync_anchors_t anchors, uint64_t computer_data_class_version, mobilesync_sync_type_t *sync_type, uint64_t *device_data_class_version, char** error_description) | ||
35 | mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, char* reason) | ||
36 | mobilesync_error_t mobilesync_finish(mobilesync_client_t client) | ||
37 | |||
38 | mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client) | ||
39 | mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client) | ||
40 | mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist.plist_t *entities, uint8_t *is_last_record, plist.plist_t *actions) | ||
41 | mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client) | ||
42 | |||
43 | mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client) | ||
44 | mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist.plist_t changes, uint8_t is_last_record, plist.plist_t actions) | ||
45 | mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist.plist_t *mapping) | ||
46 | |||
47 | mobilesync_anchors_t mobilesync_anchors_new(char *device_anchor, char *computer_anchor) | ||
48 | void mobilesync_anchors_free(mobilesync_anchors_t anchors) | ||
49 | |||
50 | plist.plist_t mobilesync_actions_new() | ||
51 | void mobilesync_actions_add(plist.plist_t actions, ...) | ||
52 | void mobilesync_actions_free(plist.plist_t actions) | ||
53 | |||
54 | SYNC_TYPE_FAST = MOBILESYNC_SYNC_TYPE_FAST | ||
55 | SYNC_TYPE_SLOW = MOBILESYNC_SYNC_TYPE_SLOW | ||
56 | SYNC_TYPE_RESET = MOBILESYNC_SYNC_TYPE_RESET | ||
57 | |||
58 | cdef class MobileSyncError(BaseError): | ||
59 | def __init__(self, *args, **kwargs): | ||
60 | self._lookup_table = { | ||
61 | MOBILESYNC_E_SUCCESS: "Success", | ||
62 | MOBILESYNC_E_INVALID_ARG: "Invalid argument", | ||
63 | MOBILESYNC_E_PLIST_ERROR: "Property list error", | ||
64 | MOBILESYNC_E_MUX_ERROR: "MUX error", | ||
65 | MOBILESYNC_E_SSL_ERROR: "SSL error", | ||
66 | MOBILESYNC_E_RECEIVE_TIMEOUT: "Receive timeout", | ||
67 | MOBILESYNC_E_BAD_VERSION: "Bad version", | ||
68 | MOBILESYNC_E_SYNC_REFUSED: "Sync refused", | ||
69 | MOBILESYNC_E_CANCELLED: "Sync cancelled", | ||
70 | MOBILESYNC_E_WRONG_DIRECTION: "Wrong sync direction", | ||
71 | MOBILESYNC_E_NOT_READY: "Not ready to receive changes", | ||
72 | MOBILESYNC_E_UNKNOWN_ERROR: "Unknown error" | ||
73 | } | ||
74 | BaseError.__init__(self, *args, **kwargs) | ||
75 | |||
76 | cdef class MobileSyncClient(DeviceLinkService): | ||
77 | __service_name__ = "com.apple.mobilesync" | ||
78 | cdef mobilesync_client_t _c_client | ||
79 | |||
80 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
81 | self.handle_error(mobilesync_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client))) | ||
82 | |||
83 | def __dealloc__(self): | ||
84 | cdef mobilesync_error_t err | ||
85 | if self._c_client is not NULL: | ||
86 | err = mobilesync_client_free(self._c_client) | ||
87 | self.handle_error(err) | ||
88 | |||
89 | cpdef tuple start(self, bytes data_class, bytes device_anchor, bytes host_anchor): | ||
90 | cdef: | ||
91 | mobilesync_anchors_t anchors = NULL | ||
92 | mobilesync_sync_type_t sync_type | ||
93 | uint64_t computer_data_class_version = 1 | ||
94 | uint64_t device_data_class_version | ||
95 | char* error_description = NULL | ||
96 | |||
97 | if device_anchor is None: | ||
98 | anchors = mobilesync_anchors_new(NULL, host_anchor) | ||
99 | else: | ||
100 | anchors = mobilesync_anchors_new(device_anchor, host_anchor) | ||
101 | |||
102 | try: | ||
103 | self.handle_error(mobilesync_start(self._c_client, data_class, anchors, computer_data_class_version, &sync_type, &device_data_class_version, &error_description)) | ||
104 | return (sync_type, <bint>computer_data_class_version, <bint>device_data_class_version, <bytes>error_description) | ||
105 | except Exception, e: | ||
106 | raise | ||
107 | finally: | ||
108 | mobilesync_anchors_free(anchors) | ||
109 | |||
110 | cpdef finish(self): | ||
111 | self.handle_error(mobilesync_finish(self._c_client)) | ||
112 | |||
113 | cpdef cancel(self, bytes reason): | ||
114 | self.handle_error(mobilesync_cancel(self._c_client, reason)) | ||
115 | |||
116 | cpdef get_all_records_from_device(self): | ||
117 | self.handle_error(mobilesync_get_all_records_from_device(self._c_client)) | ||
118 | |||
119 | cpdef get_changes_from_device(self): | ||
120 | self.handle_error(mobilesync_get_changes_from_device(self._c_client)) | ||
121 | |||
122 | cpdef tuple receive_changes(self): | ||
123 | cdef: | ||
124 | plist.plist_t entities = NULL | ||
125 | uint8_t is_last_record = 0 | ||
126 | plist.plist_t actions = NULL | ||
127 | try: | ||
128 | self.handle_error(mobilesync_receive_changes(self._c_client, &entities, &is_last_record, &actions)) | ||
129 | return (plist.plist_t_to_node(entities), <bint>is_last_record, plist.plist_t_to_node(actions)) | ||
130 | except Exception, e: | ||
131 | if entities != NULL: | ||
132 | plist.plist_free(entities) | ||
133 | if actions != NULL: | ||
134 | plist.plist_free(actions) | ||
135 | raise | ||
136 | |||
137 | cpdef acknowledge_changes_from_device(self): | ||
138 | self.handle_error(mobilesync_acknowledge_changes_from_device(self._c_client)) | ||
139 | |||
140 | cpdef ready_to_send_changes_from_computer(self): | ||
141 | self.handle_error(mobilesync_ready_to_send_changes_from_computer(self._c_client)) | ||
142 | |||
143 | cpdef send_changes(self, plist.Node changes, bint is_last_record, plist.Node actions): | ||
144 | self.handle_error(mobilesync_send_changes(self._c_client, changes._c_node, is_last_record, actions._c_node)) | ||
145 | |||
146 | cpdef remap_identifiers(self): | ||
147 | cdef plist.plist_t remapping = NULL | ||
148 | |||
149 | try: | ||
150 | self.handle_error(mobilesync_remap_identifiers(self._c_client, &remapping)) | ||
151 | return plist.plist_t_to_node(remapping) | ||
152 | except Exception, e: | ||
153 | if remapping != NULL: | ||
154 | plist.plist_free(remapping) | ||
155 | raise | ||
156 | |||
157 | cdef int16_t _send(self, plist.plist_t node): | ||
158 | return mobilesync_send(self._c_client, node) | ||
159 | |||
160 | cdef int16_t _receive(self, plist.plist_t* node): | ||
161 | return mobilesync_receive(self._c_client, node) | ||
162 | |||
163 | cdef inline BaseError _error(self, int16_t ret): | ||
164 | return MobileSyncError(ret) | ||
diff --git a/cython/notification_proxy.pxi b/cython/notification_proxy.pxi new file mode 100644 index 0000000..261200e --- /dev/null +++ b/cython/notification_proxy.pxi | |||
@@ -0,0 +1,110 @@ | |||
1 | cdef extern from "libimobiledevice/notification_proxy.h": | ||
2 | cdef struct np_client_private: | ||
3 | pass | ||
4 | ctypedef np_client_private *np_client_t | ||
5 | ctypedef enum np_error_t: | ||
6 | NP_E_SUCCESS = 0 | ||
7 | NP_E_INVALID_ARG = -1 | ||
8 | NP_E_PLIST_ERROR = -2 | ||
9 | NP_E_CONN_FAILED = -3 | ||
10 | NP_E_UNKNOWN_ERROR = -256 | ||
11 | ctypedef void (*np_notify_cb_t) (const_char_ptr notification, void *userdata) | ||
12 | np_error_t np_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, np_client_t *client) | ||
13 | np_error_t np_client_free(np_client_t client) | ||
14 | np_error_t np_post_notification(np_client_t client, char *notification) | ||
15 | np_error_t np_observe_notification(np_client_t client, char *notification) | ||
16 | np_error_t np_observe_notifications(np_client_t client, char **notification_spec) | ||
17 | np_error_t np_set_notify_callback(np_client_t client, np_notify_cb_t notify_cb, void *userdata) | ||
18 | |||
19 | cdef char* C_NP_SYNC_WILL_START "NP_SYNC_WILL_START" | ||
20 | cdef char* C_NP_SYNC_DID_START "NP_SYNC_DID_START" | ||
21 | cdef char* C_NP_SYNC_DID_FINISH "NP_SYNC_DID_FINISH" | ||
22 | cdef char* C_NP_SYNC_LOCK_REQUEST "NP_SYNC_LOCK_REQUEST" | ||
23 | |||
24 | cdef char* C_NP_SYNC_CANCEL_REQUEST "NP_SYNC_CANCEL_REQUEST" | ||
25 | cdef char* C_NP_SYNC_SUSPEND_REQUEST "NP_SYNC_SUSPEND_REQUEST" | ||
26 | cdef char* C_NP_SYNC_RESUME_REQUEST "NP_SYNC_RESUME_REQUEST" | ||
27 | cdef char* C_NP_PHONE_NUMBER_CHANGED "NP_PHONE_NUMBER_CHANGED" | ||
28 | cdef char* C_NP_DEVICE_NAME_CHANGED "NP_DEVICE_NAME_CHANGED" | ||
29 | cdef char* C_NP_TIMEZONE_CHANGED "NP_TIMEZONE_CHANGED" | ||
30 | cdef char* C_NP_TRUSTED_HOST_ATTACHED "NP_TRUSTED_HOST_ATTACHED" | ||
31 | cdef char* C_NP_HOST_DETACHED "NP_HOST_DETACHED" | ||
32 | cdef char* C_NP_HOST_ATTACHED "NP_HOST_ATTACHED" | ||
33 | cdef char* C_NP_REGISTRATION_FAILED "NP_REGISTRATION_FAILED" | ||
34 | cdef char* C_NP_ACTIVATION_STATE "NP_ACTIVATION_STATE" | ||
35 | cdef char* C_NP_BRICK_STATE "NP_BRICK_STATE" | ||
36 | cdef char* C_NP_DS_DOMAIN_CHANGED "NP_DS_DOMAIN_CHANGED" | ||
37 | cdef char* C_NP_BACKUP_DOMAIN_CHANGED "NP_BACKUP_DOMAIN_CHANGED" | ||
38 | cdef char* C_NP_APP_INSTALLED "NP_APP_INSTALLED" | ||
39 | cdef char* C_NP_APP_UNINSTALLED "NP_APP_UNINSTALLED" | ||
40 | cdef char* C_NP_DEV_IMAGE_MOUNTED "NP_DEV_IMAGE_MOUNTED" | ||
41 | cdef char* C_NP_ATTEMPTACTIVATION "NP_ATTEMPTACTIVATION" | ||
42 | cdef char* C_NP_ITDBPREP_DID_END "NP_ITDBPREP_DID_END" | ||
43 | cdef char* C_NP_LANGUAGE_CHANGED "NP_LANGUAGE_CHANGED" | ||
44 | cdef char* C_NP_ADDRESS_BOOK_PREF_CHANGED "NP_ADDRESS_BOOK_PREF_CHANGED" | ||
45 | |||
46 | NP_SYNC_WILL_START = C_NP_SYNC_WILL_START | ||
47 | NP_SYNC_DID_START = C_NP_SYNC_DID_START | ||
48 | NP_SYNC_DID_FINISH = C_NP_SYNC_DID_FINISH | ||
49 | NP_SYNC_LOCK_REQUEST = C_NP_SYNC_LOCK_REQUEST | ||
50 | |||
51 | NP_SYNC_CANCEL_REQUEST = C_NP_SYNC_CANCEL_REQUEST | ||
52 | NP_SYNC_SUSPEND_REQUEST = C_NP_SYNC_SUSPEND_REQUEST | ||
53 | NP_SYNC_RESUME_REQUEST = C_NP_SYNC_RESUME_REQUEST | ||
54 | NP_PHONE_NUMBER_CHANGED = C_NP_PHONE_NUMBER_CHANGED | ||
55 | NP_DEVICE_NAME_CHANGED = C_NP_DEVICE_NAME_CHANGED | ||
56 | NP_TIMEZONE_CHANGED = C_NP_TIMEZONE_CHANGED | ||
57 | NP_TRUSTED_HOST_ATTACHED = C_NP_TRUSTED_HOST_ATTACHED | ||
58 | NP_HOST_DETACHED = C_NP_HOST_DETACHED | ||
59 | NP_HOST_ATTACHED = C_NP_HOST_ATTACHED | ||
60 | NP_REGISTRATION_FAILED = C_NP_REGISTRATION_FAILED | ||
61 | NP_ACTIVATION_STATE = C_NP_ACTIVATION_STATE | ||
62 | NP_BRICK_STATE = C_NP_BRICK_STATE | ||
63 | NP_DS_DOMAIN_CHANGED = C_NP_DS_DOMAIN_CHANGED | ||
64 | NP_BACKUP_DOMAIN_CHANGED = C_NP_BACKUP_DOMAIN_CHANGED | ||
65 | NP_APP_INSTALLED = C_NP_APP_INSTALLED | ||
66 | NP_APP_UNINSTALLED = C_NP_APP_UNINSTALLED | ||
67 | NP_DEV_IMAGE_MOUNTED = C_NP_DEV_IMAGE_MOUNTED | ||
68 | NP_ATTEMPTACTIVATION = C_NP_ATTEMPTACTIVATION | ||
69 | NP_ITDBPREP_DID_END = C_NP_ITDBPREP_DID_END | ||
70 | NP_LANGUAGE_CHANGED = C_NP_LANGUAGE_CHANGED | ||
71 | NP_ADDRESS_BOOK_PREF_CHANGED = C_NP_ADDRESS_BOOK_PREF_CHANGED | ||
72 | |||
73 | cdef void np_notify_cb(const_char_ptr notification, void *py_callback) noexcept: | ||
74 | (<object>py_callback)(notification) | ||
75 | |||
76 | cdef class NotificationProxyError(BaseError): | ||
77 | def __init__(self, *args, **kwargs): | ||
78 | self._lookup_table = { | ||
79 | NP_E_SUCCESS: "Success", | ||
80 | NP_E_INVALID_ARG: "Invalid argument", | ||
81 | NP_E_PLIST_ERROR: "Property list error", | ||
82 | NP_E_CONN_FAILED: "Connection failed", | ||
83 | NP_E_UNKNOWN_ERROR: "Unknown error" | ||
84 | } | ||
85 | BaseError.__init__(self, *args, **kwargs) | ||
86 | |||
87 | cdef class NotificationProxyClient(PropertyListService): | ||
88 | __service_name__ = "com.apple.mobile.notification_proxy" | ||
89 | cdef np_client_t _c_client | ||
90 | |||
91 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
92 | self.handle_error(np_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
93 | |||
94 | def __dealloc__(self): | ||
95 | cdef np_error_t err | ||
96 | if self._c_client is not NULL: | ||
97 | err = np_client_free(self._c_client) | ||
98 | self.handle_error(err) | ||
99 | |||
100 | cdef inline BaseError _error(self, int16_t ret): | ||
101 | return NotificationProxyError(ret) | ||
102 | |||
103 | cpdef set_notify_callback(self, object callback): | ||
104 | self.handle_error(np_set_notify_callback(self._c_client, np_notify_cb, <void*>callback)) | ||
105 | |||
106 | cpdef observe_notification(self, bytes notification): | ||
107 | self.handle_error(np_observe_notification(self._c_client, notification)) | ||
108 | |||
109 | cpdef post_notification(self, bytes notification): | ||
110 | self.handle_error(np_post_notification(self._c_client, notification)) | ||
diff --git a/cython/restore.pxi b/cython/restore.pxi new file mode 100644 index 0000000..9d03935 --- /dev/null +++ b/cython/restore.pxi | |||
@@ -0,0 +1,131 @@ | |||
1 | cdef extern from "libimobiledevice/restore.h": | ||
2 | cdef struct restored_client_private: | ||
3 | pass | ||
4 | ctypedef restored_client_private *restored_client_t | ||
5 | |||
6 | ctypedef enum restored_error_t: | ||
7 | RESTORE_E_SUCCESS = 0 | ||
8 | RESTORE_E_INVALID_ARG = -1 | ||
9 | RESTORE_E_PLIST_ERROR = -2 | ||
10 | RESTORE_E_MUX_ERROR = -3 | ||
11 | RESTORE_E_NOT_ENOUGH_DATA = -4 | ||
12 | RESTORE_E_RECEIVE_TIMEOUT = -5 | ||
13 | RESTORE_E_UNKNOWN_ERROR = -256 | ||
14 | |||
15 | restored_error_t restored_client_new(idevice_t device, restored_client_t *client, char *label) | ||
16 | restored_error_t restored_client_free(restored_client_t client) | ||
17 | |||
18 | restored_error_t restored_query_type(restored_client_t client, char **tp, uint64_t *version) | ||
19 | restored_error_t restored_query_value(restored_client_t client, char *key, plist.plist_t *value) | ||
20 | restored_error_t restored_get_value(restored_client_t client, char *key, plist.plist_t *value) | ||
21 | restored_error_t restored_send(restored_client_t client, plist.plist_t plist) | ||
22 | restored_error_t restored_receive(restored_client_t client, plist.plist_t *plist) | ||
23 | restored_error_t restored_goodbye(restored_client_t client) | ||
24 | |||
25 | restored_error_t restored_start_restore(restored_client_t client, plist.plist_t options, uint64_t version) | ||
26 | restored_error_t restored_reboot(restored_client_t client) | ||
27 | |||
28 | void restored_client_set_label(restored_client_t client, char *label) | ||
29 | |||
30 | cdef class RestoreError(BaseError): | ||
31 | def __init__(self, *args, **kwargs): | ||
32 | self._lookup_table = { | ||
33 | RESTORE_E_SUCCESS: "Success", | ||
34 | RESTORE_E_INVALID_ARG: "Invalid argument", | ||
35 | RESTORE_E_PLIST_ERROR: "Property list error", | ||
36 | RESTORE_E_MUX_ERROR: "MUX Error", | ||
37 | RESTORE_E_NOT_ENOUGH_DATA: "Not enough data", | ||
38 | RESTORE_E_RECEIVE_TIMEOUT: "Receive timeout", | ||
39 | RESTORE_E_UNKNOWN_ERROR: "Unknown error" | ||
40 | } | ||
41 | BaseError.__init__(self, *args, **kwargs) | ||
42 | |||
43 | cdef class RestoreClient(PropertyListService): | ||
44 | cdef restored_client_t _c_client | ||
45 | |||
46 | def __cinit__(self, iDevice device not None, bytes label=b'', *args, **kwargs): | ||
47 | cdef: | ||
48 | restored_error_t err | ||
49 | char* c_label = NULL | ||
50 | if label: | ||
51 | c_label = label | ||
52 | err = restored_client_new(device._c_dev, &self._c_client, c_label) | ||
53 | self.handle_error(err) | ||
54 | |||
55 | self.device = device | ||
56 | |||
57 | def __dealloc__(self): | ||
58 | cdef restored_error_t err | ||
59 | if self._c_client is not NULL: | ||
60 | err = restored_client_free(self._c_client) | ||
61 | self.handle_error(err) | ||
62 | |||
63 | cdef inline BaseError _error(self, int16_t ret): | ||
64 | return RestoreError(ret) | ||
65 | |||
66 | cdef inline int16_t _send(self, plist.plist_t node): | ||
67 | return restored_send(self._c_client, node) | ||
68 | |||
69 | cdef inline int16_t _receive(self, plist.plist_t* node): | ||
70 | return restored_receive(self._c_client, node) | ||
71 | |||
72 | cpdef tuple query_type(self): | ||
73 | cdef: | ||
74 | restored_error_t err | ||
75 | char* c_type = NULL | ||
76 | uint64_t c_version = 0 | ||
77 | tuple result | ||
78 | err = restored_query_type(self._c_client, &c_type, &c_version) | ||
79 | try: | ||
80 | self.handle_error(err) | ||
81 | result = (c_type, c_version) | ||
82 | return result | ||
83 | except BaseError, e: | ||
84 | raise | ||
85 | finally: | ||
86 | if c_type != NULL: | ||
87 | free(c_type) | ||
88 | |||
89 | cpdef plist.Node query_value(self, bytes key=None): | ||
90 | cdef: | ||
91 | restored_error_t err | ||
92 | plist.plist_t c_node = NULL | ||
93 | char* c_key = NULL | ||
94 | if key is not None: | ||
95 | c_key = key | ||
96 | err = restored_query_value(self._c_client, c_key, &c_node) | ||
97 | try: | ||
98 | self.handle_error(err) | ||
99 | return plist.plist_t_to_node(c_node) | ||
100 | except BaseError, e: | ||
101 | if c_node != NULL: | ||
102 | plist.plist_free(c_node) | ||
103 | raise | ||
104 | |||
105 | cpdef plist.Node get_value(self, bytes key=None): | ||
106 | cdef: | ||
107 | restored_error_t err | ||
108 | plist.plist_t c_node = NULL | ||
109 | char* c_key = NULL | ||
110 | if key is not None: | ||
111 | c_key = key | ||
112 | err = restored_get_value(self._c_client, c_key, &c_node) | ||
113 | try: | ||
114 | self.handle_error(err) | ||
115 | return plist.plist_t_to_node(c_node) | ||
116 | except BaseError, e: | ||
117 | if c_node != NULL: | ||
118 | plist.plist_free(c_node) | ||
119 | raise | ||
120 | |||
121 | cpdef goodbye(self): | ||
122 | self.handle_error(restored_goodbye(self._c_client)) | ||
123 | |||
124 | cpdef start_restore(self, plist.Node options, uint64_t version): | ||
125 | self.handle_error(restored_start_restore(self._c_client, options._c_node, version)) | ||
126 | |||
127 | cpdef reboot(self): | ||
128 | self.handle_error(restored_reboot(self._c_client)) | ||
129 | |||
130 | cpdef set_label(self, bytes label): | ||
131 | restored_client_set_label(self._c_client, label) | ||
diff --git a/cython/sbservices.pxi b/cython/sbservices.pxi new file mode 100644 index 0000000..8ff2595 --- /dev/null +++ b/cython/sbservices.pxi | |||
@@ -0,0 +1,80 @@ | |||
1 | cdef extern from "libimobiledevice/sbservices.h": | ||
2 | cdef struct sbservices_client_private: | ||
3 | pass | ||
4 | ctypedef sbservices_client_private *sbservices_client_t | ||
5 | ctypedef enum sbservices_error_t: | ||
6 | SBSERVICES_E_SUCCESS = 0 | ||
7 | SBSERVICES_E_INVALID_ARG = -1 | ||
8 | SBSERVICES_E_PLIST_ERROR = -2 | ||
9 | SBSERVICES_E_CONN_FAILED = -3 | ||
10 | SBSERVICES_E_UNKNOWN_ERROR = -256 | ||
11 | sbservices_error_t sbservices_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, sbservices_client_t *client) | ||
12 | sbservices_error_t sbservices_client_free(sbservices_client_t client) | ||
13 | sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist.plist_t *state, char *format_version) | ||
14 | sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist.plist_t newstate) | ||
15 | sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, char *bundleId, char **pngdata, uint64_t *pngsize) | ||
16 | |||
17 | cdef class SpringboardServicesError(BaseError): | ||
18 | def __init__(self, *args, **kwargs): | ||
19 | self._lookup_table = { | ||
20 | SBSERVICES_E_SUCCESS: "Success", | ||
21 | SBSERVICES_E_INVALID_ARG: "Invalid argument", | ||
22 | SBSERVICES_E_PLIST_ERROR: "Property list error", | ||
23 | SBSERVICES_E_CONN_FAILED: "Connection failed", | ||
24 | SBSERVICES_E_UNKNOWN_ERROR: "Unknown error" | ||
25 | } | ||
26 | BaseError.__init__(self, *args, **kwargs) | ||
27 | |||
28 | cdef class SpringboardServicesClient(PropertyListService): | ||
29 | __service_name__ = "com.apple.springboardservices" | ||
30 | cdef sbservices_client_t _c_client | ||
31 | cdef char* format_version | ||
32 | |||
33 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
34 | self.handle_error(sbservices_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
35 | self.format_version = "2" | ||
36 | |||
37 | def __dealloc__(self): | ||
38 | if self._c_client is not NULL: | ||
39 | err = sbservices_client_free(self._c_client) | ||
40 | self.handle_error(err) | ||
41 | |||
42 | cdef inline BaseError _error(self, int16_t ret): | ||
43 | return SpringboardServicesError(ret) | ||
44 | |||
45 | property format_version: | ||
46 | def __get__(self): | ||
47 | return <bytes>self.format_version | ||
48 | def __set__(self, char* newversion): | ||
49 | self.format_version = newversion | ||
50 | |||
51 | property icon_state: | ||
52 | def __get__(self): | ||
53 | cdef: | ||
54 | plist.plist_t c_node = NULL | ||
55 | sbservices_error_t err | ||
56 | err = sbservices_get_icon_state(self._c_client, &c_node, self.format_version) | ||
57 | try: | ||
58 | self.handle_error(err) | ||
59 | |||
60 | return plist.plist_t_to_node(c_node) | ||
61 | except BaseError, e: | ||
62 | if c_node != NULL: | ||
63 | plist.plist_free(c_node) | ||
64 | raise | ||
65 | def __set__(self, plist.Node newstate not None): | ||
66 | self.handle_error(sbservices_set_icon_state(self._c_client, newstate._c_node)) | ||
67 | |||
68 | cpdef bytes get_pngdata(self, bytes bundleId): | ||
69 | cdef: | ||
70 | char* pngdata = NULL | ||
71 | uint64_t pngsize | ||
72 | sbservices_error_t err | ||
73 | err = sbservices_get_icon_pngdata(self._c_client, bundleId, &pngdata, &pngsize) | ||
74 | try: | ||
75 | self.handle_error(err) | ||
76 | |||
77 | return pngdata[:pngsize] | ||
78 | except BaseError, e: | ||
79 | free(pngdata) | ||
80 | raise | ||
diff --git a/cython/screenshotr.pxi b/cython/screenshotr.pxi new file mode 100644 index 0000000..a1e82e2 --- /dev/null +++ b/cython/screenshotr.pxi | |||
@@ -0,0 +1,66 @@ | |||
1 | cdef extern from "libimobiledevice/screenshotr.h": | ||
2 | cdef struct screenshotr_client_private: | ||
3 | pass | ||
4 | ctypedef screenshotr_client_private *screenshotr_client_t | ||
5 | |||
6 | ctypedef enum screenshotr_error_t: | ||
7 | SCREENSHOTR_E_SUCCESS = 0 | ||
8 | SCREENSHOTR_E_INVALID_ARG = -1 | ||
9 | SCREENSHOTR_E_PLIST_ERROR = -2 | ||
10 | SCREENSHOTR_E_MUX_ERROR = -3 | ||
11 | SCREENSHOTR_E_SSL_ERROR = -4 | ||
12 | SCREENSHOTR_E_RECEIVE_TIMEOUT = 5 | ||
13 | SCREENSHOTR_E_BAD_VERSION = -6 | ||
14 | SCREENSHOTR_E_UNKNOWN_ERROR = -256 | ||
15 | |||
16 | screenshotr_error_t screenshotr_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, screenshotr_client_t * client) | ||
17 | screenshotr_error_t screenshotr_client_free(screenshotr_client_t client) | ||
18 | screenshotr_error_t screenshotr_take_screenshot(screenshotr_client_t client, char **imgdata, uint64_t *imgsize) | ||
19 | |||
20 | cdef class ScreenshotrError(BaseError): | ||
21 | def __init__(self, *args, **kwargs): | ||
22 | self._lookup_table = { | ||
23 | SCREENSHOTR_E_SUCCESS: "Success", | ||
24 | SCREENSHOTR_E_INVALID_ARG: "Invalid argument", | ||
25 | SCREENSHOTR_E_PLIST_ERROR: "Property list error", | ||
26 | SCREENSHOTR_E_MUX_ERROR: "MUX error", | ||
27 | SCREENSHOTR_E_SSL_ERROR: "SSL error", | ||
28 | SCREENSHOTR_E_RECEIVE_TIMEOUT: "Receive timeout", | ||
29 | SCREENSHOTR_E_BAD_VERSION: "Bad version", | ||
30 | SCREENSHOTR_E_UNKNOWN_ERROR: "Unknown error" | ||
31 | } | ||
32 | BaseError.__init__(self, *args, **kwargs) | ||
33 | |||
34 | cdef class ScreenshotrClient(DeviceLinkService): | ||
35 | __service_name__ = "com.apple.mobile.screenshotr" | ||
36 | cdef screenshotr_client_t _c_client | ||
37 | |||
38 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
39 | self.handle_error(screenshotr_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
40 | |||
41 | def __dealloc__(self): | ||
42 | cdef screenshotr_error_t err | ||
43 | if self._c_client is not NULL: | ||
44 | err = screenshotr_client_free(self._c_client) | ||
45 | self.handle_error(err) | ||
46 | |||
47 | cpdef bytes take_screenshot(self): | ||
48 | cdef: | ||
49 | char* c_data = NULL | ||
50 | uint64_t data_size | ||
51 | bytes result | ||
52 | screenshotr_error_t err | ||
53 | |||
54 | err = screenshotr_take_screenshot(self._c_client, &c_data, &data_size) | ||
55 | try: | ||
56 | self.handle_error(err) | ||
57 | |||
58 | result = c_data[:data_size] | ||
59 | return result | ||
60 | except Exception, e: | ||
61 | if c_data != NULL: | ||
62 | free(c_data) | ||
63 | raise | ||
64 | |||
65 | cdef inline BaseError _error(self, int16_t ret): | ||
66 | return ScreenshotrError(ret) | ||
diff --git a/cython/webinspector.pxi b/cython/webinspector.pxi new file mode 100644 index 0000000..f77547d --- /dev/null +++ b/cython/webinspector.pxi | |||
@@ -0,0 +1,60 @@ | |||
1 | cdef extern from "libimobiledevice/webinspector.h": | ||
2 | cdef struct webinspector_client_private: | ||
3 | pass | ||
4 | ctypedef webinspector_client_private *webinspector_client_t | ||
5 | |||
6 | ctypedef enum webinspector_error_t: | ||
7 | WEBINSPECTOR_E_SUCCESS = 0 | ||
8 | WEBINSPECTOR_E_INVALID_ARG = -1 | ||
9 | WEBINSPECTOR_E_PLIST_ERROR = -2 | ||
10 | WEBINSPECTOR_E_MUX_ERROR = -3 | ||
11 | WEBINSPECTOR_E_SSL_ERROR = -4 | ||
12 | WEBINSPECTOR_E_RECEIVE_TIMEOUT = -5, | ||
13 | WEBINSPECTOR_E_NOT_ENOUGH_DATA = -6, | ||
14 | WEBINSPECTOR_E_UNKNOWN_ERROR = -256 | ||
15 | |||
16 | webinspector_error_t webinspector_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, webinspector_client_t * client) | ||
17 | webinspector_error_t webinspector_client_free(webinspector_client_t client) | ||
18 | |||
19 | webinspector_error_t webinspector_send(webinspector_client_t client, plist.plist_t plist) | ||
20 | webinspector_error_t webinspector_receive(webinspector_client_t client, plist.plist_t * plist) | ||
21 | webinspector_error_t webinspector_receive_with_timeout(webinspector_client_t client, plist.plist_t * plist, uint32_t timeout_ms) | ||
22 | |||
23 | cdef class WebinspectorError(BaseError): | ||
24 | def __init__(self, *args, **kwargs): | ||
25 | self._lookup_table = { | ||
26 | WEBINSPECTOR_E_SUCCESS: "Success", | ||
27 | WEBINSPECTOR_E_INVALID_ARG: "Invalid argument", | ||
28 | WEBINSPECTOR_E_PLIST_ERROR: "Property list error", | ||
29 | WEBINSPECTOR_E_MUX_ERROR: "MUX error", | ||
30 | WEBINSPECTOR_E_SSL_ERROR: "SSL Error", | ||
31 | WEBINSPECTOR_E_NOT_ENOUGH_DATA: 'Not enough data', | ||
32 | WEBINSPECTOR_E_RECEIVE_TIMEOUT: 'Connection timeout', | ||
33 | WEBINSPECTOR_E_UNKNOWN_ERROR: "Unknown error" | ||
34 | } | ||
35 | BaseError.__init__(self, *args, **kwargs) | ||
36 | |||
37 | cdef class WebinspectorClient(PropertyListService): | ||
38 | __service_name__ = "com.apple.webinspector" | ||
39 | cdef webinspector_client_t _c_client | ||
40 | |||
41 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
42 | self.handle_error(webinspector_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client)) | ||
43 | |||
44 | def __dealloc__(self): | ||
45 | cdef webinspector_error_t err | ||
46 | if self._c_client is not NULL: | ||
47 | err = webinspector_client_free(self._c_client) | ||
48 | self.handle_error(err) | ||
49 | |||
50 | cdef inline int16_t _send(self, plist.plist_t node): | ||
51 | return webinspector_send(self._c_client, node) | ||
52 | |||
53 | cdef inline int16_t _receive(self, plist.plist_t* node): | ||
54 | return webinspector_receive(self._c_client, node) | ||
55 | |||
56 | cdef inline int16_t _receive_with_timeout(self, plist.plist_t* node, int timeout_ms): | ||
57 | return webinspector_receive_with_timeout(self._c_client, node, timeout_ms) | ||
58 | |||
59 | cdef inline BaseError _error(self, int16_t ret): | ||
60 | return WebinspectorError(ret) | ||