/* swig.i */ %module imobiledevice %feature("autodoc", "1"); %{ /* Includes the header in the wrapper code */ #include #include #include #include #include #include #include "../src/debug.h" typedef struct { idevice_t dev; } idevice; typedef struct { idevice* dev; lockdownd_client_t client; } Lockdownd; typedef struct { idevice* dev; mobilesync_client_t client; } MobileSync; typedef struct { idevice* dev; np_client_t client; } NotificationProxy; //now declare funtions to handle creation and deletion of objects static void my_delete_idevice(idevice* dev) { if (dev) { idevice_free(dev->dev); free(dev); } } static Lockdownd* my_new_Lockdownd(idevice* device) { if (!device) return NULL; Lockdownd* client = (Lockdownd*) malloc(sizeof(Lockdownd)); client->dev = device; client->client = NULL; if (LOCKDOWN_E_SUCCESS == lockdownd_client_new_with_handshake(device->dev , &(client->client), NULL)) { return client; } else { free(client); return NULL; } } static void my_delete_Lockdownd(Lockdownd* lckd) { if (lckd) { lockdownd_client_free(lckd->client); free(lckd); } } static MobileSync* my_new_MobileSync(Lockdownd* lckd) { if (!lckd || !lckd->dev) return NULL; MobileSync* client = NULL; uint16_t port = 0; if (LOCKDOWN_E_SUCCESS == lockdownd_start_service(lckd->client, "com.apple.mobilesync", &port)) { client = (MobileSync*) malloc(sizeof(MobileSync)); client->dev = lckd->dev; client->client = NULL; mobilesync_client_new(lckd->dev->dev, port, &(client->client)); } return client; } static NotificationProxy* my_new_NotificationProxy(Lockdownd* lckd) { if (!lckd || !lckd->dev) return NULL; NotificationProxy* client = NULL; uint16_t port = 0; if (LOCKDOWN_E_SUCCESS == lockdownd_start_service(lckd->client, "com.apple.mobile.notification_proxy", &port)) { client = (NotificationProxy*) malloc(sizeof(NotificationProxy)); client->dev = lckd->dev; client->client = NULL; np_client_new(lckd->dev->dev, port, &(client->client)); } return client; } static PList::Node* new_node_from_plist(plist_t node) { PList::Node* ret = NULL; plist_type subtype = plist_get_node_type(node); switch(subtype) { case PLIST_DICT: ret = new PList::Dictionary(node); break; case PLIST_ARRAY: ret = new PList::Array(node); break; case PLIST_BOOLEAN: ret = new PList::Boolean(node); break; case PLIST_UINT: ret = new PList::Integer(node); break; case PLIST_REAL: ret = new PList::Real(node); break; case PLIST_STRING: ret = new PList::String(node); break; case PLIST_DATE: ret = new PList::Date(node); break; case PLIST_DATA: ret = new PList::Data(node); break; default: break; } return ret; } #ifdef SWIGPYTHON static void NotificationProxyPythonCallback(const char *notification, void* user_data) { PyObject *func, *arglist; func = (PyObject *) user_data; arglist = Py_BuildValue("(s)",notification); PyEval_CallObject(func, arglist); Py_DECREF(arglist); } #endif %} /* Parse the header file to generate wrappers */ %include "stdint.i" %include "cstring.i" %include "plist/swig/plist.i" /* This needs to be here since if it's after * the structs, SWIG won't pick it up for %extend */ #ifdef SWIGPYTHON %typemap(in) (PyObject *pyfunc) { if (!PyCallable_Check($input)) { PyErr_SetString(PyExc_TypeError, "Need a callable object!"); return NULL; } $1 = $input; } %typemap(in) (const char **string_list) { /* Check if it's a list */ if (PyList_Check($input)) { int size = PyList_Size($input); int i = 0; $1 = (char **) malloc((size+1)*sizeof(char *)); for (i = 0; i < size; i++) { PyObject *o = PyList_GetItem($input,i); if (PyString_Check(o)) { $1[i] = PyString_AsString(PyList_GetItem($input,i)); } else { PyErr_SetString(PyExc_TypeError,"List must contain strings"); free($1); return NULL; } } $1[i] = 0; } else if (PyTuple_Check($input)) { int size = PyTuple_Size($input); int i = 0; $1 = (char **) malloc((size+1)*sizeof(char *)); for (i = 0; i < size; i++) { PyObject *o = PyTuple_GetItem($input,i); if (PyString_Check(o)) { $1[i] = PyString_AsString(PyTuple_GetItem($input,i)); } else { PyErr_SetString(PyExc_TypeError,"List must contain strings"); free($1); return NULL; } } $1[i] = 0; } else { PyErr_SetString(PyExc_TypeError, "not a list or tuple"); return NULL; } } %typemap(freearg) (const char **string_list) { free((char *) $1); } #endif typedef struct { idevice_t dev; } idevice; typedef struct { idevice* dev; lockdownd_client_t client; } Lockdownd; typedef struct { idevice* dev; mobilesync_client_t client; } MobileSync; typedef struct { idevice* dev; np_client_t client; } NotificationProxy; %extend idevice { // Attach these functions to struct idevice idevice() { idevice* device = (idevice*) malloc(sizeof(idevice)); device->dev = NULL; return device; } ~idevice() { my_delete_idevice($self); } void set_debug_level(int level) { idevice_set_debug_level(level); } int init_device_by_uuid(char* uuid) { if (IDEVICE_E_SUCCESS == idevice_new(&($self->dev), uuid)) return 1; return 0; } int init_device() { if (IDEVICE_E_SUCCESS == idevice_new(&($self->dev), NULL)) return 1; return 0; } %newobject get_uuid; char* get_uuid(){ char* uuid = NULL; idevice_get_uuid($self->dev, &uuid); return uuid; } Lockdownd* get_lockdown_client() { return my_new_Lockdownd($self); } }; %extend Lockdownd { // Attach these functions to struct Lockdownd Lockdownd(idevice* device) { return my_new_Lockdownd(device); } ~Lockdownd() { my_delete_Lockdownd($self); } void send(PList::Node* node) { lockdownd_send($self->client, node->GetPlist()); } PList::Node* receive() { plist_t node = NULL; lockdownd_receive($self->client, &node); return new_node_from_plist(node); } MobileSync* get_mobilesync_client() { return my_new_MobileSync($self); } NotificationProxy* get_notification_proxy_client() { return my_new_NotificationProxy($self); } }; %extend MobileSync { // Attach these functions to struct MobileSync MobileSync(Lockdownd* lckd) { return my_new_MobileSync(lckd); } ~MobileSync() { mobilesync_client_free($self->client); free($self); } void send(PList::Node* node) { mobilesync_send($self->client, node->GetPlist()); } PList::Node* receive() { plist_t node = NULL; mobilesync_receive($self->client, &node); return new_node_from_plist(node); } }; #define NP_SYNC_WILL_START "com.apple.itunes-mobdev.syncWillStart" #define NP_SYNC_DID_START "com.apple.itunes-mobdev.syncDidStart" #define NP_SYNC_DID_FINISH "com.apple.itunes-mobdev.syncDidFinish" #define NP_SYNC_LOCK_REQUEST "com.apple.itunes-mobdev.syncLockRequest" %extend NotificationProxy { NotificationProxy(Lockdownd* lckd) { return my_new_NotificationProxy(lckd); } ~NotificationProxy() { np_client_free($self->client); free($self); } int16_t post_notification(const char* notification) { return np_post_notification($self->client, notification); } int16_t observe_notification(const char* notification) { return np_observe_notification($self->client, notification); } int16_t observe_notifications(const char** string_list) { return np_observe_notifications($self->client, string_list); } }; #ifdef SWIGPYTHON %extend NotificationProxy { int16_t set_callback(PyObject *pyfunc) { int16_t res; res = np_set_notify_callback($self->client, NotificationProxyPythonCallback, (void *) pyfunc); Py_INCREF(pyfunc); return res; } }; #endif