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 | 246 | ||||
| -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, 3099 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..fb96320 --- /dev/null +++ b/cython/debugserver.pxi | |||
| @@ -0,0 +1,246 @@ | |||
| 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 cpython.bytes cimport PyBytes_AsString as PyString_AsString | ||
| 47 | cdef char ** to_cstring_array(list_str): | ||
| 48 | if not list_str: | ||
| 49 | return NULL | ||
| 50 | cdef char **ret = <char **>malloc(len(list_str) * sizeof(char *)) | ||
| 51 | for i in xrange(len(list_str)): | ||
| 52 | ret[i] = PyString_AsString(list_str[i]) | ||
| 53 | return ret | ||
| 54 | |||
| 55 | |||
| 56 | cdef class DebugServerCommand(Base): | ||
| 57 | cdef debugserver_command_t _c_command | ||
| 58 | |||
| 59 | def __init__(self, bytes name, int argc = 0, argv = None, *args, **kwargs): | ||
| 60 | cdef: | ||
| 61 | char* c_name = name | ||
| 62 | char** c_argv = to_cstring_array(argv) | ||
| 63 | |||
| 64 | try: | ||
| 65 | self.handle_error(debugserver_command_new(c_name, argc, c_argv, &self._c_command)) | ||
| 66 | except BaseError, e: | ||
| 67 | raise | ||
| 68 | finally: | ||
| 69 | free(c_argv) | ||
| 70 | |||
| 71 | def __enter__(self): | ||
| 72 | return self | ||
| 73 | |||
| 74 | def __exit__(self, type, value, traceback): | ||
| 75 | self.free() | ||
| 76 | |||
| 77 | cdef free(self): | ||
| 78 | cdef debugserver_error_t err | ||
| 79 | if self._c_command is not NULL: | ||
| 80 | err = debugserver_command_free(self._c_command) | ||
| 81 | self.handle_error(err) | ||
| 82 | |||
| 83 | cdef inline BaseError _error(self, int16_t ret): | ||
| 84 | return DebugServerError(ret) | ||
| 85 | |||
| 86 | |||
| 87 | cdef class DebugServerClient(BaseService): | ||
| 88 | __service_name__ = "com.apple.debugserver" | ||
| 89 | cdef debugserver_client_t _c_client | ||
| 90 | |||
| 91 | def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs): | ||
| 92 | if (device is not None and descriptor is not None): | ||
| 93 | self.handle_error(debugserver_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client))) | ||
| 94 | |||
| 95 | def __dealloc__(self): | ||
| 96 | cdef debugserver_error_t err | ||
| 97 | if self._c_client is not NULL: | ||
| 98 | err = debugserver_client_free(self._c_client) | ||
| 99 | self.handle_error(err) | ||
| 100 | |||
| 101 | cdef BaseError _error(self, int16_t ret): | ||
| 102 | return DebugServerError(ret) | ||
| 103 | |||
| 104 | cpdef uint32_t send(self, bytes data): | ||
| 105 | cdef: | ||
| 106 | uint32_t bytes_send | ||
| 107 | char* c_data = data | ||
| 108 | try: | ||
| 109 | self.handle_error(debugserver_client_send(self._c_client, c_data, len(data), &bytes_send)) | ||
| 110 | except BaseError, e: | ||
| 111 | raise | ||
| 112 | |||
| 113 | return bytes_send | ||
| 114 | |||
| 115 | cpdef bytes send_command(self, DebugServerCommand command): | ||
| 116 | cdef: | ||
| 117 | char* c_response = NULL | ||
| 118 | bytes result | ||
| 119 | |||
| 120 | try: | ||
| 121 | self.handle_error(debugserver_client_send_command(self._c_client, command._c_command, &c_response, NULL)) | ||
| 122 | if c_response: | ||
| 123 | result = c_response | ||
| 124 | return result | ||
| 125 | else: | ||
| 126 | return None | ||
| 127 | except BaseError, e: | ||
| 128 | raise | ||
| 129 | finally: | ||
| 130 | free(c_response) | ||
| 131 | |||
| 132 | cpdef bytes receive(self, uint32_t size): | ||
| 133 | cdef: | ||
| 134 | uint32_t bytes_received | ||
| 135 | char* c_data = <char *>malloc(size) | ||
| 136 | bytes result | ||
| 137 | |||
| 138 | try: | ||
| 139 | self.handle_error(debugserver_client_receive(self._c_client, c_data, size, &bytes_received)) | ||
| 140 | result = c_data[:bytes_received] | ||
| 141 | return result | ||
| 142 | except BaseError, e: | ||
| 143 | raise | ||
| 144 | finally: | ||
| 145 | free(c_data) | ||
| 146 | |||
| 147 | cpdef bytes receive_with_timeout(self, uint32_t size, unsigned int timeout): | ||
| 148 | cdef: | ||
| 149 | uint32_t bytes_received | ||
| 150 | char* c_data = <char *>malloc(size) | ||
| 151 | bytes result | ||
| 152 | |||
| 153 | try: | ||
| 154 | self.handle_error(debugserver_client_receive_with_timeout(self._c_client, c_data, size, &bytes_received, timeout)) | ||
| 155 | result = c_data[:bytes_received] | ||
| 156 | return result | ||
| 157 | except BaseError, e: | ||
| 158 | raise | ||
| 159 | finally: | ||
| 160 | free(c_data) | ||
| 161 | |||
| 162 | cpdef bytes receive_response(self): | ||
| 163 | cdef: | ||
| 164 | char* c_response = NULL | ||
| 165 | bytes result | ||
| 166 | |||
| 167 | try: | ||
| 168 | self.handle_error(debugserver_client_receive_response(self._c_client, &c_response, NULL)) | ||
| 169 | if c_response: | ||
| 170 | result = c_response | ||
| 171 | return result | ||
| 172 | else: | ||
| 173 | return None | ||
| 174 | except BaseError, e: | ||
| 175 | raise | ||
| 176 | finally: | ||
| 177 | free(c_response) | ||
| 178 | |||
| 179 | cpdef bytes set_argv(self, int argc, argv): | ||
| 180 | cdef: | ||
| 181 | char** c_argv = to_cstring_array(argv) | ||
| 182 | char* c_response = NULL | ||
| 183 | bytes result | ||
| 184 | |||
| 185 | try: | ||
| 186 | self.handle_error(debugserver_client_set_argv(self._c_client, argc, c_argv, &c_response)) | ||
| 187 | if c_response: | ||
| 188 | result = c_response | ||
| 189 | return result | ||
| 190 | else: | ||
| 191 | return None | ||
| 192 | except BaseError, e: | ||
| 193 | raise | ||
| 194 | finally: | ||
| 195 | free(c_argv) | ||
| 196 | free(c_response) | ||
| 197 | |||
| 198 | cpdef bytes set_environment_hex_encoded(self, bytes env): | ||
| 199 | cdef: | ||
| 200 | char* c_env = env | ||
| 201 | char* c_response = NULL | ||
| 202 | bytes result | ||
| 203 | |||
| 204 | try: | ||
| 205 | self.handle_error(debugserver_client_set_environment_hex_encoded(self._c_client, c_env, &c_response)) | ||
| 206 | if c_response: | ||
| 207 | result = c_response | ||
| 208 | return result | ||
| 209 | else: | ||
| 210 | return None | ||
| 211 | except BaseError, e: | ||
| 212 | raise | ||
| 213 | finally: | ||
| 214 | free(c_response) | ||
| 215 | |||
| 216 | cpdef bytes encode_string(self, bytes buffer): | ||
| 217 | cdef: | ||
| 218 | char *c_buffer = buffer | ||
| 219 | uint32_t encoded_length = len(c_buffer) * 2 + 0x3 + 1 | ||
| 220 | char* c_encoded_buffer = <char *>malloc(encoded_length) | ||
| 221 | bytes result | ||
| 222 | |||
| 223 | try: | ||
| 224 | debugserver_encode_string(c_buffer, &c_encoded_buffer, &encoded_length) | ||
| 225 | result = c_encoded_buffer[:encoded_length] | ||
| 226 | return result | ||
| 227 | except BaseError, e: | ||
| 228 | raise | ||
| 229 | finally: | ||
| 230 | free(c_encoded_buffer) | ||
| 231 | |||
| 232 | cpdef bytes decode_string(self, bytes encoded_buffer): | ||
| 233 | cdef: | ||
| 234 | char* c_encoded_buffer = encoded_buffer | ||
| 235 | uint32_t encoded_length = len(c_encoded_buffer) | ||
| 236 | char *c_buffer = <char *>malloc(encoded_length) | ||
| 237 | bytes result | ||
| 238 | |||
| 239 | try: | ||
| 240 | debugserver_decode_string(c_encoded_buffer, encoded_length, &c_buffer) | ||
| 241 | result = c_buffer | ||
| 242 | return result | ||
| 243 | except BaseError, e: | ||
| 244 | raise | ||
| 245 | finally: | ||
| 246 | 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) | ||
