| cdef class BaseError(Exception): |
| def __cinit__(self, int16_t errcode): |
| self._c_errcode = errcode |
| |
| def __nonzero__(self): |
| return self._c_errcode != 0 |
| |
| property message: |
| def __get__(self): |
| if self._c_errcode in self._lookup_table: |
| return self._lookup_table[self._c_errcode] |
| else: |
| return "Unknown error ({0})".format(self._c_errcode) |
| |
| property code: |
| def __get__(self): |
| return self._c_errcode |
| |
| def __str__(self): |
| return '%s (%s)' % (self.message, self.code) |
| |
| def __repr__(self): |
| return self.__str__() |
| |
| cdef class Base: |
| cdef inline int handle_error(self, int16_t ret) except -1: |
| if ret == 0: |
| return 0 |
| cdef BaseError err = self._error(ret) |
| raise err |
| |
| cdef BaseError _error(self, int16_t ret): pass |
| |
| cdef extern from "libimobiledevice/libimobiledevice.h": |
| ctypedef enum idevice_error_t: |
| IDEVICE_E_SUCCESS = 0 |
| IDEVICE_E_INVALID_ARG = -1 |
| IDEVICE_E_UNKNOWN_ERROR = -2 |
| IDEVICE_E_NO_DEVICE = -3 |
| IDEVICE_E_NOT_ENOUGH_DATA = -4 |
| IDEVICE_E_SSL_ERROR = -6 |
| IDEVICE_E_TIMEOUT = -7 |
| cdef enum idevice_options: |
| IDEVICE_LOOKUP_USBMUX = 1 << 1 |
| IDEVICE_LOOKUP_NETWORK = 1 << 2 |
| IDEVICE_LOOKUP_PREFER_NETWORK = 1 << 3 |
| ctypedef void (*idevice_event_cb_t) (const_idevice_event_t event, void *user_data) |
| cdef extern idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data) |
| cdef extern idevice_error_t idevice_event_unsubscribe() |
| idevice_error_t idevice_get_device_list(char ***devices, int *count) |
| idevice_error_t idevice_device_list_free(char **devices) |
| void idevice_set_debug_level(int level) |
| idevice_error_t idevice_new(idevice_t *device, char *udid) |
| idevice_error_t idevice_new_with_options(idevice_t *device, const char *udid, idevice_options options); |
| idevice_error_t idevice_free(idevice_t device) |
| idevice_error_t idevice_get_udid(idevice_t device, char** udid) |
| idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle) |
| idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection) |
| idevice_error_t idevice_disconnect(idevice_connection_t connection) |
| idevice_error_t idevice_connection_send(idevice_connection_t connection, char *data, uint32_t len, uint32_t *sent_bytes) |
| idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) |
| idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) |
| |
| cdef class iDeviceError(BaseError): |
| def __init__(self, *args, **kwargs): |
| self._lookup_table = { |
| IDEVICE_E_SUCCESS: 'Success', |
| IDEVICE_E_INVALID_ARG: 'Invalid argument', |
| IDEVICE_E_UNKNOWN_ERROR: 'Unknown error', |
| IDEVICE_E_NO_DEVICE: 'No device', |
| IDEVICE_E_NOT_ENOUGH_DATA: 'Not enough data', |
| IDEVICE_E_SSL_ERROR: 'SSL Error', |
| IDEVICE_E_TIMEOUT: 'Connection timeout' |
| } |
| BaseError.__init__(self, *args, **kwargs) |
| |
| def set_debug_level(int level): |
| idevice_set_debug_level(level) |
| |
| cdef class iDeviceEvent: |
| def __init__(self, *args, **kwargs): |
| raise TypeError("iDeviceEvent cannot be instantiated") |
| |
| def __str__(self): |
| return 'iDeviceEvent: %s (%s)' % (self.event == IDEVICE_DEVICE_ADD and 'Add' or 'Remove', self.udid) |
| |
| property event: |
| def __get__(self): |
| return self._c_event.event |
| property udid: |
| def __get__(self): |
| return self._c_event.udid |
| property conn_type: |
| def __get__(self): |
| return self._c_event.conn_type |
| |
| cdef void idevice_event_cb(const_idevice_event_t c_event, void *user_data) with gil: |
| cdef iDeviceEvent event = iDeviceEvent.__new__(iDeviceEvent) |
| event._c_event = c_event |
| (<object>user_data)(event) |
| |
| def event_subscribe(object callback): |
| cdef iDeviceError err = iDeviceError(idevice_event_subscribe(idevice_event_cb, <void*>callback)) |
| if err: raise err |
| |
| def event_unsubscribe(): |
| cdef iDeviceError err = iDeviceError(idevice_event_unsubscribe()) |
| if err: raise err |
| |
| def get_device_list(): |
| cdef: |
| char** devices = NULL |
| int count |
| list result |
| bytes device |
| iDeviceError err = iDeviceError(idevice_get_device_list(&devices, &count)) |
| |
| if err: |
| if devices != NULL: |
| idevice_device_list_free(devices) |
| raise err |
| |
| result = [] |
| for i from 0 <= i < count: |
| device = devices[i] |
| result.append(device) |
| |
| err = iDeviceError(idevice_device_list_free(devices)) |
| if err: raise err |
| return result |
| |
| cdef class iDeviceConnection(Base): |
| def __init__(self, *args, **kwargs): |
| raise TypeError("iDeviceConnection cannot be instantiated. Please use iDevice.connect()") |
| |
| cpdef bytes receive_timeout(self, uint32_t max_len, unsigned int timeout): |
| cdef: |
| uint32_t bytes_received |
| char* c_data = <char *>malloc(max_len) |
| bytes result |
| |
| try: |
| self.handle_error(idevice_connection_receive_timeout(self._c_connection, c_data, max_len, &bytes_received, timeout)) |
| result = c_data[:bytes_received] |
| return result |
| except BaseError, e: |
| raise |
| finally: |
| free(c_data) |
| |
| cpdef bytes receive(self, max_len): |
| cdef: |
| uint32_t bytes_received |
| char* c_data = <char *>malloc(max_len) |
| bytes result |
| |
| try: |
| self.handle_error(idevice_connection_receive(self._c_connection, c_data, max_len, &bytes_received)) |
| result = c_data[:bytes_received] |
| return result |
| except BaseError, e: |
| raise |
| finally: |
| free(c_data) |
| |
| cpdef disconnect(self): |
| cdef idevice_error_t err |
| err = idevice_disconnect(self._c_connection) |
| self.handle_error(err) |
| |
| cdef BaseError _error(self, int16_t ret): |
| return iDeviceError(ret) |
| |
| from libc.stdlib cimport * |
| |
| cdef class iDevice(Base): |
| def __cinit__(self, object udid=None, *args, **kwargs): |
| cdef char* c_udid = NULL |
| if isinstance(udid, (str, bytes)): |
| c_udid = <bytes>udid |
| elif udid is not None: |
| raise TypeError("iDevice's constructor takes a string or None as the udid argument") |
| self.handle_error(idevice_new(&self._c_dev, c_udid)) |
| |
| def __dealloc__(self): |
| if self._c_dev is not NULL: |
| self.handle_error(idevice_free(self._c_dev)) |
| |
| cdef BaseError _error(self, int16_t ret): |
| return iDeviceError(ret) |
| |
| cpdef iDeviceConnection connect(self, uint16_t port): |
| cdef: |
| idevice_error_t err |
| idevice_connection_t c_conn = NULL |
| iDeviceConnection conn |
| err = idevice_connect(self._c_dev, port, &c_conn) |
| try: |
| self.handle_error(err) |
| |
| conn = iDeviceConnection.__new__(iDeviceConnection) |
| conn._c_connection = c_conn |
| |
| return conn |
| except Exception, e: |
| if c_conn != NULL: |
| idevice_disconnect(c_conn) |
| |
| property udid: |
| def __get__(self): |
| cdef: |
| char* udid |
| idevice_error_t err |
| err = idevice_get_udid(self._c_dev, &udid) |
| try: |
| self.handle_error(err) |
| return udid |
| except Exception, e: |
| if udid != NULL: |
| free(udid) |
| property handle: |
| def __get__(self): |
| cdef uint32_t handle |
| self.handle_error(idevice_get_handle(self._c_dev, &handle)) |
| return handle |
| |
| cdef extern from *: |
| ctypedef char* const_char_ptr "const char*" |
| |
| cdef class BaseService(Base): |
| __service_name__ = None |
| |
| cdef class PropertyListService(BaseService): |
| cpdef send(self, plist.Node node): |
| self.handle_error(self._send(node._c_node)) |
| |
| cpdef object receive(self): |
| cdef: |
| plist.plist_t c_node = NULL |
| int16_t err |
| err = self._receive(&c_node) |
| try: |
| self.handle_error(err) |
| |
| return plist.plist_t_to_node(c_node) |
| except BaseError, e: |
| if c_node != NULL: |
| plist.plist_free(c_node) |
| raise |
| |
| cpdef object receive_with_timeout(self, int timeout_ms): |
| cdef: |
| plist.plist_t c_node = NULL |
| int16_t err |
| err = self._receive_with_timeout(&c_node, timeout_ms) |
| try: |
| self.handle_error(err) |
| |
| return plist.plist_t_to_node(c_node) |
| except BaseError, e: |
| if c_node != NULL: |
| plist.plist_free(c_node) |
| raise |
| |
| cdef int16_t _send(self, plist.plist_t node): |
| raise NotImplementedError("send is not implemented") |
| |
| cdef int16_t _receive(self, plist.plist_t* c_node): |
| raise NotImplementedError("receive is not implemented") |
| |
| cdef int16_t _receive_with_timeout(self, plist.plist_t* c_node, int timeout_ms): |
| raise NotImplementedError("receive_with_timeout is not implemented") |
| |
| cdef class DeviceLinkService(PropertyListService): |
| pass |
| |
| include "lockdown.pxi" |
| include "mobilesync.pxi" |
| include "notification_proxy.pxi" |
| include "sbservices.pxi" |
| include "mobilebackup.pxi" |
| include "mobilebackup2.pxi" |
| include "afc.pxi" |
| include "file_relay.pxi" |
| include "screenshotr.pxi" |
| include "installation_proxy.pxi" |
| include "mobile_image_mounter.pxi" |
| include "webinspector.pxi" |
| include "heartbeat.pxi" |
| include "diagnostics_relay.pxi" |
| include "misagent.pxi" |
| include "house_arrest.pxi" |
| include "restore.pxi" |
| include "debugserver.pxi" |