From bea5efe442daeab05d5d7a2e9d9e7b934ba6e684 Mon Sep 17 00:00:00 2001 From: Bryan Forbes Date: Fri, 9 Apr 2010 16:52:30 -0500 Subject: Implemented hierarchy suggested by Martin S. Implemented new BaseService constructors. Moved LockdownClient to lockdown.pxi. Implemented more of the afc interface. --- cython/Makefile.am | 1 + cython/afc.pxi | 155 +++++++++++++++++++----- cython/file_relay.pxi | 11 +- cython/imobiledevice.pxd | 39 +++++- cython/imobiledevice.pyx | 117 +++++------------- cython/installation_proxy.pxi | 9 +- cython/lockdown.pxi | 254 ++++++++++++++++++++++++++++++++++++++++ cython/mobile_image_mounter.pxi | 11 +- cython/mobilebackup.pxi | 11 +- cython/mobilesync.pxi | 11 +- cython/notification_proxy.pxi | 9 +- cython/property_list_client.pxi | 3 +- cython/sbservices.pxi | 19 +-- cython/screenshotr.pxi | 9 +- 14 files changed, 472 insertions(+), 187 deletions(-) create mode 100644 cython/lockdown.pxi diff --git a/cython/Makefile.am b/cython/Makefile.am index b1dea79..a8e39d4 100644 --- a/cython/Makefile.am +++ b/cython/Makefile.am @@ -9,6 +9,7 @@ BUILT_SOURCES = imobiledevice.c PXDINCLUDES = imobiledevice.pxd stdint.pxi $(CYTHON_PLIST_INCLUDE_DIR)/plist.pxd PXIINCLUDES = \ stdint.pxi \ + lockdown.pxi \ mobilesync.pxi \ notification_proxy.pxi \ sbservices.pxi \ diff --git a/cython/afc.pxi b/cython/afc.pxi index 1e2617a..ff5c2b0 100644 --- a/cython/afc.pxi +++ b/cython/afc.pxi @@ -51,6 +51,13 @@ cdef extern from "libimobiledevice/afc.h": afc_error_t afc_get_device_info(afc_client_t client, char ***infos) afc_error_t afc_read_directory(afc_client_t client, char *dir, char ***list) afc_error_t afc_get_file_info(afc_client_t client, char *filename, char ***infolist) + afc_error_t afc_remove_path(afc_client_t client, char *path) + afc_error_t afc_rename_path(afc_client_t client, char *f, char *to) + afc_error_t afc_make_directory(afc_client_t client, char *dir) + afc_error_t afc_truncate(afc_client_t client, char *path, uint64_t newsize) + afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, char *target, char *linkname) + afc_error_t afc_set_file_time(afc_client_t client, char *path, uint64_t mtime) + afc_error_t afc_file_open(afc_client_t client, char *filename, afc_file_mode_t file_mode, uint64_t *handle) afc_error_t afc_file_close(afc_client_t client, uint64_t handle) afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation) @@ -59,12 +66,6 @@ cdef extern from "libimobiledevice/afc.h": afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence) afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position) afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize) - afc_error_t afc_remove_path(afc_client_t client, char *path) - afc_error_t afc_rename_path(afc_client_t client, char *f, char *to) - afc_error_t afc_make_directory(afc_client_t client, char *dir) - afc_error_t afc_truncate(afc_client_t client, char *path, uint64_t newsize) - afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, char *target, char *linkname) - afc_error_t afc_set_file_time(afc_client_t client, char *path, uint64_t mtime) cdef class AfcError(BaseError): def __init__(self, *args, **kwargs): @@ -100,19 +101,55 @@ cdef class AfcError(BaseError): } BaseError.__init__(self, *args, **kwargs) -cdef class AfcClient(Base): +# forward declaration of AfcClient +cdef class AfcClient(BaseService) + +cdef class AfcFile(Base): + cdef uint64_t _c_handle + cdef AfcClient _client + cdef bytes _filename + + def __init__(self, *args, **kwargs): + raise TypeError("AfcFile cannot be instantiated") + + cpdef close(self): + self.handle_error(afc_file_close(self._client._c_client, self._c_handle)) + + cpdef seek(self, int64_t offset, int whence): + self.handle_error(afc_file_seek(self._client._c_client, self._c_handle, offset, whence)) + + cpdef uint64_t tell(self): + cdef uint64_t position + self.handle_error(afc_file_tell(self._client._c_client, self._c_handle, &position)) + return position + + cpdef truncate(self, uint64_t newsize): + self.handle_error(afc_file_truncate(self._client._c_client, self._c_handle, newsize)) + + cpdef uint32_t write(self, bytes data): + cdef: + uint32_t bytes_written + char* c_data = data + try: + self.handle_error(afc_file_write(self._client._c_client, self._c_handle, c_data, len(data), &bytes_written)) + except BaseError, e: + raise + finally: + free(c_data) + + return bytes_written + + cdef inline BaseError _error(self, int16_t ret): + return AfcError(ret) + +cdef class AfcClient(BaseService): + __service_name__ = "com.apple.afc" cdef afc_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd afc_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.afc") err = afc_client_new(dev._c_dev, port, &(self._c_client)) self.handle_error(err) @@ -133,13 +170,18 @@ cdef class AfcClient(Base): int i = 0 list result = [] err = afc_get_device_info(self._c_client, &infos) - self.handle_error(err) - while infos[i]: - info = infos[i] - result.append(info) - free(infos[i]) - i = i + 1 - free(infos) + try: + self.handle_error(err) + except BaseError, e: + raise + finally: + if infos != NULL: + while infos[i]: + info = infos[i] + result.append(info) + free(infos[i]) + i = i + 1 + free(infos) return result @@ -151,12 +193,69 @@ cdef class AfcClient(Base): int i = 0 list result = [] err = afc_read_directory(self._c_client, directory, &dir_list) - self.handle_error(err) - while dir_list[i]: - f = dir_list[i] - result.append(f) - free(dir_list[i]) - i = i + 1 - free(dir_list) + try: + self.handle_error(err) + except BaseError, e: + raise + finally: + if dir_list != NULL: + while dir_list[i]: + f = dir_list[i] + result.append(f) + free(dir_list[i]) + i = i + 1 + free(dir_list) + + return result + + cpdef AfcFile open(self, bytes filename): + cdef: + str mode = 'r' + afc_file_mode_t c_mode + uint64_t handle + AfcFile f + if mode == 'r': + c_mode = AFC_FOPEN_RDONLY + self.handle_error(afc_file_open(self._c_client, filename, c_mode, &handle)) + f = AfcFile.__new__(AfcFile) + f._c_handle = handle + f._client = self + f._filename = filename + + return f + + cpdef get_file_info(self, bytes path): + cdef: + list result + char** c_result + int i = 0 + bytes info + try: + self.handle_error(afc_get_file_info(self._c_client, path, &c_result)) + except BaseError, e: + raise + finally: + if c_result != NULL: + while c_result[i]: + info = c_result[i] + result.append(info) + free(c_result[i]) + i = i + 1 + free(c_result) return result + + cpdef remove_path(self, bytes path): + self.handle_error(afc_remove_path(self._c_client, path)) + + cpdef rename_path(self, bytes f, bytes t): + self.handle_error(afc_rename_path(self._c_client, f, t)) + + cpdef make_directory(self, bytes d): + self.handle_error(afc_make_directory(self._c_client, d)) + + cpdef truncate(self, bytes path, uint64_t newsize): + self.handle_error(afc_truncate(self._c_client, path, newsize)) + + cpdef set_file_time(self, bytes path, uint64_t mtime): + self.handle_error(afc_set_file_time(self._c_client, path, mtime)) diff --git a/cython/file_relay.pxi b/cython/file_relay.pxi index 05c99f5..db9932a 100644 --- a/cython/file_relay.pxi +++ b/cython/file_relay.pxi @@ -33,19 +33,14 @@ cdef class FileRelayError(BaseError): cimport stdlib -cdef class FileRelayClient(Base): +cdef class FileRelayClient(PropertyListService): + __service_name__ = "com.apple.mobile.file_relay" cdef file_relay_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd file_relay_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.mobile.file_relay") err = file_relay_client_new(dev._c_dev, port, &self._c_client) self.handle_error(err) diff --git a/cython/imobiledevice.pxd b/cython/imobiledevice.pxd index 6bf75af..a699138 100644 --- a/cython/imobiledevice.pxd +++ b/cython/imobiledevice.pxd @@ -45,14 +45,47 @@ cdef class iDevice(Base): cpdef iDeviceConnection connect(self, uint16_t port) -cdef class LockdownError(BaseError): pass +cdef class BaseService(Base): + pass + +cdef class PropertyListService(BaseService): + cpdef send(self, plist.Node node) + cpdef object receive(self) + cdef inline int16_t _send(self, plist.plist_t node) + cdef inline int16_t _receive(self, plist.plist_t* c_node) cdef extern from "libimobiledevice/lockdown.h": cdef struct lockdownd_client_private: pass ctypedef lockdownd_client_private *lockdownd_client_t + cdef struct lockdownd_pair_record: + char *device_certificate + char *host_certificate + char *host_id + char *root_certificate + ctypedef lockdownd_pair_record *lockdownd_pair_record_t + +cdef class LockdownError(BaseError): pass + +cdef class LockdownPairRecord: + cdef lockdownd_pair_record_t _c_record -cdef class LockdownClient(Base): +cdef class LockdownClient(PropertyListService): cdef lockdownd_client_t _c_client - cpdef int start_service(self, bytes service) + cdef readonly iDevice device + + cpdef bytes query_type(self) + cpdef plist.Node get_value(self, bytes domain=*, bytes key=*) + cpdef set_value(self, bytes domain, bytes key, object value) + cpdef remove_value(self, bytes domain, bytes key) + cpdef uint16_t start_service(self, object service) + cpdef object get_service_client(self, object service_class) + cpdef tuple start_session(self, bytes host_id) + cpdef stop_session(self, bytes session_id) + cpdef pair(self, object pair_record=*) + cpdef validate_pair(self, object pair_record=*) + cpdef unpair(self, object pair_record=*) + cpdef activate(self, plist.Node activation_record) + cpdef deactivate(self) + cpdef enter_recovery(self) cpdef goodbye(self) diff --git a/cython/imobiledevice.pyx b/cython/imobiledevice.pyx index b57db04..77a7a3a 100644 --- a/cython/imobiledevice.pyx +++ b/cython/imobiledevice.pyx @@ -170,99 +170,42 @@ cdef class iDevice(Base): self.handle_error(idevice_get_handle(self._c_dev, &handle)) return handle -cdef extern from "libimobiledevice/lockdown.h": - cdef struct lockdownd_client_private: - pass - ctypedef lockdownd_client_private *lockdownd_client_t - ctypedef enum lockdownd_error_t: - LOCKDOWN_E_SUCCESS = 0 - LOCKDOWN_E_INVALID_ARG = -1 - LOCKDOWN_E_INVALID_CONF = -2 - LOCKDOWN_E_PLIST_ERROR = -3 - LOCKDOWN_E_PAIRING_FAILED = -4 - LOCKDOWN_E_SSL_ERROR = -5 - LOCKDOWN_E_DICT_ERROR = -6 - LOCKDOWN_E_START_SERVICE_FAILED = -7 - LOCKDOWN_E_NOT_ENOUGH_DATA = -8 - LOCKDOWN_E_SET_VALUE_PROHIBITED = -9 - LOCKDOWN_E_GET_VALUE_PROHIBITED = -10 - LOCKDOWN_E_REMOVE_VALUE_PROHIBITED = -11 - LOCKDOWN_E_MUX_ERROR = -12 - LOCKDOWN_E_ACTIVATION_FAILED = -13 - LOCKDOWN_E_PASSWORD_PROTECTED = -14 - LOCKDOWN_E_NO_RUNNING_SESSION = -15 - LOCKDOWN_E_INVALID_HOST_ID = -16 - LOCKDOWN_E_INVALID_SERVICE = -17 - LOCKDOWN_E_INVALID_ACTIVATION_RECORD = -18 - LOCKDOWN_E_UNKNOWN_ERROR = -256 - - lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, char *label) - lockdownd_error_t lockdownd_client_free(lockdownd_client_t client) - lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, char *service, uint16_t *port) - -cdef class LockdownError(BaseError): - def __init__(self, *args, **kwargs): - self._lookup_table = { - LOCKDOWN_E_SUCCESS: "Success", - LOCKDOWN_E_INVALID_ARG: "Invalid argument", - LOCKDOWN_E_INVALID_CONF: "Invalid configuration", - LOCKDOWN_E_PLIST_ERROR: "Property list error", - LOCKDOWN_E_PAIRING_FAILED: "Pairing failed", - LOCKDOWN_E_SSL_ERROR: "SSL error", - LOCKDOWN_E_DICT_ERROR: "Dict error", - LOCKDOWN_E_START_SERVICE_FAILED: "Start service failed", - LOCKDOWN_E_NOT_ENOUGH_DATA: "Not enough data", - LOCKDOWN_E_SET_VALUE_PROHIBITED: "Set value prohibited", - LOCKDOWN_E_GET_VALUE_PROHIBITED: "Get value prohibited", - LOCKDOWN_E_REMOVE_VALUE_PROHIBITED: "Remove value prohibited", - LOCKDOWN_E_MUX_ERROR: "MUX Error", - LOCKDOWN_E_ACTIVATION_FAILED: "Activation failed", - LOCKDOWN_E_PASSWORD_PROTECTED: "Password protected", - LOCKDOWN_E_NO_RUNNING_SESSION: "No running session", - LOCKDOWN_E_INVALID_HOST_ID: "Invalid host ID", - LOCKDOWN_E_INVALID_SERVICE: "Invalid service", - LOCKDOWN_E_INVALID_ACTIVATION_RECORD: "Invalid activation record", - LOCKDOWN_E_UNKNOWN_ERROR: "Unknown error" - } - BaseError.__init__(self, *args, **kwargs) +cdef extern from *: + ctypedef char* const_char_ptr "const char*" + void free(void *ptr) + void plist_free(plist.plist_t node) + +cdef class BaseService(Base): + __service_name__ = None -cdef class LockdownClient(Base): - def __cinit__(self, iDevice device not None, bytes label="", *args, **kwargs): +cdef class PropertyListService(BaseService): + cpdef send(self, plist.Node node): + self.handle_error(self._send(node._c_node)) + + cpdef object receive(self): cdef: - iDevice dev = device - lockdownd_error_t err - char* c_label = NULL - if label: - c_label = label - err = lockdownd_client_new_with_handshake(dev._c_dev, &(self._c_client), c_label) - self.handle_error(err) - - def __dealloc__(self): - cdef lockdownd_error_t err - if self._c_client is not NULL: - err = lockdownd_client_free(self._c_client) + plist.plist_t c_node = NULL + int16_t err + err = self._receive(&c_node) + try: self.handle_error(err) + except BaseError, e: + if c_node != NULL: + plist_free(c_node) + raise - cdef inline BaseError _error(self, int16_t ret): - return LockdownError(ret) - - cpdef int start_service(self, bytes service): - cdef: - uint16_t port - lockdownd_error_t err - err = lockdownd_start_service(self._c_client, service, &port) - self.handle_error(err) - return port - - cpdef goodbye(self): - pass + return plist.plist_t_to_node(c_node) -cdef extern from *: - ctypedef char* const_char_ptr "const char*" - void free(void *ptr) - void plist_free(plist.plist_t node) + cdef inline int16_t _send(self, plist.plist_t node): + raise NotImplementedError("send is not implemented") + + cdef inline int16_t _receive(self, plist.plist_t* c_node): + raise NotImplementedError("receive is not implemented") + +cdef class DeviceLinkService(PropertyListService): + pass -include "property_list_client.pxi" +include "lockdown.pxi" include "mobilesync.pxi" include "notification_proxy.pxi" include "sbservices.pxi" diff --git a/cython/installation_proxy.pxi b/cython/installation_proxy.pxi index a8083d3..f584cbd 100644 --- a/cython/installation_proxy.pxi +++ b/cython/installation_proxy.pxi @@ -43,18 +43,13 @@ cdef class InstallationProxyError(BaseError): BaseError.__init__(self, *args, **kwargs) cdef class InstallationProxy(Base): + __service_name__ = "com.apple.mobile.installation_proxy" cdef instproxy_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd instproxy_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.mobile.installation_proxy") err = instproxy_client_new(dev._c_dev, port, &self._c_client) self.handle_error(err) diff --git a/cython/lockdown.pxi b/cython/lockdown.pxi new file mode 100644 index 0000000..76f84b1 --- /dev/null +++ b/cython/lockdown.pxi @@ -0,0 +1,254 @@ +cdef extern from "libimobiledevice/lockdown.h": + ctypedef enum lockdownd_error_t: + LOCKDOWN_E_SUCCESS = 0 + LOCKDOWN_E_INVALID_ARG = -1 + LOCKDOWN_E_INVALID_CONF = -2 + LOCKDOWN_E_PLIST_ERROR = -3 + LOCKDOWN_E_PAIRING_FAILED = -4 + LOCKDOWN_E_SSL_ERROR = -5 + LOCKDOWN_E_DICT_ERROR = -6 + LOCKDOWN_E_START_SERVICE_FAILED = -7 + LOCKDOWN_E_NOT_ENOUGH_DATA = -8 + LOCKDOWN_E_SET_VALUE_PROHIBITED = -9 + LOCKDOWN_E_GET_VALUE_PROHIBITED = -10 + LOCKDOWN_E_REMOVE_VALUE_PROHIBITED = -11 + LOCKDOWN_E_MUX_ERROR = -12 + LOCKDOWN_E_ACTIVATION_FAILED = -13 + LOCKDOWN_E_PASSWORD_PROTECTED = -14 + LOCKDOWN_E_NO_RUNNING_SESSION = -15 + LOCKDOWN_E_INVALID_HOST_ID = -16 + LOCKDOWN_E_INVALID_SERVICE = -17 + LOCKDOWN_E_INVALID_ACTIVATION_RECORD = -18 + LOCKDOWN_E_UNKNOWN_ERROR = -256 + + lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, char *label) + lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, char *label) + lockdownd_error_t lockdownd_client_free(lockdownd_client_t client) + + lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **tp) + lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t *value) + lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t value) + lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, char *domain, char *key) + lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, char *service, uint16_t *port) + lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, char *host_id, char **session_id, int *ssl_enabled) + lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, char *session_id) + lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist.plist_t plist) + lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist.plist_t *plist) + lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record) + lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record) + lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record) + lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist.plist_t activation_record) + lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client) + lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client) + lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client) + +cdef class LockdownError(BaseError): + def __init__(self, *args, **kwargs): + self._lookup_table = { + LOCKDOWN_E_SUCCESS: "Success", + LOCKDOWN_E_INVALID_ARG: "Invalid argument", + LOCKDOWN_E_INVALID_CONF: "Invalid configuration", + LOCKDOWN_E_PLIST_ERROR: "Property list error", + LOCKDOWN_E_PAIRING_FAILED: "Pairing failed", + LOCKDOWN_E_SSL_ERROR: "SSL error", + LOCKDOWN_E_DICT_ERROR: "Dict error", + LOCKDOWN_E_START_SERVICE_FAILED: "Start service failed", + LOCKDOWN_E_NOT_ENOUGH_DATA: "Not enough data", + LOCKDOWN_E_SET_VALUE_PROHIBITED: "Set value prohibited", + LOCKDOWN_E_GET_VALUE_PROHIBITED: "Get value prohibited", + LOCKDOWN_E_REMOVE_VALUE_PROHIBITED: "Remove value prohibited", + LOCKDOWN_E_MUX_ERROR: "MUX Error", + LOCKDOWN_E_ACTIVATION_FAILED: "Activation failed", + LOCKDOWN_E_PASSWORD_PROTECTED: "Password protected", + LOCKDOWN_E_NO_RUNNING_SESSION: "No running session", + LOCKDOWN_E_INVALID_HOST_ID: "Invalid host ID", + LOCKDOWN_E_INVALID_SERVICE: "Invalid service", + LOCKDOWN_E_INVALID_ACTIVATION_RECORD: "Invalid activation record", + LOCKDOWN_E_UNKNOWN_ERROR: "Unknown error" + } + BaseError.__init__(self, *args, **kwargs) + +cdef class LockdownPairRecord: + #def __cinit__(self, bytes device_certificate, bytes host_certificate, bytes host_id, bytes root_certificate, *args, **kwargs): + property device_certificate: + def __get__(self): + cdef bytes result = self._c_record.device_certificate + return result + property host_certificate: + def __get__(self): + cdef bytes result = self._c_record.host_certificate + return result + property host_id: + def __get__(self): + cdef bytes result = self._c_record.host_id + return result + property root_certificate: + def __get__(self): + cdef bytes result = self._c_record.root_certificate + return result + +cdef class LockdownClient(PropertyListService): + def __cinit__(self, iDevice device not None, bytes label="", bool handshake=True, *args, **kwargs): + cdef: + iDevice dev = device + lockdownd_error_t err + char* c_label = NULL + if label: + c_label = label + if handshake: + err = lockdownd_client_new_with_handshake(dev._c_dev, &self._c_client, c_label) + else: + err = lockdownd_client_new(dev._c_dev, &self._c_client, c_label) + self.handle_error(err) + + self.device = dev + + def __dealloc__(self): + cdef lockdownd_error_t err + if self._c_client is not NULL: + err = lockdownd_client_free(self._c_client) + self.handle_error(err) + + cpdef bytes query_type(self): + cdef: + lockdownd_error_t err + char* c_type = NULL + bytes result + err = lockdownd_query_type(self._c_client, &c_type) + try: + self.handle_error(err) + except BaseError, e: + raise + finally: + if c_type != NULL: + result = c_type + free(c_type) + + return result + + cpdef plist.Node get_value(self, bytes domain=None, bytes key=None): + cdef: + lockdownd_error_t err + plist.plist_t c_node = NULL + char* c_domain = NULL + char* c_key = NULL + if domain is not None: + c_domain = domain + if key is not None: + c_key = key + err = lockdownd_get_value(self._c_client, c_domain, c_key, &c_node) + try: + self.handle_error(err) + except BaseError, e: + if c_node != NULL: + plist_free(c_node) + raise + + return plist.plist_t_to_node(c_node) + + cpdef set_value(self, bytes domain, bytes key, object value): + cdef plist.plist_t c_node = plist.native_to_plist_t(value) + try: + self.handle_error(lockdownd_set_value(self._c_client, domain, key, c_node)) + except BaseError, e: + raise + finally: + if c_node != NULL: + plist_free(c_node) + + cpdef remove_value(self, bytes domain, bytes key): + self.handle_error(lockdownd_remove_value(self._c_client, domain, key)) + + cpdef uint16_t start_service(self, object service): + cdef: + char* c_service_name = NULL + uint16_t port = 0 + + if hasattr(service, '__service_name__') and \ + service.__service_name__ is not None \ + and isinstance(service.__service_name__, basestring): + c_service_name = service.__service_name__ + elif isinstance(service, basestring): + c_service_name = service + else: + raise TypeError("LockdownClient.start_service() takes a BaseService or string as its first argument") + + try: + self.handle_error(lockdownd_start_service(self._c_client, c_service_name, &port)) + except BaseError, e: + raise + + return port + + cpdef object get_service_client(self, object service_class): + cdef: + uint16_t port = 0 + object result + + if not hasattr(service_class, '__service_name__') and \ + not service_class.__service_name__ is not None \ + and not isinstance(service_class.__service_name__, basestring): + raise TypeError("LockdownClient.get_service_client() takes a BaseService as its first argument") + + port = self.start_service(service_class) + return service_class(self.device, port) + + cpdef tuple start_session(self, bytes host_id): + cdef: + lockdownd_error_t err + char* c_session_id = NULL + bint ssl_enabled + bytes session_id + err = lockdownd_start_session(self._c_client, host_id, &c_session_id, &ssl_enabled) + try: + self.handle_error(err) + except BaseError, e: + raise + finally: + if c_session_id != NULL: + session_id = c_session_id + free(c_session_id) + + return (session_id, ssl_enabled) + + cpdef stop_session(self, bytes session_id): + self.handle_error(lockdownd_stop_session(self._c_client, session_id)) + + cpdef pair(self, object pair_record=None): + cdef lockdownd_pair_record_t c_pair_record = NULL + if pair_record is not None: + c_pair_record = (pair_record)._c_record + self.handle_error(lockdownd_pair(self._c_client, c_pair_record)) + + cpdef validate_pair(self, object pair_record=None): + cdef lockdownd_pair_record_t c_pair_record = NULL + if pair_record is not None: + c_pair_record = (pair_record)._c_record + self.handle_error(lockdownd_validate_pair(self._c_client, c_pair_record)) + + cpdef unpair(self, object pair_record=None): + cdef lockdownd_pair_record_t c_pair_record = NULL + if pair_record is not None: + c_pair_record = (pair_record)._c_record + self.handle_error(lockdownd_unpair(self._c_client, c_pair_record)) + + cpdef activate(self, plist.Node activation_record): + self.handle_error(lockdownd_activate(self._c_client, activation_record._c_node)) + + cpdef deactivate(self): + self.handle_error(lockdownd_deactivate(self._c_client)) + + cpdef enter_recovery(self): + self.handle_error(lockdownd_enter_recovery(self._c_client)) + + cpdef goodbye(self): + self.handle_error(lockdownd_goodbye(self._c_client)) + + cdef inline int16_t _send(self, plist.plist_t node): + return lockdownd_send(self._c_client, node) + + cdef inline int16_t _receive(self, plist.plist_t* node): + return lockdownd_receive(self._c_client, node) + + cdef inline BaseError _error(self, int16_t ret): + return LockdownError(ret) diff --git a/cython/mobile_image_mounter.pxi b/cython/mobile_image_mounter.pxi index 9086f2c..e70cff7 100644 --- a/cython/mobile_image_mounter.pxi +++ b/cython/mobile_image_mounter.pxi @@ -27,19 +27,14 @@ cdef class MobileImageMounterError(BaseError): } BaseError.__init__(self, *args, **kwargs) -cdef class MobileImageMounterClient(Base): +cdef class MobileImageMounterClient(PropertyListService): + __service_name__ = "com.apple.mobile.mobile_image_mounter" cdef mobile_image_mounter_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd mobile_image_mounter_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.mobile.mobile_image_mounter") err = mobile_image_mounter_new(dev._c_dev, port, &self._c_client) self.handle_error(err) diff --git a/cython/mobilebackup.pxi b/cython/mobilebackup.pxi index 330a99d..cb5276e 100644 --- a/cython/mobilebackup.pxi +++ b/cython/mobilebackup.pxi @@ -28,19 +28,14 @@ cdef class MobileBackupError(BaseError): } BaseError.__init__(self, *args, **kwargs) -cdef class MobileBackupClient(PropertyListClient): +cdef class MobileBackupClient(PropertyListService): + __service_name__ = "com.apple.mobilebackup" cdef mobilebackup_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd mobilebackup_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.mobilebackup") err = mobilebackup_client_new(dev._c_dev, port, &self._c_client) self.handle_error(err) diff --git a/cython/mobilesync.pxi b/cython/mobilesync.pxi index d5dacb1..1b36ba7 100644 --- a/cython/mobilesync.pxi +++ b/cython/mobilesync.pxi @@ -28,19 +28,14 @@ cdef class MobileSyncError(BaseError): } BaseError.__init__(self, *args, **kwargs) -cdef class MobileSyncClient(PropertyListClient): +cdef class MobileSyncClient(DeviceLinkService): + __service_name__ = "com.apple.mobilesync" cdef mobilesync_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd mobilesync_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.mobilesync") err = mobilesync_client_new(dev._c_dev, port, &(self._c_client)) self.handle_error(err) diff --git a/cython/notification_proxy.pxi b/cython/notification_proxy.pxi index d5f2d25..cc25f2d 100644 --- a/cython/notification_proxy.pxi +++ b/cython/notification_proxy.pxi @@ -31,18 +31,13 @@ cdef class NotificationProxyError(BaseError): BaseError.__init__(self, *args, **kwargs) cdef class NotificationProxy(Base): + __service_name__ = "com.apple.mobile.notification_proxy" cdef np_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd np_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.mobile.notification_proxy") err = np_client_new(dev._c_dev, port, &self._c_client) self.handle_error(err) diff --git a/cython/property_list_client.pxi b/cython/property_list_client.pxi index 2f9ce76..c137b34 100644 --- a/cython/property_list_client.pxi +++ b/cython/property_list_client.pxi @@ -1,7 +1,6 @@ cdef class PropertyListClient(Base): cpdef send(self, plist.Node node): - cdef plist.Node n = node - self.handle_error(self._send(n._c_node)) + self.handle_error(self._send(node._c_node)) cpdef object receive(self): cdef: diff --git a/cython/sbservices.pxi b/cython/sbservices.pxi index 6eece0a..28aa5a5 100644 --- a/cython/sbservices.pxi +++ b/cython/sbservices.pxi @@ -26,19 +26,13 @@ cdef class SpringboardServicesError(BaseError): BaseError.__init__(self, *args, **kwargs) cdef class SpringboardServicesClient(Base): + __service_name__ = "com.apple.springboardservices" cdef sbservices_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.springboardservices") - err = SpringboardServicesError(sbservices_client_new(dev._c_dev, port, &(self._c_client))) - if err: raise err + self.handle_error(sbservices_client_new(dev._c_dev, port, &self._c_client)) def __dealloc__(self): if self._c_client is not NULL: @@ -52,7 +46,6 @@ cdef class SpringboardServicesClient(Base): def __get__(self): cdef: plist.plist_t c_node = NULL - plist.Node node sbservices_error_t err err = sbservices_get_icon_state(self._c_client, &c_node) try: @@ -61,11 +54,9 @@ cdef class SpringboardServicesClient(Base): if c_node != NULL: plist_free(c_node) raise - node = plist.plist_t_to_node(c_node) - return node + return plist.plist_t_to_node(c_node) def __set__(self, plist.Node newstate not None): - cdef plist.Node node = newstate - self.handle_error(sbservices_set_icon_state(self._c_client, node._c_node)) + self.handle_error(sbservices_set_icon_state(self._c_client, newstate._c_node)) cpdef bytes get_pngdata(self, bytes bundleId): cdef: diff --git a/cython/screenshotr.pxi b/cython/screenshotr.pxi index 92d95b9..d3a896f 100644 --- a/cython/screenshotr.pxi +++ b/cython/screenshotr.pxi @@ -28,18 +28,13 @@ cdef class ScreenshotrError(BaseError): BaseError.__init__(self, *args, **kwargs) cdef class ScreenshotrClient(Base): + __service_name__ = "com.apple.mobile.screenshotr" cdef screenshotr_client_t _c_client - def __cinit__(self, iDevice device not None, LockdownClient lockdown=None, *args, **kwargs): + def __cinit__(self, iDevice device not None, int port, *args, **kwargs): cdef: iDevice dev = device - LockdownClient lckd screenshotr_error_t err - if lockdown is None: - lckd = LockdownClient(dev) - else: - lckd = lockdown - port = lckd.start_service("com.apple.mobile.screenshotr") err = screenshotr_client_new(dev._c_dev, port, &self._c_client) self.handle_error(err) -- cgit v1.1-32-gdbae