diff options
| author | 2009-05-18 22:29:39 +0200 | |
|---|---|---|
| committer | 2009-05-18 18:47:20 -0700 | |
| commit | 8eaac0513bfb238edec22d46320669f5c9c76542 (patch) | |
| tree | 2db842339bf525d67017525bcbd3f4d35181e5ca | |
| parent | dca1758c4f9602fc240c6a7c9ae45839e154d15f (diff) | |
| download | libimobiledevice-8eaac0513bfb238edec22d46320669f5c9c76542.tar.gz libimobiledevice-8eaac0513bfb238edec22d46320669f5c9c76542.tar.bz2 | |
Make use of usbmuxd and remove libusb dependencies
Signed-off-by: Matt Colyer <matt@colyer.name>
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | configure.ac | 4 | ||||
| -rw-r--r-- | dev/Makefile.am | 4 | ||||
| -rw-r--r-- | dev/afccheck.c | 2 | ||||
| -rw-r--r-- | dev/iphoneinfo.c | 6 | ||||
| -rw-r--r-- | dev/main.c | 15 | ||||
| -rw-r--r-- | dev/msyncclient.c | 2 | ||||
| -rw-r--r-- | dev/syslog_relay.c | 25 | ||||
| -rw-r--r-- | include/libiphone/libiphone.h | 22 | ||||
| -rw-r--r-- | src/AFC.c | 75 | ||||
| -rw-r--r-- | src/AFC.h | 4 | ||||
| -rw-r--r-- | src/Makefile.am | 7 | ||||
| -rw-r--r-- | src/MobileSync.c | 25 | ||||
| -rw-r--r-- | src/MobileSync.h | 3 | ||||
| -rw-r--r-- | src/NotificationProxy.c | 47 | ||||
| -rw-r--r-- | src/NotificationProxy.h | 3 | ||||
| -rw-r--r-- | src/iphone.c | 295 | ||||
| -rw-r--r-- | src/iphone.h | 17 | ||||
| -rw-r--r-- | src/lockdown.c | 25 | ||||
| -rw-r--r-- | src/lockdown.h | 4 | ||||
| -rw-r--r-- | src/usbmux.c | 410 | ||||
| -rw-r--r-- | src/usbmux.h | 58 | ||||
| -rw-r--r-- | udev/89-libiphone.rules | 9 | ||||
| -rw-r--r-- | udev/Makefile.am | 4 |
24 files changed, 187 insertions, 881 deletions
diff --git a/Makefile.am b/Makefile.am index a691d73..39ee8e8 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | AUTOMAKE_OPTIONS = foreign | 1 | AUTOMAKE_OPTIONS = foreign |
| 2 | ACLOCAL_AMFLAGS = -I m4 | 2 | ACLOCAL_AMFLAGS = -I m4 |
| 3 | SUBDIRS = src include fdi swig udev $(DEV_SUB) | 3 | SUBDIRS = src include fdi swig $(DEV_SUB) |
| 4 | 4 | ||
| 5 | DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools | 5 | DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools |
| 6 | 6 | ||
diff --git a/configure.ac b/configure.ac index 29dd5f0..50c7d1b 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -20,7 +20,7 @@ AC_PROG_CC | |||
| 20 | AM_PROG_CC_C_O | 20 | AM_PROG_CC_C_O |
| 21 | 21 | ||
| 22 | # Checks for libraries. | 22 | # Checks for libraries. |
| 23 | PKG_CHECK_MODULES(libusb, libusb >= 0.1.12) | 23 | PKG_CHECK_MODULES(libusbmuxd, libusbmuxd >= 0.1.0) |
| 24 | PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1) | 24 | PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1) |
| 25 | PKG_CHECK_MODULES(libgthread2, gthread-2.0 >= 2.14.1) | 25 | PKG_CHECK_MODULES(libgthread2, gthread-2.0 >= 2.14.1) |
| 26 | PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 ) | 26 | PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 ) |
| @@ -95,4 +95,4 @@ if test "$enable_largefile" != no; then | |||
| 95 | fi | 95 | fi |
| 96 | AC_SUBST(LFS_CFLAGS) | 96 | AC_SUBST(LFS_CFLAGS) |
| 97 | 97 | ||
| 98 | AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile udev/Makefile libiphone-1.0.pc) | 98 | AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile libiphone-1.0.pc) |
diff --git a/dev/Makefile.am b/dev/Makefile.am index 8afe2f9..3fa8f8c 100644 --- a/dev/Makefile.am +++ b/dev/Makefile.am | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | INCLUDES = -I$(top_srcdir)/include | 1 | INCLUDES = -I$(top_srcdir)/include |
| 2 | 2 | ||
| 3 | AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) | 3 | AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) |
| 4 | AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) | 4 | AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) |
| 5 | 5 | ||
| 6 | bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneinfo iphonesyslog | 6 | bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneinfo iphonesyslog |
| 7 | 7 | ||
diff --git a/dev/afccheck.c b/dev/afccheck.c index 152a8df..2f7d92c 100644 --- a/dev/afccheck.c +++ b/dev/afccheck.c | |||
| @@ -106,7 +106,7 @@ int main(int argc, char *argv[]) | |||
| 106 | return 1; | 106 | return 1; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | iphone_afc_new_client(phone, 3432, port, &afc); | 109 | iphone_afc_new_client(phone, port, &afc); |
| 110 | 110 | ||
| 111 | //makes sure thread environment is available | 111 | //makes sure thread environment is available |
| 112 | if (!g_thread_supported()) | 112 | if (!g_thread_supported()) |
diff --git a/dev/iphoneinfo.c b/dev/iphoneinfo.c index 4995b9b..409ad2d 100644 --- a/dev/iphoneinfo.c +++ b/dev/iphoneinfo.c | |||
| @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) | |||
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | if (bus_n != -1) { | 65 | /* if (bus_n != -1) { |
| 66 | ret = iphone_get_specific_device(bus_n, dev_n, &phone); | 66 | ret = iphone_get_specific_device(bus_n, dev_n, &phone); |
| 67 | if (ret != IPHONE_E_SUCCESS) { | 67 | if (ret != IPHONE_E_SUCCESS) { |
| 68 | printf("No device found for usb bus %d and dev %d, is it plugged in?\n", bus_n, dev_n); | 68 | printf("No device found for usb bus %d and dev %d, is it plugged in?\n", bus_n, dev_n); |
| @@ -70,13 +70,13 @@ int main(int argc, char *argv[]) | |||
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | else | 72 | else |
| 73 | { | 73 | {*/ |
| 74 | ret = iphone_get_device(&phone); | 74 | ret = iphone_get_device(&phone); |
| 75 | if (ret != IPHONE_E_SUCCESS) { | 75 | if (ret != IPHONE_E_SUCCESS) { |
| 76 | printf("No device found, is it plugged in?\n"); | 76 | printf("No device found, is it plugged in?\n"); |
| 77 | return -1; | 77 | return -1; |
| 78 | } | 78 | } |
| 79 | } | 79 | /* }*/ |
| 80 | 80 | ||
| 81 | if (IPHONE_E_SUCCESS != iphone_lckd_new_client(phone, &control)) { | 81 | if (IPHONE_E_SUCCESS != iphone_lckd_new_client(phone, &control)) { |
| 82 | iphone_free_device(phone); | 82 | iphone_free_device(phone); |
| @@ -42,7 +42,7 @@ void perform_notification(iphone_device_t phone, iphone_lckd_client_t control, c | |||
| 42 | iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &nport); | 42 | iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &nport); |
| 43 | if (nport) { | 43 | if (nport) { |
| 44 | printf("::::::::::::::: np was started ::::::::::::\n"); | 44 | printf("::::::::::::::: np was started ::::::::::::\n"); |
| 45 | iphone_np_new_client(phone, 3555, nport, &np); | 45 | iphone_np_new_client(phone, nport, &np); |
| 46 | if (np) { | 46 | if (np) { |
| 47 | printf("::::::::: PostNotification %s\n", notification); | 47 | printf("::::::::: PostNotification %s\n", notification); |
| 48 | iphone_np_post_notification(np, notification); | 48 | iphone_np_post_notification(np, notification); |
| @@ -98,12 +98,12 @@ int main(int argc, char *argv[]) | |||
| 98 | 98 | ||
| 99 | if (port) { | 99 | if (port) { |
| 100 | iphone_afc_client_t afc = NULL; | 100 | iphone_afc_client_t afc = NULL; |
| 101 | iphone_afc_new_client(phone, 3432, port, &afc); | 101 | iphone_afc_new_client(phone, port, &afc); |
| 102 | if (afc) { | 102 | if (afc) { |
| 103 | iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &npp); | 103 | iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &npp); |
| 104 | if (npp) { | 104 | if (npp) { |
| 105 | printf("Notification Proxy started.\n"); | 105 | printf("Notification Proxy started.\n"); |
| 106 | iphone_np_new_client(phone, 3756, npp, &gnp); | 106 | iphone_np_new_client(phone, npp, &gnp); |
| 107 | } else { | 107 | } else { |
| 108 | printf("ERROR: Notification proxy could not be started.\n"); | 108 | printf("ERROR: Notification proxy could not be started.\n"); |
| 109 | } | 109 | } |
| @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) | |||
| 115 | NULL | 115 | NULL |
| 116 | }; | 116 | }; |
| 117 | iphone_np_observe_notifications(gnp, nspec); | 117 | iphone_np_observe_notifications(gnp, nspec); |
| 118 | //iphone_np_set_notify_callback(gnp, notifier); | 118 | iphone_np_set_notify_callback(gnp, notifier); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | perform_notification(phone, control, NP_SYNC_WILL_START); | 121 | perform_notification(phone, control, NP_SYNC_WILL_START); |
| @@ -209,15 +209,16 @@ int main(int argc, char *argv[]) | |||
| 209 | if (gnp && lockfile) { | 209 | if (gnp && lockfile) { |
| 210 | char *noti; | 210 | char *noti; |
| 211 | 211 | ||
| 212 | /* | ||
| 212 | noti = NULL; | 213 | noti = NULL; |
| 213 | iphone_np_get_notification(gnp, ¬i); | 214 | iphone_np_get_notification(gnp, ¬i); |
| 214 | if (noti) { | 215 | if (noti) { |
| 215 | printf("------> received notification '%s'\n", noti); | 216 | printf("------> received notification '%s'\n", noti); |
| 216 | free(noti); | 217 | free(noti); |
| 217 | } | 218 | }*/ |
| 218 | 219 | ||
| 219 | printf("XXX sleeping\n"); | 220 | printf("XXX sleeping\n"); |
| 220 | for (i = 0; i < 5; i++) { | 221 | /*for (i = 0; i < 5; i++) { |
| 221 | noti = NULL; | 222 | noti = NULL; |
| 222 | printf("--- getting notification\n"); | 223 | printf("--- getting notification\n"); |
| 223 | iphone_np_get_notification(gnp, ¬i); | 224 | iphone_np_get_notification(gnp, ¬i); |
| @@ -229,6 +230,8 @@ int main(int argc, char *argv[]) | |||
| 229 | } | 230 | } |
| 230 | sleep(1); | 231 | sleep(1); |
| 231 | } | 232 | } |
| 233 | */ | ||
| 234 | sleep(5); | ||
| 232 | 235 | ||
| 233 | //perform_notification(phone, control, NP_SYNC_DID_FINISH); | 236 | //perform_notification(phone, control, NP_SYNC_DID_FINISH); |
| 234 | 237 | ||
diff --git a/dev/msyncclient.c b/dev/msyncclient.c index 804e1ed..e3bb0c2 100644 --- a/dev/msyncclient.c +++ b/dev/msyncclient.c | |||
| @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) | |||
| 51 | 51 | ||
| 52 | if (port) { | 52 | if (port) { |
| 53 | iphone_msync_client_t msync = NULL; | 53 | iphone_msync_client_t msync = NULL; |
| 54 | iphone_msync_new_client(phone, 3432, port, &msync); | 54 | iphone_msync_new_client(phone, port, &msync); |
| 55 | if (msync) { | 55 | if (msync) { |
| 56 | iphone_msync_get_all_contacts(msync); | 56 | iphone_msync_get_all_contacts(msync); |
| 57 | iphone_msync_free_client(msync); | 57 | iphone_msync_free_client(msync); |
diff --git a/dev/syslog_relay.c b/dev/syslog_relay.c index 56cf56c..35c684a 100644 --- a/dev/syslog_relay.c +++ b/dev/syslog_relay.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <usb.h> | 27 | #include <usb.h> |
| 28 | 28 | ||
| 29 | #include <libiphone/libiphone.h> | 29 | #include <libiphone/libiphone.h> |
| 30 | #include <usbmuxd.h> | ||
| 30 | 31 | ||
| 31 | static int quit_flag = 0; | 32 | static int quit_flag = 0; |
| 32 | 33 | ||
| @@ -78,7 +79,7 @@ int main(int argc, char *argv[]) | |||
| 78 | } | 79 | } |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | if (bus_n != -1) { | 82 | /* if (bus_n != -1) { |
| 82 | ret = iphone_get_specific_device(bus_n, dev_n, &phone); | 83 | ret = iphone_get_specific_device(bus_n, dev_n, &phone); |
| 83 | if (ret != IPHONE_E_SUCCESS) { | 84 | if (ret != IPHONE_E_SUCCESS) { |
| 84 | printf("No device found for usb bus %d and dev %d, is it plugged in?\n", bus_n, dev_n); | 85 | printf("No device found for usb bus %d and dev %d, is it plugged in?\n", bus_n, dev_n); |
| @@ -86,13 +87,13 @@ int main(int argc, char *argv[]) | |||
| 86 | } | 87 | } |
| 87 | } | 88 | } |
| 88 | else | 89 | else |
| 89 | { | 90 | {*/ |
| 90 | ret = iphone_get_device(&phone); | 91 | ret = iphone_get_device(&phone); |
| 91 | if (ret != IPHONE_E_SUCCESS) { | 92 | if (ret != IPHONE_E_SUCCESS) { |
| 92 | printf("No device found, is it plugged in?\n"); | 93 | printf("No device found, is it plugged in?\n"); |
| 93 | return -1; | 94 | return -1; |
| 94 | } | 95 | } |
| 95 | } | 96 | /* }*/ |
| 96 | 97 | ||
| 97 | if (IPHONE_E_SUCCESS != iphone_lckd_new_client(phone, &control)) { | 98 | if (IPHONE_E_SUCCESS != iphone_lckd_new_client(phone, &control)) { |
| 98 | iphone_free_device(phone); | 99 | iphone_free_device(phone); |
| @@ -103,15 +104,19 @@ int main(int argc, char *argv[]) | |||
| 103 | ret = iphone_lckd_start_service(control, "com.apple.syslog_relay", &port); | 104 | ret = iphone_lckd_start_service(control, "com.apple.syslog_relay", &port); |
| 104 | if ((ret == IPHONE_E_SUCCESS) && port) { | 105 | if ((ret == IPHONE_E_SUCCESS) && port) { |
| 105 | /* connect to socket relay messages */ | 106 | /* connect to socket relay messages */ |
| 106 | iphone_umux_client_t syslog_client = NULL; | 107 | //iphone_umux_client_t syslog_client = NULL; |
| 107 | 108 | ||
| 108 | ret = iphone_mux_new_client(phone, 514, port, &syslog_client); | 109 | //ret = iphone_mux_new_client(phone, 514, port, &syslog_client); |
| 109 | if (ret == IPHONE_E_SUCCESS) { | 110 | int sfd = usbmuxd_connect(iphone_get_device_handle(phone), port); |
| 111 | //if (ret == IPHONE_E_SUCCESS) { | ||
| 112 | if (sfd < 0) { | ||
| 113 | printf("ERROR: Could not open usbmux connection.\n"); | ||
| 114 | } else { | ||
| 110 | while (!quit_flag) { | 115 | while (!quit_flag) { |
| 111 | char *receive = NULL; | 116 | char *receive = NULL; |
| 112 | uint32_t datalen = 0, bytes = 0, recv_bytes = 0; | 117 | uint32_t datalen = 0, bytes = 0, recv_bytes = 0; |
| 113 | 118 | ||
| 114 | ret = iphone_mux_recv(syslog_client, (char *) &datalen, sizeof(datalen), &bytes); | 119 | ret = usbmuxd_recv(sfd, (char *) &datalen, sizeof(datalen), &bytes); |
| 115 | datalen = ntohl(datalen); | 120 | datalen = ntohl(datalen); |
| 116 | 121 | ||
| 117 | if (datalen == 0) | 122 | if (datalen == 0) |
| @@ -121,7 +126,7 @@ int main(int argc, char *argv[]) | |||
| 121 | receive = (char *) malloc(sizeof(char) * datalen); | 126 | receive = (char *) malloc(sizeof(char) * datalen); |
| 122 | 127 | ||
| 123 | while (!quit_flag && (recv_bytes <= datalen)) { | 128 | while (!quit_flag && (recv_bytes <= datalen)) { |
| 124 | ret = iphone_mux_recv(syslog_client, receive, datalen, &bytes); | 129 | ret = usbmuxd_recv(sfd, receive, datalen, &bytes); |
| 125 | 130 | ||
| 126 | if (bytes == 0) | 131 | if (bytes == 0) |
| 127 | break; | 132 | break; |
| @@ -133,10 +138,8 @@ int main(int argc, char *argv[]) | |||
| 133 | 138 | ||
| 134 | free(receive); | 139 | free(receive); |
| 135 | } | 140 | } |
| 136 | } else { | ||
| 137 | printf("ERROR: Could not open usbmux connection.\n"); | ||
| 138 | } | 141 | } |
| 139 | iphone_mux_free_client(syslog_client); | 142 | usbmuxd_disconnect(sfd); //iphone_mux_free_client(syslog_client); |
| 140 | } else { | 143 | } else { |
| 141 | printf("ERROR: Could not start service com.apple.syslog_relay.\n"); | 144 | printf("ERROR: Could not start service com.apple.syslog_relay.\n"); |
| 142 | } | 145 | } |
diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h index dedc78f..bd8d9fb 100644 --- a/include/libiphone/libiphone.h +++ b/include/libiphone/libiphone.h | |||
| @@ -30,6 +30,7 @@ extern "C" { | |||
| 30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
| 31 | #include <sys/stat.h> | 31 | #include <sys/stat.h> |
| 32 | #include <plist/plist.h> | 32 | #include <plist/plist.h> |
| 33 | #include <usbmuxd.h> | ||
| 33 | 34 | ||
| 34 | //general errors | 35 | //general errors |
| 35 | #define IPHONE_E_SUCCESS 0 | 36 | #define IPHONE_E_SUCCESS 0 |
| @@ -68,9 +69,6 @@ typedef struct iphone_device_int *iphone_device_t; | |||
| 68 | struct iphone_lckd_client_int; | 69 | struct iphone_lckd_client_int; |
| 69 | typedef struct iphone_lckd_client_int *iphone_lckd_client_t; | 70 | typedef struct iphone_lckd_client_int *iphone_lckd_client_t; |
| 70 | 71 | ||
| 71 | struct iphone_umux_client_int; | ||
| 72 | typedef struct iphone_umux_client_int *iphone_umux_client_t; | ||
| 73 | |||
| 74 | struct iphone_afc_client_int; | 72 | struct iphone_afc_client_int; |
| 75 | typedef struct iphone_afc_client_int *iphone_afc_client_t; | 73 | typedef struct iphone_afc_client_int *iphone_afc_client_t; |
| 76 | 74 | ||
| @@ -95,9 +93,10 @@ void iphone_set_debug(int level); | |||
| 95 | 93 | ||
| 96 | //device related functions | 94 | //device related functions |
| 97 | iphone_error_t iphone_get_device ( iphone_device_t *device ); | 95 | iphone_error_t iphone_get_device ( iphone_device_t *device ); |
| 98 | iphone_error_t iphone_get_specific_device( unsigned int bus_n, int dev_n, iphone_device_t * device ); | 96 | iphone_error_t iphone_get_device_by_uuid ( iphone_device_t *device, const char *uuid ); |
| 99 | iphone_error_t iphone_free_device ( iphone_device_t device ); | 97 | iphone_error_t iphone_free_device ( iphone_device_t device ); |
| 100 | 98 | ||
| 99 | uint32_t iphone_get_device_handle ( iphone_device_t device ); | ||
| 101 | 100 | ||
| 102 | //lockdownd related functions | 101 | //lockdownd related functions |
| 103 | iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid); | 102 | iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid); |
| @@ -110,17 +109,8 @@ iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, plist_t* plist); | |||
| 110 | iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, plist_t plist); | 109 | iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, plist_t plist); |
| 111 | 110 | ||
| 112 | 111 | ||
| 113 | //usbmux related functions | ||
| 114 | iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ); | ||
| 115 | iphone_error_t iphone_mux_free_client ( iphone_umux_client_t client ); | ||
| 116 | |||
| 117 | iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t *sent_bytes ); | ||
| 118 | iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes ); | ||
| 119 | iphone_error_t iphone_mux_recv_timeout ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes, int timeout); | ||
| 120 | |||
| 121 | |||
| 122 | //afc related functions | 112 | //afc related functions |
| 123 | iphone_error_t iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t *client ); | 113 | iphone_error_t iphone_afc_new_client ( iphone_device_t device, int dst_port, iphone_afc_client_t *client ); |
| 124 | iphone_error_t iphone_afc_free_client ( iphone_afc_client_t client ); | 114 | iphone_error_t iphone_afc_free_client ( iphone_afc_client_t client ); |
| 125 | int iphone_afc_get_afcerror ( iphone_afc_client_t client ); | 115 | int iphone_afc_get_afcerror ( iphone_afc_client_t client ); |
| 126 | int iphone_afc_get_errno ( iphone_afc_client_t client ); | 116 | int iphone_afc_get_errno ( iphone_afc_client_t client ); |
| @@ -143,7 +133,7 @@ iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, | |||
| 143 | 133 | ||
| 144 | 134 | ||
| 145 | 135 | ||
| 146 | iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port, | 136 | iphone_error_t iphone_msync_new_client(iphone_device_t device, int dst_port, |
| 147 | iphone_msync_client_t * client); | 137 | iphone_msync_client_t * client); |
| 148 | iphone_error_t iphone_msync_free_client(iphone_msync_client_t client); | 138 | iphone_error_t iphone_msync_free_client(iphone_msync_client_t client); |
| 149 | 139 | ||
| @@ -167,7 +157,7 @@ iphone_error_t iphone_msync_send(iphone_msync_client_t client, plist_t plist); | |||
| 167 | #define NP_APP_INSTALLED "com.apple.mobile.application_installed" | 157 | #define NP_APP_INSTALLED "com.apple.mobile.application_installed" |
| 168 | #define NP_APP_UNINSTALLED "com.apple.mobile.application_uninstalled" | 158 | #define NP_APP_UNINSTALLED "com.apple.mobile.application_uninstalled" |
| 169 | 159 | ||
| 170 | iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ); | 160 | iphone_error_t iphone_np_new_client ( iphone_device_t device, int dst_port, iphone_np_client_t *client ); |
| 171 | iphone_error_t iphone_np_free_client ( iphone_np_client_t client ); | 161 | iphone_error_t iphone_np_free_client ( iphone_np_client_t client ); |
| 172 | 162 | ||
| 173 | iphone_error_t iphone_np_post_notification ( iphone_np_client_t client, const char *notification ); | 163 | iphone_error_t iphone_np_post_notification ( iphone_np_client_t client, const char *notification ); |
| @@ -20,7 +20,9 @@ | |||
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <stdio.h> | 22 | #include <stdio.h> |
| 23 | #include <stdlib.h> | ||
| 23 | #include <errno.h> | 24 | #include <errno.h> |
| 25 | #include <unistd.h> | ||
| 24 | #include "AFC.h" | 26 | #include "AFC.h" |
| 25 | #include "utils.h" | 27 | #include "utils.h" |
| 26 | 28 | ||
| @@ -61,29 +63,28 @@ static void afc_unlock(iphone_afc_client_t client) | |||
| 61 | * | 63 | * |
| 62 | * @return A handle to the newly-connected client or NULL upon error. | 64 | * @return A handle to the newly-connected client or NULL upon error. |
| 63 | */ | 65 | */ |
| 64 | iphone_error_t iphone_afc_new_client(iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t * client) | 66 | iphone_error_t iphone_afc_new_client(iphone_device_t device, int dst_port, iphone_afc_client_t * client) |
| 65 | { | 67 | { |
| 66 | int ret = IPHONE_E_SUCCESS; | ||
| 67 | |||
| 68 | //makes sure thread environment is available | 68 | //makes sure thread environment is available |
| 69 | if (!g_thread_supported()) | 69 | if (!g_thread_supported()) |
| 70 | g_thread_init(NULL); | 70 | g_thread_init(NULL); |
| 71 | iphone_afc_client_t client_loc = (iphone_afc_client_t) malloc(sizeof(struct iphone_afc_client_int)); | ||
| 72 | 71 | ||
| 73 | if (!device) | 72 | if (!device) |
| 74 | return IPHONE_E_INVALID_ARG; | 73 | return IPHONE_E_INVALID_ARG; |
| 75 | 74 | ||
| 76 | // Attempt connection | 75 | // Attempt connection |
| 77 | client_loc->connection = NULL; | 76 | int sfd = usbmuxd_connect(device->handle, dst_port); |
| 78 | ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); | 77 | if (sfd < 0) { |
| 79 | if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { | 78 | return IPHONE_E_UNKNOWN_ERROR; // ret; |
| 80 | free(client_loc); | ||
| 81 | return ret; | ||
| 82 | } | 79 | } |
| 80 | |||
| 81 | iphone_afc_client_t client_loc = (iphone_afc_client_t) malloc(sizeof(struct iphone_afc_client_int)); | ||
| 82 | client_loc->sfd = sfd; | ||
| 83 | |||
| 83 | // Allocate a packet | 84 | // Allocate a packet |
| 84 | client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); | 85 | client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); |
| 85 | if (!client_loc->afc_packet) { | 86 | if (!client_loc->afc_packet) { |
| 86 | iphone_mux_free_client(client_loc->connection); | 87 | usbmuxd_disconnect(client_loc->sfd); |
| 87 | free(client_loc); | 88 | free(client_loc); |
| 88 | return IPHONE_E_UNKNOWN_ERROR; | 89 | return IPHONE_E_UNKNOWN_ERROR; |
| 89 | } | 90 | } |
| @@ -106,10 +107,10 @@ iphone_error_t iphone_afc_new_client(iphone_device_t device, int src_port, int d | |||
| 106 | */ | 107 | */ |
| 107 | iphone_error_t iphone_afc_free_client(iphone_afc_client_t client) | 108 | iphone_error_t iphone_afc_free_client(iphone_afc_client_t client) |
| 108 | { | 109 | { |
| 109 | if (!client || !client->connection || !client->afc_packet) | 110 | if (!client || client->sfd < 0 || !client->afc_packet) |
| 110 | return IPHONE_E_INVALID_ARG; | 111 | return IPHONE_E_INVALID_ARG; |
| 111 | 112 | ||
| 112 | iphone_mux_free_client(client->connection); | 113 | usbmuxd_disconnect(client->sfd); |
| 113 | free(client->afc_packet); | 114 | free(client->afc_packet); |
| 114 | if (client->mutex) { | 115 | if (client->mutex) { |
| 115 | g_mutex_free(client->mutex); | 116 | g_mutex_free(client->mutex); |
| @@ -217,7 +218,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int | |||
| 217 | int bytes = 0, offset = 0; | 218 | int bytes = 0, offset = 0; |
| 218 | char *buffer; | 219 | char *buffer; |
| 219 | 220 | ||
| 220 | if (!client || !client->connection || !client->afc_packet) | 221 | if (!client || client->sfd < 0 || !client->afc_packet) |
| 221 | return 0; | 222 | return 0; |
| 222 | if (!data || !length) | 223 | if (!data || !length) |
| 223 | length = 0; | 224 | length = 0; |
| @@ -248,7 +249,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int | |||
| 248 | return -1; | 249 | return -1; |
| 249 | } | 250 | } |
| 250 | memcpy(buffer + sizeof(AFCPacket), data, offset); | 251 | memcpy(buffer + sizeof(AFCPacket), data, offset); |
| 251 | iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); | 252 | usbmuxd_send(client->sfd, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); |
| 252 | free(buffer); | 253 | free(buffer); |
| 253 | if (bytes <= 0) { | 254 | if (bytes <= 0) { |
| 254 | return bytes; | 255 | return bytes; |
| @@ -259,7 +260,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int | |||
| 259 | log_debug_msg("Buffer: \n"); | 260 | log_debug_msg("Buffer: \n"); |
| 260 | log_debug_buffer(data + offset, length - offset); | 261 | log_debug_buffer(data + offset, length - offset); |
| 261 | 262 | ||
| 262 | iphone_mux_send(client->connection, data + offset, length - offset, (uint32_t*)&bytes); | 263 | usbmuxd_send(client->sfd, data + offset, length - offset, (uint32_t*)&bytes); |
| 263 | return bytes; | 264 | return bytes; |
| 264 | } else { | 265 | } else { |
| 265 | log_debug_msg("dispatch_AFC_packet doin things the old way\n"); | 266 | log_debug_msg("dispatch_AFC_packet doin things the old way\n"); |
| @@ -273,7 +274,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int | |||
| 273 | } | 274 | } |
| 274 | log_debug_buffer(buffer, client->afc_packet->this_length); | 275 | log_debug_buffer(buffer, client->afc_packet->this_length); |
| 275 | log_debug_msg("\n"); | 276 | log_debug_msg("\n"); |
| 276 | iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); | 277 | usbmuxd_send(client->sfd, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); |
| 277 | 278 | ||
| 278 | if (buffer) { | 279 | if (buffer) { |
| 279 | free(buffer); | 280 | free(buffer); |
| @@ -307,7 +308,7 @@ static int receive_AFC_data(iphone_afc_client_t client, char **dump_here) | |||
| 307 | client->afcerror = 0; | 308 | client->afcerror = 0; |
| 308 | 309 | ||
| 309 | // first, read the AFC header | 310 | // first, read the AFC header |
| 310 | iphone_mux_recv(client->connection, (char*)&header, sizeof(AFCPacket), (uint32_t*)&bytes); | 311 | usbmuxd_recv(client->sfd, (char*)&header, sizeof(AFCPacket), (uint32_t*)&bytes); |
| 311 | if (bytes <= 0) { | 312 | if (bytes <= 0) { |
| 312 | log_debug_msg("%s: Just didn't get enough.\n", __func__); | 313 | log_debug_msg("%s: Just didn't get enough.\n", __func__); |
| 313 | *dump_here = NULL; | 314 | *dump_here = NULL; |
| @@ -359,24 +360,26 @@ static int receive_AFC_data(iphone_afc_client_t client, char **dump_here) | |||
| 359 | } | 360 | } |
| 360 | 361 | ||
| 361 | *dump_here = (char*)malloc(entire_len); | 362 | *dump_here = (char*)malloc(entire_len); |
| 362 | iphone_mux_recv(client->connection, *dump_here, this_len, (uint32_t*)&bytes); | 363 | if (this_len > 0) { |
| 363 | if (bytes <= 0) { | 364 | usbmuxd_recv(client->sfd, *dump_here, this_len, (uint32_t*)&bytes); |
| 364 | free(*dump_here); | 365 | if (bytes <= 0) { |
| 365 | *dump_here = NULL; | 366 | free(*dump_here); |
| 366 | log_debug_msg("%s: Did not get packet contents!\n", __func__); | 367 | *dump_here = NULL; |
| 367 | return -1; | 368 | log_debug_msg("%s: Did not get packet contents!\n", __func__); |
| 368 | } else if ((uint32_t)bytes < this_len) { | 369 | return -1; |
| 369 | free(*dump_here); | 370 | } else if ((uint32_t)bytes < this_len) { |
| 370 | *dump_here = NULL; | 371 | free(*dump_here); |
| 371 | log_debug_msg("%s: Could not receive this_len=%d bytes\n", __func__, this_len); | 372 | *dump_here = NULL; |
| 372 | return -1; | 373 | log_debug_msg("%s: Could not receive this_len=%d bytes\n", __func__, this_len); |
| 374 | return -1; | ||
| 375 | } | ||
| 373 | } | 376 | } |
| 374 | 377 | ||
| 375 | current_count = this_len; | 378 | current_count = this_len; |
| 376 | 379 | ||
| 377 | if (entire_len > this_len) { | 380 | if (entire_len > this_len) { |
| 378 | while (current_count < entire_len) { | 381 | while (current_count < entire_len) { |
| 379 | iphone_mux_recv(client->connection, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)&bytes); | 382 | usbmuxd_recv(client->sfd, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)&bytes); |
| 380 | if (bytes <= 0) { | 383 | if (bytes <= 0) { |
| 381 | log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, bytes); | 384 | log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, bytes); |
| 382 | break; | 385 | break; |
| @@ -559,7 +562,7 @@ iphone_error_t iphone_afc_delete_file(iphone_afc_client_t client, const char *pa | |||
| 559 | char *response = NULL; | 562 | char *response = NULL; |
| 560 | int bytes; | 563 | int bytes; |
| 561 | 564 | ||
| 562 | if (!client || !path || !client->afc_packet || !client->connection) | 565 | if (!client || !path || !client->afc_packet || client->sfd < 0) |
| 563 | return IPHONE_E_INVALID_ARG; | 566 | return IPHONE_E_INVALID_ARG; |
| 564 | 567 | ||
| 565 | afc_lock(client); | 568 | afc_lock(client); |
| @@ -600,7 +603,7 @@ iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *fr | |||
| 600 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); | 603 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); |
| 601 | int bytes = 0; | 604 | int bytes = 0; |
| 602 | 605 | ||
| 603 | if (!client || !from || !to || !client->afc_packet || !client->connection) | 606 | if (!client || !from || !to || !client->afc_packet || client->sfd < 0) |
| 604 | return IPHONE_E_INVALID_ARG; | 607 | return IPHONE_E_INVALID_ARG; |
| 605 | 608 | ||
| 606 | afc_lock(client); | 609 | afc_lock(client); |
| @@ -748,7 +751,7 @@ iphone_error_t iphone_afc_get_file_attr(iphone_afc_client_t client, const char * | |||
| 748 | { | 751 | { |
| 749 | 752 | ||
| 750 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 753 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 751 | if (!client || !client->connection || !client->afc_packet || !stbuf) | 754 | if (!client || client->sfd < 0 || !client->afc_packet || !stbuf) |
| 752 | return IPHONE_E_INVALID_ARG; | 755 | return IPHONE_E_INVALID_ARG; |
| 753 | 756 | ||
| 754 | memset(stbuf, 0, sizeof(struct stat)); | 757 | memset(stbuf, 0, sizeof(struct stat)); |
| @@ -793,7 +796,7 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename, | |||
| 793 | int bytes = 0, length = 0; | 796 | int bytes = 0, length = 0; |
| 794 | char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); | 797 | char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); |
| 795 | 798 | ||
| 796 | if (!client || !client->connection || !client->afc_packet) | 799 | if (!client || client->sfd < 0|| !client->afc_packet) |
| 797 | return IPHONE_E_INVALID_ARG; | 800 | return IPHONE_E_INVALID_ARG; |
| 798 | 801 | ||
| 799 | afc_lock(client); | 802 | afc_lock(client); |
| @@ -851,7 +854,7 @@ iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *d | |||
| 851 | int current_count = 0, bytes_loc = 0; | 854 | int current_count = 0, bytes_loc = 0; |
| 852 | const int MAXIMUM_READ_SIZE = 1 << 16; | 855 | const int MAXIMUM_READ_SIZE = 1 << 16; |
| 853 | 856 | ||
| 854 | if (!client || !client->afc_packet || !client->connection || !file) | 857 | if (!client || !client->afc_packet || client->sfd < 0 || !file) |
| 855 | return IPHONE_E_INVALID_ARG; | 858 | return IPHONE_E_INVALID_ARG; |
| 856 | log_debug_msg("afc_read_file called for length %i\n", length); | 859 | log_debug_msg("afc_read_file called for length %i\n", length); |
| 857 | 860 | ||
| @@ -926,7 +929,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file, | |||
| 926 | int bytes_loc = 0; | 929 | int bytes_loc = 0; |
| 927 | char *out_buffer = NULL; | 930 | char *out_buffer = NULL; |
| 928 | 931 | ||
| 929 | if (!client || !client->afc_packet || !client->connection || !file || !bytes) | 932 | if (!client || !client->afc_packet || client->sfd < 0 || !file || !bytes) |
| 930 | return IPHONE_E_INVALID_ARG; | 933 | return IPHONE_E_INVALID_ARG; |
| 931 | 934 | ||
| 932 | afc_lock(client); | 935 | afc_lock(client); |
| @@ -1219,7 +1222,7 @@ iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, | |||
| 1219 | int bytes = 0; | 1222 | int bytes = 0; |
| 1220 | uint64_t size_requested = newsize; | 1223 | uint64_t size_requested = newsize; |
| 1221 | 1224 | ||
| 1222 | if (!client || !path || !client->afc_packet || !client->connection) | 1225 | if (!client || !path || !client->afc_packet || client->sfd < 0) |
| 1223 | return IPHONE_E_INVALID_ARG; | 1226 | return IPHONE_E_INVALID_ARG; |
| 1224 | 1227 | ||
| 1225 | afc_lock(client); | 1228 | afc_lock(client); |
| @@ -19,7 +19,7 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "usbmux.h" | 22 | #include "libiphone/libiphone.h" |
| 23 | #include "iphone.h" | 23 | #include "iphone.h" |
| 24 | 24 | ||
| 25 | #include <string.h> | 25 | #include <string.h> |
| @@ -47,7 +47,7 @@ typedef struct __AFCToken { | |||
| 47 | } AFCToken; | 47 | } AFCToken; |
| 48 | 48 | ||
| 49 | struct iphone_afc_client_int { | 49 | struct iphone_afc_client_int { |
| 50 | iphone_umux_client_t connection; | 50 | int sfd; |
| 51 | AFCPacket *afc_packet; | 51 | AFCPacket *afc_packet; |
| 52 | int file_handle; | 52 | int file_handle; |
| 53 | int lock; | 53 | int lock; |
diff --git a/src/Makefile.am b/src/Makefile.am index 2ae1943..5489684 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | INCLUDES = -I$(top_srcdir)/include | 1 | INCLUDES = -I$(top_srcdir)/include |
| 2 | 2 | ||
| 3 | AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) | 3 | AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusbmuxd_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) |
| 4 | AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) | 4 | AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS) |
| 5 | 5 | ||
| 6 | lib_LTLIBRARIES = libiphone.la | 6 | lib_LTLIBRARIES = libiphone.la |
| 7 | libiphone_la_SOURCES = usbmux.c usbmux.h \ | 7 | libiphone_la_SOURCES = iphone.c iphone.h \ |
| 8 | iphone.c iphone.h \ | ||
| 9 | lockdown.c lockdown.h\ | 8 | lockdown.c lockdown.h\ |
| 10 | AFC.c AFC.h\ | 9 | AFC.c AFC.h\ |
| 11 | NotificationProxy.c NotificationProxy.h\ | 10 | NotificationProxy.c NotificationProxy.h\ |
diff --git a/src/MobileSync.c b/src/MobileSync.c index 58d0beb..7d6e947 100644 --- a/src/MobileSync.c +++ b/src/MobileSync.c | |||
| @@ -22,29 +22,30 @@ | |||
| 22 | #include "MobileSync.h" | 22 | #include "MobileSync.h" |
| 23 | #include <plist/plist.h> | 23 | #include <plist/plist.h> |
| 24 | #include <string.h> | 24 | #include <string.h> |
| 25 | #include <stdlib.h> | ||
| 25 | #include <arpa/inet.h> | 26 | #include <arpa/inet.h> |
| 26 | 27 | ||
| 27 | 28 | ||
| 28 | #define MSYNC_VERSION_INT1 100 | 29 | #define MSYNC_VERSION_INT1 100 |
| 29 | #define MSYNC_VERSION_INT2 100 | 30 | #define MSYNC_VERSION_INT2 100 |
| 30 | 31 | ||
| 31 | iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port, | 32 | iphone_error_t iphone_msync_new_client(iphone_device_t device, int dst_port, |
| 32 | iphone_msync_client_t * client) | 33 | iphone_msync_client_t * client) |
| 33 | { | 34 | { |
| 34 | if (!device || src_port == 0 || dst_port == 0 || !client || *client) | 35 | if (!device || dst_port == 0 || !client || *client) |
| 35 | return IPHONE_E_INVALID_ARG; | 36 | return IPHONE_E_INVALID_ARG; |
| 36 | 37 | ||
| 37 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 38 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 38 | 39 | ||
| 39 | iphone_msync_client_t client_loc = (iphone_msync_client_t) malloc(sizeof(struct iphone_msync_client_int)); | ||
| 40 | |||
| 41 | // Attempt connection | 40 | // Attempt connection |
| 42 | client_loc->connection = NULL; | 41 | int sfd = usbmuxd_connect(device->handle, dst_port); |
| 43 | ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); | 42 | if (sfd < 0) { |
| 44 | if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { | ||
| 45 | free(client_loc); | ||
| 46 | return ret; | 43 | return ret; |
| 47 | } | 44 | } |
| 45 | |||
| 46 | iphone_msync_client_t client_loc = (iphone_msync_client_t) malloc(sizeof(struct iphone_msync_client_int)); | ||
| 47 | client_loc->sfd = sfd; | ||
| 48 | |||
| 48 | //perform handshake | 49 | //perform handshake |
| 49 | plist_t array = NULL; | 50 | plist_t array = NULL; |
| 50 | 51 | ||
| @@ -120,7 +121,7 @@ iphone_error_t iphone_msync_free_client(iphone_msync_client_t client) | |||
| 120 | return IPHONE_E_INVALID_ARG; | 121 | return IPHONE_E_INVALID_ARG; |
| 121 | 122 | ||
| 122 | iphone_msync_stop_session(client); | 123 | iphone_msync_stop_session(client); |
| 123 | return iphone_mux_free_client(client->connection); | 124 | return usbmuxd_disconnect(client->sfd); |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | /** Polls the iPhone for MobileSync data. | 127 | /** Polls the iPhone for MobileSync data. |
| @@ -138,14 +139,14 @@ iphone_error_t iphone_msync_recv(iphone_msync_client_t client, plist_t * plist) | |||
| 138 | char *receive = NULL; | 139 | char *receive = NULL; |
| 139 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; | 140 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; |
| 140 | 141 | ||
| 141 | ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes); | 142 | ret = usbmuxd_recv(client->sfd, (char *) &datalen, sizeof(datalen), &bytes); |
| 142 | datalen = ntohl(datalen); | 143 | datalen = ntohl(datalen); |
| 143 | 144 | ||
| 144 | receive = (char *) malloc(sizeof(char) * datalen); | 145 | receive = (char *) malloc(sizeof(char) * datalen); |
| 145 | 146 | ||
| 146 | /* fill buffer and request more packets if needed */ | 147 | /* fill buffer and request more packets if needed */ |
| 147 | while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { | 148 | while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { |
| 148 | ret = iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes); | 149 | ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); |
| 149 | received_bytes += bytes; | 150 | received_bytes += bytes; |
| 150 | } | 151 | } |
| 151 | 152 | ||
| @@ -201,7 +202,7 @@ iphone_error_t iphone_msync_send(iphone_msync_client_t client, plist_t plist) | |||
| 201 | memcpy(real_query, &length, sizeof(length)); | 202 | memcpy(real_query, &length, sizeof(length)); |
| 202 | memcpy(real_query + 4, content, ntohl(length)); | 203 | memcpy(real_query + 4, content, ntohl(length)); |
| 203 | 204 | ||
| 204 | ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes); | 205 | ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); |
| 205 | free(real_query); | 206 | free(real_query); |
| 206 | return ret; | 207 | return ret; |
| 207 | } | 208 | } |
diff --git a/src/MobileSync.h b/src/MobileSync.h index 7655b59..495e702 100644 --- a/src/MobileSync.h +++ b/src/MobileSync.h | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #ifndef MOBILESYNC_H | 21 | #ifndef MOBILESYNC_H |
| 22 | #define MOBILESYNC_H | 22 | #define MOBILESYNC_H |
| 23 | 23 | ||
| 24 | #include "usbmux.h" | ||
| 25 | #include "iphone.h" | 24 | #include "iphone.h" |
| 26 | #include "utils.h" | 25 | #include "utils.h" |
| 27 | 26 | ||
| @@ -30,7 +29,7 @@ | |||
| 30 | 29 | ||
| 31 | 30 | ||
| 32 | struct iphone_msync_client_int { | 31 | struct iphone_msync_client_int { |
| 33 | iphone_umux_client_t connection; | 32 | int sfd; |
| 34 | }; | 33 | }; |
| 35 | 34 | ||
| 36 | 35 | ||
diff --git a/src/NotificationProxy.c b/src/NotificationProxy.c index d8bcc34..6fc048c 100644 --- a/src/NotificationProxy.c +++ b/src/NotificationProxy.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include <string.h> | 22 | #include <string.h> |
| 23 | #include <stdio.h> | 23 | #include <stdio.h> |
| 24 | #include <stdlib.h> | ||
| 24 | #include <arpa/inet.h> | 25 | #include <arpa/inet.h> |
| 25 | #include <plist/plist.h> | 26 | #include <plist/plist.h> |
| 26 | #include "NotificationProxy.h" | 27 | #include "NotificationProxy.h" |
| @@ -79,9 +80,9 @@ static iphone_error_t np_plist_send(iphone_np_client_t client, plist_t dict) | |||
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | nlen = htonl(length); | 82 | nlen = htonl(length); |
| 82 | iphone_mux_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); | 83 | usbmuxd_send(client->sfd, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); |
| 83 | if (bytes == sizeof(nlen)) { | 84 | if (bytes == sizeof(nlen)) { |
| 84 | iphone_mux_send(client->connection, XML_content, length, (uint32_t*)&bytes); | 85 | usbmuxd_send(client->sfd, XML_content, length, (uint32_t*)&bytes); |
| 85 | if (bytes > 0) { | 86 | if (bytes > 0) { |
| 86 | if ((uint32_t)bytes == length) { | 87 | if ((uint32_t)bytes == length) { |
| 87 | res = IPHONE_E_SUCCESS; | 88 | res = IPHONE_E_SUCCESS; |
| @@ -107,26 +108,24 @@ static iphone_error_t np_plist_send(iphone_np_client_t client, plist_t dict) | |||
| 107 | * | 108 | * |
| 108 | * @return A handle to the newly-connected client or NULL upon error. | 109 | * @return A handle to the newly-connected client or NULL upon error. |
| 109 | */ | 110 | */ |
| 110 | iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ) | 111 | iphone_error_t iphone_np_new_client ( iphone_device_t device, int dst_port, iphone_np_client_t *client ) |
| 111 | { | 112 | { |
| 112 | int ret = IPHONE_E_SUCCESS; | ||
| 113 | |||
| 114 | //makes sure thread environment is available | 113 | //makes sure thread environment is available |
| 115 | if (!g_thread_supported()) | 114 | if (!g_thread_supported()) |
| 116 | g_thread_init(NULL); | 115 | g_thread_init(NULL); |
| 117 | iphone_np_client_t client_loc = (iphone_np_client_t) malloc(sizeof(struct iphone_np_client_int)); | ||
| 118 | 116 | ||
| 119 | if (!device) | 117 | if (!device) |
| 120 | return IPHONE_E_INVALID_ARG; | 118 | return IPHONE_E_INVALID_ARG; |
| 121 | 119 | ||
| 122 | // Attempt connection | 120 | // Attempt connection |
| 123 | client_loc->connection = NULL; | 121 | int sfd = usbmuxd_connect(device->handle, dst_port); |
| 124 | ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); | 122 | if (sfd < 0) { |
| 125 | if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { | 123 | return IPHONE_E_UNKNOWN_ERROR; //ret; |
| 126 | free(client_loc); | ||
| 127 | return ret; | ||
| 128 | } | 124 | } |
| 129 | 125 | ||
| 126 | iphone_np_client_t client_loc = (iphone_np_client_t) malloc(sizeof(struct iphone_np_client_int)); | ||
| 127 | client_loc->sfd = sfd; | ||
| 128 | |||
| 130 | client_loc->mutex = g_mutex_new(); | 129 | client_loc->mutex = g_mutex_new(); |
| 131 | 130 | ||
| 132 | client_loc->notifier = NULL; | 131 | client_loc->notifier = NULL; |
| @@ -144,13 +143,11 @@ iphone_error_t iphone_np_free_client ( iphone_np_client_t client ) | |||
| 144 | if (!client) | 143 | if (!client) |
| 145 | return IPHONE_E_INVALID_ARG; | 144 | return IPHONE_E_INVALID_ARG; |
| 146 | 145 | ||
| 147 | if (client->connection) { | 146 | usbmuxd_disconnect(client->sfd); |
| 148 | iphone_mux_free_client(client->connection); | 147 | client->sfd = -1; |
| 149 | client->connection = NULL; | 148 | if (client->notifier) { |
| 150 | if (client->notifier) { | 149 | log_debug_msg("joining np callback\n"); |
| 151 | log_debug_msg("joining np callback\n"); | 150 | g_thread_join(client->notifier); |
| 152 | g_thread_join(client->notifier); | ||
| 153 | } | ||
| 154 | } | 151 | } |
| 155 | if (client->mutex) { | 152 | if (client->mutex) { |
| 156 | g_mutex_free(client->mutex); | 153 | g_mutex_free(client->mutex); |
| @@ -295,13 +292,13 @@ iphone_error_t iphone_np_get_notification( iphone_np_client_t client, char **not | |||
| 295 | char *XML_content = NULL; | 292 | char *XML_content = NULL; |
| 296 | plist_t dict = NULL; | 293 | plist_t dict = NULL; |
| 297 | 294 | ||
| 298 | if (!client || !client->connection || *notification) { | 295 | if (!client || client->sfd < 0 || *notification) { |
| 299 | return IPHONE_E_INVALID_ARG; | 296 | return IPHONE_E_INVALID_ARG; |
| 300 | } | 297 | } |
| 301 | 298 | ||
| 302 | np_lock(client); | 299 | np_lock(client); |
| 303 | 300 | ||
| 304 | iphone_mux_recv_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, 500); | 301 | usbmuxd_recv_timeout(client->sfd, (char*)&pktlen, sizeof(pktlen), &bytes, 500); |
| 305 | log_debug_msg("NotificationProxy: initial read=%i\n", bytes); | 302 | log_debug_msg("NotificationProxy: initial read=%i\n", bytes); |
| 306 | if (bytes < 4) { | 303 | if (bytes < 4) { |
| 307 | log_debug_msg("NotificationProxy: no notification received!\n"); | 304 | log_debug_msg("NotificationProxy: no notification received!\n"); |
| @@ -313,7 +310,7 @@ iphone_error_t iphone_np_get_notification( iphone_np_client_t client, char **not | |||
| 313 | XML_content = (char*)malloc(pktlen); | 310 | XML_content = (char*)malloc(pktlen); |
| 314 | log_debug_msg("pointer %p\n", XML_content); | 311 | log_debug_msg("pointer %p\n", XML_content); |
| 315 | 312 | ||
| 316 | iphone_mux_recv_timeout(client->connection, XML_content, pktlen, &bytes, 1000); | 313 | usbmuxd_recv_timeout(client->sfd, XML_content, pktlen, &bytes, 1000); |
| 317 | if (bytes <= 0) { | 314 | if (bytes <= 0) { |
| 318 | res = IPHONE_E_UNKNOWN_ERROR; | 315 | res = IPHONE_E_UNKNOWN_ERROR; |
| 319 | } else { | 316 | } else { |
| @@ -393,7 +390,7 @@ gpointer iphone_np_notifier( gpointer arg ) | |||
| 393 | if (!npt) return NULL; | 390 | if (!npt) return NULL; |
| 394 | 391 | ||
| 395 | log_debug_msg("%s: starting callback.\n", __func__); | 392 | log_debug_msg("%s: starting callback.\n", __func__); |
| 396 | while (npt->client->connection) { | 393 | while (npt->client->sfd >= 0) { |
| 397 | iphone_np_get_notification(npt->client, ¬ification); | 394 | iphone_np_get_notification(npt->client, ¬ification); |
| 398 | if (notification) { | 395 | if (notification) { |
| 399 | npt->cbfunc(notification); | 396 | npt->cbfunc(notification); |
| @@ -432,11 +429,11 @@ iphone_error_t iphone_np_set_notify_callback( iphone_np_client_t client, iphone_ | |||
| 432 | np_lock(client); | 429 | np_lock(client); |
| 433 | if (client->notifier) { | 430 | if (client->notifier) { |
| 434 | log_debug_msg("%s: callback already set, removing\n"); | 431 | log_debug_msg("%s: callback already set, removing\n"); |
| 435 | iphone_umux_client_t conn = client->connection; | 432 | int conn = client->sfd; |
| 436 | client->connection = NULL; | 433 | client->sfd = -1; |
| 437 | g_thread_join(client->notifier); | 434 | g_thread_join(client->notifier); |
| 438 | client->notifier = NULL; | 435 | client->notifier = NULL; |
| 439 | client->connection = conn; | 436 | client->sfd = conn; |
| 440 | } | 437 | } |
| 441 | 438 | ||
| 442 | if (notify_cb) { | 439 | if (notify_cb) { |
diff --git a/src/NotificationProxy.h b/src/NotificationProxy.h index 3552b79..afae98a 100644 --- a/src/NotificationProxy.h +++ b/src/NotificationProxy.h | |||
| @@ -19,13 +19,12 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | #include "libiphone/libiphone.h" | 21 | #include "libiphone/libiphone.h" |
| 22 | #include "usbmux.h" | ||
| 23 | #include "iphone.h" | 22 | #include "iphone.h" |
| 24 | 23 | ||
| 25 | #include <glib.h> | 24 | #include <glib.h> |
| 26 | 25 | ||
| 27 | struct iphone_np_client_int { | 26 | struct iphone_np_client_int { |
| 28 | iphone_umux_client_t connection; | 27 | int sfd; |
| 29 | GMutex *mutex; | 28 | GMutex *mutex; |
| 30 | GThread *notifier; | 29 | GThread *notifier; |
| 31 | }; | 30 | }; |
diff --git a/src/iphone.c b/src/iphone.c index 9dd3c07..9551173 100644 --- a/src/iphone.c +++ b/src/iphone.c | |||
| @@ -19,200 +19,85 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "usbmux.h" | ||
| 23 | #include "iphone.h" | 22 | #include "iphone.h" |
| 24 | #include "utils.h" | 23 | #include "utils.h" |
| 25 | #include <arpa/inet.h> | ||
| 26 | #include <usb.h> | ||
| 27 | #include <stdio.h> | 24 | #include <stdio.h> |
| 28 | #include <stdlib.h> | 25 | #include <stdlib.h> |
| 29 | #include <string.h> | 26 | #include <string.h> |
| 27 | #include <errno.h> | ||
| 28 | #include <libiphone/libiphone.h> | ||
| 30 | 29 | ||
| 31 | /** | 30 | /** |
| 32 | * This function sets the configuration of the given device to 3 | 31 | * Retrieves a list of connected devices from usbmuxd and matches their |
| 33 | * and claims the interface 1. If usb_set_configuration fails, it detaches | 32 | * UUID with the given UUID. If the given UUID is NULL then the first |
| 34 | * the kernel driver that blocks the device, and retries configuration. | 33 | * device reported by usbmuxd is used. |
| 35 | * | 34 | * |
| 36 | * @param phone which device to configure | 35 | * @param device Upon calling this function, a pointer to a location of type |
| 37 | */ | 36 | * iphone_device_t, which must have the value NULL. On return, this location |
| 38 | static void iphone_config_usb_device(iphone_device_t phone) | 37 | * will be filled with a handle to the device. |
| 39 | { | 38 | * @param uuid The UUID to match. |
| 40 | int ret; | ||
| 41 | int bytes; | ||
| 42 | unsigned char buf[512]; | ||
| 43 | |||
| 44 | log_debug_msg("setting configuration... "); | ||
| 45 | ret = usb_set_configuration(phone->device, 3); | ||
| 46 | if (ret != 0) { | ||
| 47 | log_debug_msg("Hm, usb_set_configuration returned %d: %s, trying to fix:\n", ret, strerror(-ret)); | ||
| 48 | log_debug_msg("-> detaching kernel driver... "); | ||
| 49 | ret = | ||
| 50 | usb_detach_kernel_driver_np(phone->device, | ||
| 51 | phone->__device->config->interface->altsetting->bInterfaceNumber); | ||
| 52 | if (ret != 0) { | ||
| 53 | log_debug_msg("usb_detach_kernel_driver_np returned %d: %s\n", ret, strerror(-ret)); | ||
| 54 | } else { | ||
| 55 | log_debug_msg("done.\n"); | ||
| 56 | log_debug_msg("setting configuration again... "); | ||
| 57 | ret = usb_set_configuration(phone->device, 3); | ||
| 58 | if (ret != 0) { | ||
| 59 | log_debug_msg("Error: usb_set_configuration returned %d: %s\n", ret, strerror(-ret)); | ||
| 60 | } else { | ||
| 61 | log_debug_msg("done.\n"); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } else { | ||
| 65 | log_debug_msg("done.\n"); | ||
| 66 | } | ||
| 67 | |||
| 68 | log_debug_msg("claiming interface... "); | ||
| 69 | ret = usb_claim_interface(phone->device, 1); | ||
| 70 | if (ret != 0) { | ||
| 71 | log_debug_msg("Error: usb_claim_interface returned %d: %s\n", ret, strerror(-ret)); | ||
| 72 | } else { | ||
| 73 | log_debug_msg("done.\n"); | ||
| 74 | } | ||
| 75 | |||
| 76 | do { | ||
| 77 | bytes = usb_bulk_read(phone->device, BULKIN, (void *) &buf, 512, 800); | ||
| 78 | if (bytes > 0) { | ||
| 79 | log_debug_msg("iphone_config_usb_device: initial read returned %d bytes of data.\n", bytes); | ||
| 80 | log_debug_buffer(buf, bytes); | ||
| 81 | } | ||
| 82 | } while (bytes > 0); | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Given a USB bus and device number, returns a device handle to the iPhone on | ||
| 87 | * that bus. To aid compatibility with future devices, this function does not | ||
| 88 | * check the vendor and device IDs! To do that, you should use | ||
| 89 | * iphone_get_device() or a system-specific API (e.g. HAL). | ||
| 90 | * | 39 | * |
| 91 | * @param bus_n The USB bus number. | ||
| 92 | * @param dev_n The USB device number. | ||
| 93 | * @param device A pointer to a iphone_device_t, which must be set to NULL upon | ||
| 94 | * calling iphone_get_specific_device, which will be filled with a device | ||
| 95 | * descriptor on return. | ||
| 96 | * @return IPHONE_E_SUCCESS if ok, otherwise an error code. | 40 | * @return IPHONE_E_SUCCESS if ok, otherwise an error code. |
| 97 | */ | 41 | */ |
| 98 | iphone_error_t iphone_get_specific_device(unsigned int bus_n, int dev_n, iphone_device_t * device) | 42 | iphone_error_t iphone_get_device_by_uuid(iphone_device_t * device, const char *uuid) |
| 99 | { | 43 | { |
| 100 | struct usb_bus *bus, *busses; | 44 | iphone_device_t phone; |
| 101 | struct usb_device *dev; | 45 | uint32_t handle = 0; |
| 102 | usbmux_version_header *version; | 46 | usbmuxd_scan_result *dev_list = NULL; |
| 103 | int bytes = 0; | 47 | int i; |
| 104 | |||
| 105 | //check we can actually write in device | ||
| 106 | if (!device || (device && *device)) | ||
| 107 | return IPHONE_E_INVALID_ARG; | ||
| 108 | |||
| 109 | iphone_device_t phone = (iphone_device_t) malloc(sizeof(struct iphone_device_int)); | ||
| 110 | 48 | ||
| 111 | // Initialize the struct | 49 | if (usbmuxd_scan(&dev_list) < 0) { |
| 112 | phone->device = NULL; | 50 | log_debug_msg("%s: usbmuxd_scan returned an error, is usbmuxd running?\n", __func__); |
| 113 | phone->__device = NULL; | 51 | } |
| 114 | phone->buffer = NULL; | 52 | if (dev_list && dev_list[0].handle > 0) { |
| 115 | 53 | if (!uuid) { | |
| 116 | // Initialize libusb | 54 | // select first device found if no UUID specified |
| 117 | usb_init(); | 55 | handle = dev_list[0].handle; |
| 118 | usb_find_busses(); | 56 | } else { |
| 119 | usb_find_devices(); | 57 | // otherwise walk through the list |
| 120 | busses = usb_get_busses(); | 58 | for (i = 0; dev_list[i].handle > 0; i++) { |
| 121 | 59 | log_debug_msg("%s: device handle=%d, uuid=%s\n", __func__, dev_list[i].handle, dev_list[i].serial_number); | |
| 122 | // Set the device configuration | 60 | if (strcasecmp(uuid, dev_list[i].serial_number) == 0) { |
| 123 | for (bus = busses; bus; bus = bus->next) | 61 | handle = dev_list[i].handle; |
| 124 | if (strtoul(bus->dirname, NULL, 10) == bus_n) | 62 | break; |
| 125 | for (dev = bus->devices; dev != NULL; dev = dev->next) | ||
| 126 | if (strtol(dev->filename, NULL, 10) == dev_n) { | ||
| 127 | phone->__device = dev; | ||
| 128 | phone->device = usb_open(phone->__device); | ||
| 129 | iphone_config_usb_device(phone); | ||
| 130 | goto found; | ||
| 131 | } | 63 | } |
| 132 | 64 | } | |
| 133 | iphone_free_device(phone); | ||
| 134 | |||
| 135 | log_debug_msg("iphone_get_specific_device: iPhone not found\n"); | ||
| 136 | return IPHONE_E_NO_DEVICE; | ||
| 137 | |||
| 138 | found: | ||
| 139 | // Send the version command to the phone | ||
| 140 | version = version_header(); | ||
| 141 | bytes = usb_bulk_write(phone->device, BULKOUT, (char *) version, sizeof(*version), 800); | ||
| 142 | if (bytes < 20) { | ||
| 143 | log_debug_msg("get_iPhone(): libusb did NOT send enough!\n"); | ||
| 144 | if (bytes < 0) { | ||
| 145 | log_debug_msg("get_iPhone(): libusb gave me the error %d: %s (%s)\n", | ||
| 146 | bytes, usb_strerror(), strerror(-bytes)); | ||
| 147 | } | 65 | } |
| 148 | } | 66 | free(dev_list); |
| 149 | // Read the phone's response | ||
| 150 | bytes = usb_bulk_read(phone->device, BULKIN, (char *) version, sizeof(*version), 800); | ||
| 151 | 67 | ||
| 152 | // Check for bad response | 68 | if (handle > 0) { |
| 153 | if (bytes < 20) { | 69 | phone = (iphone_device_t) malloc(sizeof(struct iphone_device_int)); |
| 154 | free(version); | 70 | phone->handle = handle; |
| 155 | iphone_free_device(phone); | 71 | *device = phone; |
| 156 | log_debug_msg("get_iPhone(): Invalid version message -- header too short.\n"); | 72 | return IPHONE_E_SUCCESS; |
| 157 | if (bytes < 0) | 73 | } |
| 158 | log_debug_msg("get_iPhone(): libusb error message %d: %s (%s)\n", bytes, usb_strerror(), strerror(-bytes)); | ||
| 159 | return IPHONE_E_NOT_ENOUGH_DATA; | ||
| 160 | } | ||
| 161 | // Check for correct version | ||
| 162 | if (ntohl(version->major) == 1 && ntohl(version->minor) == 0) { | ||
| 163 | // We're all ready to roll. | ||
| 164 | log_debug_msg("get_iPhone() success\n"); | ||
| 165 | free(version); | ||
| 166 | *device = phone; | ||
| 167 | return IPHONE_E_SUCCESS; | ||
| 168 | } else { | ||
| 169 | // Bad header | ||
| 170 | log_debug_msg("get_iPhone(): Received a bad header/invalid version number.\n"); | ||
| 171 | log_debug_buffer((char *) version, sizeof(*version)); | ||
| 172 | iphone_free_device(phone); | ||
| 173 | free(version); | ||
| 174 | return IPHONE_E_BAD_HEADER; | ||
| 175 | } | 74 | } |
| 176 | 75 | ||
| 177 | // If it got to this point it's gotta be bad | 76 | return IPHONE_E_NO_DEVICE; |
| 178 | log_debug_msg("get_iPhone(): Unknown error.\n"); | ||
| 179 | iphone_free_device(phone); | ||
| 180 | free(version); | ||
| 181 | return IPHONE_E_UNKNOWN_ERROR; // if it got to this point it's gotta be bad | ||
| 182 | } | 77 | } |
| 183 | 78 | ||
| 184 | /** | 79 | /** |
| 185 | * Scans all USB busses and devices for a known AFC-compatible device and | 80 | * This function has the purpose to retrieve a handle to the first |
| 186 | * returns a handle to the first such device it finds. Known devices include | 81 | * attached iPhone/iPod reported by usbmuxd. |
| 187 | * those with vendor ID 0x05ac and product ID between 0x1290 and 0x1293 | ||
| 188 | * inclusive. | ||
| 189 | * | 82 | * |
| 190 | * This function is convenient, but on systems where higher-level abstractions | 83 | * @param Upon calling this function, a pointer to a location of type |
| 191 | * (such as HAL) are available it may be preferable to use | ||
| 192 | * iphone_get_specific_device instead, because it can deal with multiple | ||
| 193 | * connected devices as well as devices not known to libiphone. | ||
| 194 | * | ||
| 195 | * @param device Upon calling this function, a pointer to a location of type | ||
| 196 | * iphone_device_t, which must have the value NULL. On return, this location | 84 | * iphone_device_t, which must have the value NULL. On return, this location |
| 197 | * will be filled with a handle to the device. | 85 | * will be filled with a handle to the device. |
| 86 | * | ||
| 198 | * @return IPHONE_E_SUCCESS if ok, otherwise an error code. | 87 | * @return IPHONE_E_SUCCESS if ok, otherwise an error code. |
| 199 | */ | 88 | */ |
| 200 | iphone_error_t iphone_get_device(iphone_device_t * device) | 89 | iphone_error_t iphone_get_device(iphone_device_t * device) |
| 201 | { | 90 | { |
| 202 | struct usb_bus *bus; | 91 | return iphone_get_device_by_uuid(device, NULL); |
| 203 | struct usb_device *dev; | 92 | } |
| 204 | |||
| 205 | usb_init(); | ||
| 206 | usb_find_busses(); | ||
| 207 | usb_find_devices(); | ||
| 208 | |||
| 209 | for (bus = usb_get_busses(); bus != NULL; bus = bus->next) | ||
| 210 | for (dev = bus->devices; dev != NULL; dev = dev->next) | ||
| 211 | if (dev->descriptor.idVendor == 0x05ac | ||
| 212 | && dev->descriptor.idProduct >= 0x1290 && dev->descriptor.idProduct <= 0x1293) | ||
| 213 | return iphone_get_specific_device(strtoul(bus->dirname, NULL, 10), strtol(dev->filename, NULL, 10), device); | ||
| 214 | 93 | ||
| 215 | return IPHONE_E_NO_DEVICE; | 94 | uint32_t iphone_get_device_handle(iphone_device_t device) |
| 95 | { | ||
| 96 | if (device) { | ||
| 97 | return device->handle; | ||
| 98 | } else { | ||
| 99 | return 0; | ||
| 100 | } | ||
| 216 | } | 101 | } |
| 217 | 102 | ||
| 218 | /** Cleans up an iPhone structure, then frees the structure itself. | 103 | /** Cleans up an iPhone structure, then frees the structure itself. |
| @@ -226,88 +111,10 @@ iphone_error_t iphone_free_device(iphone_device_t device) | |||
| 226 | if (!device) | 111 | if (!device) |
| 227 | return IPHONE_E_INVALID_ARG; | 112 | return IPHONE_E_INVALID_ARG; |
| 228 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 113 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 229 | int bytes; | ||
| 230 | unsigned char buf[512]; | ||
| 231 | 114 | ||
| 232 | // read final package(s) | 115 | ret = IPHONE_E_SUCCESS; |
| 233 | if (device->device != NULL) { | ||
| 234 | do { | ||
| 235 | bytes = usb_bulk_read(device->device, BULKIN, (void *) &buf, 512, 800); | ||
| 236 | if (bytes > 0) { | ||
| 237 | log_debug_msg("iphone_free_device: final read returned\n"); | ||
| 238 | log_debug_buffer(buf, bytes); | ||
| 239 | } | ||
| 240 | } while (bytes > 0); | ||
| 241 | } | ||
| 242 | 116 | ||
| 243 | if (device->buffer) { | ||
| 244 | free(device->buffer); | ||
| 245 | } | ||
| 246 | if (device->device) { | ||
| 247 | usb_release_interface(device->device, 1); | ||
| 248 | usb_close(device->device); | ||
| 249 | ret = IPHONE_E_SUCCESS; | ||
| 250 | } | ||
| 251 | free(device); | 117 | free(device); |
| 252 | return ret; | 118 | return ret; |
| 253 | } | 119 | } |
| 254 | 120 | ||
| 255 | /** Sends data to the phone | ||
| 256 | * This is a low-level (i.e. directly to phone) function. | ||
| 257 | * | ||
| 258 | * @param phone The iPhone to send data to | ||
| 259 | * @param data The data to send to the iPhone | ||
| 260 | * @param datalen The length of the data | ||
| 261 | * @return The number of bytes sent, or -1 on error or something. | ||
| 262 | */ | ||
| 263 | int send_to_phone(iphone_device_t phone, char *data, int datalen) | ||
| 264 | { | ||
| 265 | if (!phone) | ||
| 266 | return -1; | ||
| 267 | int bytes = 0; | ||
| 268 | |||
| 269 | if (!phone) | ||
| 270 | return -1; | ||
| 271 | log_debug_msg("send_to_phone: Attempting to send datalen = %i data = %p\n", datalen, data); | ||
| 272 | |||
| 273 | bytes = usb_bulk_write(phone->device, BULKOUT, data, datalen, 800); | ||
| 274 | if (bytes < datalen) { | ||
| 275 | if (bytes < 0) | ||
| 276 | log_debug_msg("send_to_iphone(): libusb gave me the error %d: %s - %s\n", bytes, usb_strerror(), | ||
| 277 | strerror(-bytes)); | ||
| 278 | return -1; | ||
| 279 | } else { | ||
| 280 | return bytes; | ||
| 281 | } | ||
| 282 | /* Should not be reached */ | ||
| 283 | return -1; | ||
| 284 | } | ||
| 285 | |||
| 286 | /** This function is a low-level (i.e. direct to iPhone) function. | ||
| 287 | * | ||
| 288 | * @param phone The iPhone to receive data from | ||
| 289 | * @param data Where to put data read | ||
| 290 | * @param datalen How much data to read in | ||
| 291 | * @param timeout How many milliseconds to wait for data | ||
| 292 | * | ||
| 293 | * @return How many bytes were read in, or -1 on error. | ||
| 294 | */ | ||
| 295 | int recv_from_phone(iphone_device_t phone, char *data, int datalen, int timeout) | ||
| 296 | { | ||
| 297 | if (!phone) | ||
| 298 | return -1; | ||
| 299 | int bytes = 0; | ||
| 300 | |||
| 301 | if (!phone) | ||
| 302 | return -1; | ||
| 303 | log_debug_msg("recv_from_phone(): attempting to receive %i bytes\n", datalen); | ||
| 304 | |||
| 305 | bytes = usb_bulk_read(phone->device, BULKIN, data, datalen, timeout); | ||
| 306 | if (bytes < 0) { | ||
| 307 | log_debug_msg("recv_from_phone(): libusb gave me the error %d: %s (%s)\n", bytes, usb_strerror(), | ||
| 308 | strerror(-bytes)); | ||
| 309 | return -1; | ||
| 310 | } | ||
| 311 | |||
| 312 | return bytes; | ||
| 313 | } | ||
diff --git a/src/iphone.h b/src/iphone.h index 15515e3..94d2f9f 100644 --- a/src/iphone.h +++ b/src/iphone.h | |||
| @@ -22,24 +22,11 @@ | |||
| 22 | #ifndef IPHONE_H | 22 | #ifndef IPHONE_H |
| 23 | #define IPHONE_H | 23 | #define IPHONE_H |
| 24 | 24 | ||
| 25 | #ifndef USBMUX_H | 25 | #include <stdint.h> |
| 26 | #include "usbmux.h" | ||
| 27 | #warning usbmux not included? | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #include <usb.h> | ||
| 31 | #include <libiphone/libiphone.h> | ||
| 32 | |||
| 33 | #define BULKIN 0x85 | ||
| 34 | #define BULKOUT 0x04 | ||
| 35 | 26 | ||
| 36 | struct iphone_device_int { | 27 | struct iphone_device_int { |
| 37 | char *buffer; | 28 | char *buffer; |
| 38 | struct usb_dev_handle *device; | 29 | uint32_t handle; |
| 39 | struct usb_device *__device; | ||
| 40 | }; | 30 | }; |
| 41 | 31 | ||
| 42 | // Function definitions | ||
| 43 | int send_to_phone(iphone_device_t phone, char *data, int datalen); | ||
| 44 | int recv_from_phone(iphone_device_t phone, char *data, int datalen, int timeout); | ||
| 45 | #endif | 32 | #endif |
diff --git a/src/lockdown.c b/src/lockdown.c index 5ade79a..28670de 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "usbmux.h" | ||
| 23 | #include "utils.h" | 22 | #include "utils.h" |
| 24 | #include "iphone.h" | 23 | #include "iphone.h" |
| 25 | #include "lockdown.h" | 24 | #include "lockdown.h" |
| @@ -53,13 +52,15 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) | |||
| 53 | { | 52 | { |
| 54 | if (!phone) | 53 | if (!phone) |
| 55 | return NULL; | 54 | return NULL; |
| 56 | iphone_lckd_client_t control = (iphone_lckd_client_t) malloc(sizeof(struct iphone_lckd_client_int)); | ||
| 57 | 55 | ||
| 58 | if (IPHONE_E_SUCCESS != iphone_mux_new_client(phone, 0x0a00, 0xf27e, &control->connection)) { | 56 | int sfd = usbmuxd_connect(phone->handle, 0xf27e); |
| 59 | free(control); | 57 | if (sfd < 0) { |
| 58 | log_debug_msg("%s: could not connect to lockdownd (device handle %d)\n", __func__, phone->handle); | ||
| 60 | return NULL; | 59 | return NULL; |
| 61 | } | 60 | } |
| 62 | 61 | ||
| 62 | iphone_lckd_client_t control = (iphone_lckd_client_t) malloc(sizeof(struct iphone_lckd_client_int)); | ||
| 63 | control->sfd = sfd; | ||
| 63 | control->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t)); | 64 | control->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t)); |
| 64 | control->in_SSL = 0; | 65 | control->in_SSL = 0; |
| 65 | return control; | 66 | return control; |
| @@ -167,13 +168,13 @@ iphone_error_t iphone_lckd_free_client(iphone_lckd_client_t client) | |||
| 167 | 168 | ||
| 168 | iphone_lckd_stop_SSL_session(client); | 169 | iphone_lckd_stop_SSL_session(client); |
| 169 | 170 | ||
| 170 | if (client->connection) { | 171 | if (client->sfd > 0) { |
| 171 | lockdownd_close(client); | 172 | lockdownd_close(client); |
| 172 | 173 | ||
| 173 | // IMO, read of final "sessionUpcall connection closed" packet | 174 | // IMO, read of final "sessionUpcall connection closed" packet |
| 174 | // should come here instead of in iphone_free_device | 175 | // should come here instead of in iphone_free_device |
| 175 | 176 | ||
| 176 | ret = iphone_mux_free_client(client->connection); | 177 | ret = usbmuxd_disconnect(client->sfd); |
| 177 | } | 178 | } |
| 178 | 179 | ||
| 179 | free(client); | 180 | free(client); |
| @@ -197,7 +198,7 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist) | |||
| 197 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; | 198 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; |
| 198 | 199 | ||
| 199 | if (!client->in_SSL) | 200 | if (!client->in_SSL) |
| 200 | ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes); | 201 | ret = usbmuxd_recv(client->sfd, (char *) &datalen, sizeof(datalen), &bytes); |
| 201 | else { | 202 | else { |
| 202 | bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); | 203 | bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); |
| 203 | if (bytes > 0) | 204 | if (bytes > 0) |
| @@ -210,7 +211,7 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist) | |||
| 210 | if (!client->in_SSL) { | 211 | if (!client->in_SSL) { |
| 211 | /* fill buffer and request more packets if needed */ | 212 | /* fill buffer and request more packets if needed */ |
| 212 | while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { | 213 | while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { |
| 213 | ret = iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes); | 214 | ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); //iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes); |
| 214 | received_bytes += bytes; | 215 | received_bytes += bytes; |
| 215 | } | 216 | } |
| 216 | } else { | 217 | } else { |
| @@ -271,7 +272,7 @@ iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, plist_t plist) | |||
| 271 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): made the query, sending it along\n"); | 272 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): made the query, sending it along\n"); |
| 272 | 273 | ||
| 273 | if (!client->in_SSL) | 274 | if (!client->in_SSL) |
| 274 | ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes); | 275 | ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); //iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes); |
| 275 | else { | 276 | else { |
| 276 | gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); | 277 | gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); |
| 277 | ret = IPHONE_E_SUCCESS; | 278 | ret = IPHONE_E_SUCCESS; |
| @@ -465,7 +466,7 @@ iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid | |||
| 465 | * | 466 | * |
| 466 | * @note You most likely want lockdownd_init unless you are doing something special. | 467 | * @note You most likely want lockdownd_init unless you are doing something special. |
| 467 | * | 468 | * |
| 468 | * @return 1 on success and 0 on failure. | 469 | * @return IPHONE_E_SUCCESS on succes or an error value < 0 on failure. |
| 469 | */ | 470 | */ |
| 470 | iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key) | 471 | iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key) |
| 471 | { | 472 | { |
| @@ -1026,7 +1027,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size | |||
| 1026 | control = (iphone_lckd_client_t) transport; | 1027 | control = (iphone_lckd_client_t) transport; |
| 1027 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_secuwrite() called\n"); | 1028 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_secuwrite() called\n"); |
| 1028 | log_dbg_msg(DBGMASK_LOCKDOWND, "pre-send\nlength = %zi\n", length); | 1029 | log_dbg_msg(DBGMASK_LOCKDOWND, "pre-send\nlength = %zi\n", length); |
| 1029 | iphone_mux_send(control->connection, buffer, length, &bytes); | 1030 | usbmuxd_send(control->sfd, buffer, length, &bytes); |
| 1030 | log_dbg_msg(DBGMASK_LOCKDOWND, "post-send\nsent %i bytes\n", bytes); | 1031 | log_dbg_msg(DBGMASK_LOCKDOWND, "post-send\nsent %i bytes\n", bytes); |
| 1031 | 1032 | ||
| 1032 | dump_debug_buffer("sslpacketwrite.out", buffer, length); | 1033 | dump_debug_buffer("sslpacketwrite.out", buffer, length); |
| @@ -1059,7 +1060,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ | |||
| 1059 | 1060 | ||
| 1060 | // repeat until we have the full data or an error occurs. | 1061 | // repeat until we have the full data or an error occurs. |
| 1061 | do { | 1062 | do { |
| 1062 | if ((res = iphone_mux_recv(control->connection, recv_buffer, this_len, &bytes)) != IPHONE_E_SUCCESS) { | 1063 | if ((res = usbmuxd_recv(control->sfd, recv_buffer, this_len, &bytes)) != IPHONE_E_SUCCESS) { |
| 1063 | log_debug_msg("%s: ERROR: iphone_mux_recv returned %d\n", __func__, res); | 1064 | log_debug_msg("%s: ERROR: iphone_mux_recv returned %d\n", __func__, res); |
| 1064 | return res; | 1065 | return res; |
| 1065 | } | 1066 | } |
diff --git a/src/lockdown.h b/src/lockdown.h index 7485006..1f9d84c 100644 --- a/src/lockdown.h +++ b/src/lockdown.h | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | #ifndef LOCKDOWND_H | 22 | #ifndef LOCKDOWND_H |
| 23 | #define LOCKDOWND_H | 23 | #define LOCKDOWND_H |
| 24 | 24 | ||
| 25 | #include "usbmux.h" | ||
| 26 | |||
| 27 | #include <gnutls/gnutls.h> | 25 | #include <gnutls/gnutls.h> |
| 28 | #include <string.h> | 26 | #include <string.h> |
| 29 | #include <libiphone/libiphone.h> | 27 | #include <libiphone/libiphone.h> |
| @@ -32,7 +30,7 @@ | |||
| 32 | 30 | ||
| 33 | 31 | ||
| 34 | struct iphone_lckd_client_int { | 32 | struct iphone_lckd_client_int { |
| 35 | iphone_umux_client_t connection; | 33 | int sfd; |
| 36 | gnutls_session_t *ssl_session; | 34 | gnutls_session_t *ssl_session; |
| 37 | int in_SSL; | 35 | int in_SSL; |
| 38 | char session_id[40]; | 36 | char session_id[40]; |
diff --git a/src/usbmux.c b/src/usbmux.c deleted file mode 100644 index 7d74b4b..0000000 --- a/src/usbmux.c +++ /dev/null | |||
| @@ -1,410 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * usbmux.c | ||
| 3 | * Interprets the usb multiplexing protocol used by the iPhone. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2008 Zach C. All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <sys/types.h> | ||
| 23 | #include <arpa/inet.h> | ||
| 24 | #include <stdio.h> | ||
| 25 | #include <stdlib.h> | ||
| 26 | #include <string.h> | ||
| 27 | |||
| 28 | #include "usbmux.h" | ||
| 29 | #include "utils.h" | ||
| 30 | |||
| 31 | static iphone_umux_client_t *connlist = NULL; | ||
| 32 | static int clients = 0; | ||
| 33 | |||
| 34 | /** Creates a USBMux packet for the given set of ports. | ||
| 35 | * | ||
| 36 | * @param s_port The source port for the connection. | ||
| 37 | * @param d_port The destination port for the connection. | ||
| 38 | * | ||
| 39 | * @return A USBMux packet | ||
| 40 | */ | ||
| 41 | usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port) | ||
| 42 | { | ||
| 43 | usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); | ||
| 44 | conn->type = htonl(6); | ||
| 45 | conn->length = 28; | ||
| 46 | conn->sport = htons(s_port); | ||
| 47 | conn->dport = htons(d_port); | ||
| 48 | conn->scnt = 0; | ||
| 49 | conn->ocnt = 0; | ||
| 50 | conn->offset = 0x50; | ||
| 51 | conn->window = htons(0x0200); | ||
| 52 | conn->nullnull = 0x0000; | ||
| 53 | conn->length16 = 28; | ||
| 54 | return conn; | ||
| 55 | } | ||
| 56 | |||
| 57 | /** Creates a USBMux header containing version information | ||
| 58 | * | ||
| 59 | * @return A USBMux header | ||
| 60 | */ | ||
| 61 | usbmux_version_header *version_header(void) | ||
| 62 | { | ||
| 63 | usbmux_version_header *version = (usbmux_version_header *) malloc(sizeof(usbmux_version_header)); | ||
| 64 | version->type = 0; | ||
| 65 | version->length = htonl(20); | ||
| 66 | version->major = htonl(1); | ||
| 67 | version->minor = 0; | ||
| 68 | version->allnull = 0; | ||
| 69 | return version; | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | // Maintenance functions. | ||
| 74 | |||
| 75 | /** Removes a connection from the list of connections made. | ||
| 76 | * The list of connections is necessary for buffering. | ||
| 77 | * | ||
| 78 | * @param connection The connection to delete from the tracking list. | ||
| 79 | */ | ||
| 80 | static void delete_connection(iphone_umux_client_t connection) | ||
| 81 | { | ||
| 82 | iphone_umux_client_t *newlist = (iphone_umux_client_t *) malloc(sizeof(iphone_umux_client_t) * (clients - 1)); | ||
| 83 | int i = 0, j = 0; | ||
| 84 | for (i = 0; i < clients; i++) { | ||
| 85 | if (connlist[i] == connection) | ||
| 86 | continue; | ||
| 87 | else { | ||
| 88 | newlist[j] = connlist[i]; | ||
| 89 | j++; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | free(connlist); | ||
| 93 | connlist = newlist; | ||
| 94 | clients--; | ||
| 95 | if (connection->recv_buffer) | ||
| 96 | free(connection->recv_buffer); | ||
| 97 | if (connection->header) | ||
| 98 | free(connection->header); | ||
| 99 | connection->r_len = 0; | ||
| 100 | free(connection); | ||
| 101 | } | ||
| 102 | |||
| 103 | /** Adds a connection to the list of connections made. | ||
| 104 | * The connection list is necessary for buffering. | ||
| 105 | * | ||
| 106 | * @param connection The connection to add to the global list of connections. | ||
| 107 | */ | ||
| 108 | |||
| 109 | static void add_connection(iphone_umux_client_t connection) | ||
| 110 | { | ||
| 111 | iphone_umux_client_t *newlist = | ||
| 112 | (iphone_umux_client_t *) realloc(connlist, sizeof(iphone_umux_client_t) * (clients + 1)); | ||
| 113 | newlist[clients] = connection; | ||
| 114 | connlist = newlist; | ||
| 115 | clients++; | ||
| 116 | } | ||
| 117 | |||
| 118 | /** Initializes a connection on phone, with source port s_port and destination port d_port | ||
| 119 | * | ||
| 120 | * @param device The iPhone to initialize a connection on. | ||
| 121 | * @param src_port The source port | ||
| 122 | * @param dst_port The destination port -- 0xf27e for lockdownd. | ||
| 123 | * @param client A mux TCP header for the connection which is used for tracking and data transfer. | ||
| 124 | * @return IPHONE_E_SUCCESS on success, an error code otherwise. | ||
| 125 | */ | ||
| 126 | iphone_error_t iphone_mux_new_client(iphone_device_t device, uint16_t src_port, uint16_t dst_port, | ||
| 127 | iphone_umux_client_t * client) | ||
| 128 | { | ||
| 129 | if (!device || !src_port || !dst_port) | ||
| 130 | return IPHONE_E_INVALID_ARG; | ||
| 131 | |||
| 132 | int bytes = 0; | ||
| 133 | // Initialize connection stuff | ||
| 134 | iphone_umux_client_t new_connection = (iphone_umux_client_t) malloc(sizeof(struct iphone_umux_client_int)); | ||
| 135 | new_connection->header = new_mux_packet(src_port, dst_port); | ||
| 136 | |||
| 137 | // blargg | ||
| 138 | if (new_connection && new_connection->header) { | ||
| 139 | new_connection->header->tcp_flags = 0x02; | ||
| 140 | new_connection->header->length = htonl(new_connection->header->length); | ||
| 141 | new_connection->header->length16 = htons(new_connection->header->length16); | ||
| 142 | |||
| 143 | if (send_to_phone(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { | ||
| 144 | usbmux_tcp_header *response; | ||
| 145 | response = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); | ||
| 146 | bytes = recv_from_phone(device, (char *) response, sizeof(*response), 3500); | ||
| 147 | if (response->tcp_flags != 0x12) { | ||
| 148 | free(response); | ||
| 149 | return IPHONE_E_UNKNOWN_ERROR; | ||
| 150 | } else { | ||
| 151 | free(response); | ||
| 152 | |||
| 153 | log_debug_msg("mux_connect: connection success\n"); | ||
| 154 | new_connection->header->tcp_flags = 0x10; | ||
| 155 | new_connection->header->scnt = 1; | ||
| 156 | new_connection->header->ocnt = 1; | ||
| 157 | new_connection->phone = device; | ||
| 158 | new_connection->recv_buffer = NULL; | ||
| 159 | new_connection->r_len = 0; | ||
| 160 | add_connection(new_connection); | ||
| 161 | *client = new_connection; | ||
| 162 | return IPHONE_E_SUCCESS; | ||
| 163 | } | ||
| 164 | } else { | ||
| 165 | return IPHONE_E_NOT_ENOUGH_DATA; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | // if we get to this point it's probably bad | ||
| 169 | return IPHONE_E_UNKNOWN_ERROR; | ||
| 170 | } | ||
| 171 | |||
| 172 | /** Cleans up the given USBMux connection. | ||
| 173 | * @note Once a connection is closed it may not be used again. | ||
| 174 | * | ||
| 175 | * @param connection The connection to close. | ||
| 176 | * | ||
| 177 | * @return IPHONE_E_SUCCESS on success. | ||
| 178 | */ | ||
| 179 | iphone_error_t iphone_mux_free_client(iphone_umux_client_t client) | ||
| 180 | { | ||
| 181 | if (!client || !client->phone) | ||
| 182 | return IPHONE_E_INVALID_ARG; | ||
| 183 | |||
| 184 | client->header->tcp_flags = 0x04; | ||
| 185 | client->header->length = htonl(0x1C); | ||
| 186 | client->header->scnt = htonl(client->header->scnt); | ||
| 187 | client->header->ocnt = htonl(client->header->ocnt); | ||
| 188 | client->header->window = 0; | ||
| 189 | client->header->length16 = htons(0x1C); | ||
| 190 | int bytes = 0; | ||
| 191 | |||
| 192 | bytes = usb_bulk_write(client->phone->device, BULKOUT, (char *) client->header, sizeof(usbmux_tcp_header), 800); | ||
| 193 | if (bytes < 0) | ||
| 194 | log_debug_msg("iphone_muxèfree_client(): when writing, libusb gave me the error: %s\n", usb_strerror()); | ||
| 195 | |||
| 196 | bytes = usb_bulk_read(client->phone->device, BULKIN, (char *) client->header, sizeof(usbmux_tcp_header), 800); | ||
| 197 | if (bytes < 0) | ||
| 198 | log_debug_msg("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); | ||
| 199 | |||
| 200 | delete_connection(client); | ||
| 201 | |||
| 202 | return IPHONE_E_SUCCESS; | ||
| 203 | } | ||
| 204 | |||
| 205 | |||
| 206 | /** Sends the given data over the selected connection. | ||
| 207 | * | ||
| 208 | * @param phone The iPhone to send to. | ||
| 209 | * @param client The client we're sending data on. | ||
| 210 | * @param data A pointer to the data to send. | ||
| 211 | * @param datalen How much data we're sending. | ||
| 212 | * @param sent_bytes The number of bytes sent, minus the header (28) | ||
| 213 | * | ||
| 214 | * @return IPHONE_E_SUCCESS on success. | ||
| 215 | */ | ||
| 216 | |||
| 217 | iphone_error_t iphone_mux_send(iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t * sent_bytes) | ||
| 218 | { | ||
| 219 | if (!client->phone || !client || !data || datalen == 0 || !sent_bytes) | ||
| 220 | return IPHONE_E_INVALID_ARG; | ||
| 221 | // client->scnt and client->ocnt should already be in host notation... | ||
| 222 | // we don't need to change them juuuust yet. | ||
| 223 | *sent_bytes = 0; | ||
| 224 | log_debug_msg("mux_send(): client wants to send %i bytes\n", datalen); | ||
| 225 | char *buffer = (char *) malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding | ||
| 226 | // Set the length and pre-emptively htonl/htons it | ||
| 227 | client->header->length = htonl(sizeof(usbmux_tcp_header) + datalen); | ||
| 228 | client->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen); | ||
| 229 | |||
| 230 | // Put scnt and ocnt into big-endian notation | ||
| 231 | client->header->scnt = htonl(client->header->scnt); | ||
| 232 | client->header->ocnt = htonl(client->header->ocnt); | ||
| 233 | // Concatenation of stuff in the buffer. | ||
| 234 | memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); | ||
| 235 | memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen); | ||
| 236 | |||
| 237 | // We have a buffer full of data, we should now send it to the phone. | ||
| 238 | log_debug_msg("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header) + datalen, buffer); | ||
| 239 | |||
| 240 | |||
| 241 | *sent_bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header) + datalen); | ||
| 242 | log_debug_msg("mux_send: sent %i bytes!\n", *sent_bytes); | ||
| 243 | // Now that we've sent it off, we can clean up after our sloppy selves. | ||
| 244 | dump_debug_buffer("packet", buffer, *sent_bytes); | ||
| 245 | if (buffer) | ||
| 246 | free(buffer); | ||
| 247 | // Re-calculate scnt and ocnt | ||
| 248 | client->header->scnt = ntohl(client->header->scnt) + datalen; | ||
| 249 | client->header->ocnt = ntohl(client->header->ocnt); | ||
| 250 | |||
| 251 | // Revert lengths | ||
| 252 | client->header->length = ntohl(client->header->length); | ||
| 253 | client->header->length16 = ntohs(client->header->length16); | ||
| 254 | |||
| 255 | // Now return the bytes. | ||
| 256 | if (*sent_bytes < sizeof(usbmux_tcp_header) + datalen) { | ||
| 257 | *sent_bytes = 0; | ||
| 258 | return IPHONE_E_NOT_ENOUGH_DATA; | ||
| 259 | } else { | ||
| 260 | *sent_bytes = *sent_bytes - 28; // actual length sent. :/ | ||
| 261 | } | ||
| 262 | |||
| 263 | return IPHONE_E_SUCCESS; | ||
| 264 | } | ||
| 265 | |||
| 266 | /** This is a higher-level USBMuxTCP-like function | ||
| 267 | * | ||
| 268 | * @param connection The connection to receive data on. | ||
| 269 | * @param data Where to put the data we receive. | ||
| 270 | * @param datalen How much data to read. | ||
| 271 | * @param recv_bytes Pointer to a uint32_t that will be set | ||
| 272 | * to the number of bytes received. | ||
| 273 | * @param timeout How many milliseconds to wait for data. | ||
| 274 | * | ||
| 275 | * @return IPHONE_E_SUCCESS on success, or and error value. | ||
| 276 | */ | ||
| 277 | iphone_error_t iphone_mux_recv_timeout(iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t * recv_bytes, int timeout) | ||
| 278 | { | ||
| 279 | |||
| 280 | if (!client || !data || datalen == 0 || !recv_bytes) | ||
| 281 | return IPHONE_E_INVALID_ARG; | ||
| 282 | /* | ||
| 283 | * Order of operation: | ||
| 284 | * 1.) Check if the client has a pre-received buffer. | ||
| 285 | * 2.) If so, fill data with the buffer, as much as needed. | ||
| 286 | * a.) Return quickly if the buffer has enough | ||
| 287 | * b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return) | ||
| 288 | * 3.) If not, receive directly from the phone. | ||
| 289 | * a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation. | ||
| 290 | * b.) If not, find the client the ports belong to and fill that client's buffer, then return mux_recv with the same args to try again. | ||
| 291 | */ | ||
| 292 | log_debug_msg("mux_recv: datalen == %i\n", datalen); | ||
| 293 | int bytes = 0, i = 0, complex = 0, offset = 0; | ||
| 294 | *recv_bytes = 0; | ||
| 295 | char *buffer = NULL; | ||
| 296 | usbmux_tcp_header *header = NULL; | ||
| 297 | |||
| 298 | if (client->recv_buffer) { | ||
| 299 | if (client->r_len >= datalen) { | ||
| 300 | memcpy(data, client->recv_buffer, datalen); | ||
| 301 | if (client->r_len == datalen) { | ||
| 302 | // reset everything | ||
| 303 | free(client->recv_buffer); | ||
| 304 | client->r_len = 0; | ||
| 305 | client->recv_buffer = NULL; | ||
| 306 | } else { | ||
| 307 | buffer = (char *) malloc(sizeof(char) * (client->r_len - datalen)); | ||
| 308 | memcpy(buffer, client->recv_buffer + datalen, (client->r_len - datalen)); | ||
| 309 | client->r_len -= datalen; | ||
| 310 | free(client->recv_buffer); | ||
| 311 | client->recv_buffer = buffer; | ||
| 312 | } | ||
| 313 | |||
| 314 | // Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above. | ||
| 315 | *recv_bytes = datalen; | ||
| 316 | return IPHONE_E_SUCCESS; | ||
| 317 | } else { | ||
| 318 | memcpy(data, client->recv_buffer, client->r_len); | ||
| 319 | free(client->recv_buffer); // don't need to deal with anymore, but... | ||
| 320 | client->recv_buffer = NULL; | ||
| 321 | offset = client->r_len; // see #2b, above | ||
| 322 | client->r_len = 0; | ||
| 323 | } | ||
| 324 | } // End of what to do if we have a pre-buffer. See #1 and #2 above. | ||
| 325 | |||
| 326 | buffer = (char *) malloc(sizeof(char) * 131072); // make sure we get enough ;) | ||
| 327 | |||
| 328 | // See #3. | ||
| 329 | bytes = recv_from_phone(client->phone, buffer, 131072, timeout); | ||
| 330 | if (bytes < 28) { | ||
| 331 | free(buffer); | ||
| 332 | log_debug_msg("mux_recv: Did not even get the header.\n"); | ||
| 333 | return IPHONE_E_NOT_ENOUGH_DATA; | ||
| 334 | } | ||
| 335 | |||
| 336 | header = (usbmux_tcp_header *) buffer; | ||
| 337 | if (header->sport != client->header->dport || header->dport != client->header->sport) { | ||
| 338 | // Ooooops -- we got someone else's packet. | ||
| 339 | // We gotta stick it in their buffer. (Take that any old way you want ;) ) | ||
| 340 | for (i = 0; i < clients; i++) { | ||
| 341 | if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) { | ||
| 342 | // we have a winner. | ||
| 343 | char *nfb = (char *) malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); | ||
| 344 | if (connlist[i]->recv_buffer && connlist[i]->r_len) { | ||
| 345 | memcpy(nfb, connlist[i]->recv_buffer, connlist[i]->r_len); | ||
| 346 | free(connlist[i]->recv_buffer); | ||
| 347 | } | ||
| 348 | connlist[i]->r_len += bytes - 28; | ||
| 349 | //connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * client->r_len); // grow their buffer | ||
| 350 | connlist[i]->recv_buffer = nfb; | ||
| 351 | nfb = NULL; // A cookie for you if you can guess what "nfb" means. | ||
| 352 | complex = connlist[i]->r_len - (bytes - 28); | ||
| 353 | memcpy(connlist[i]->recv_buffer + complex, buffer + 28, bytes - 28); // paste into their buffer | ||
| 354 | connlist[i]->header->ocnt += bytes - 28; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | // If it wasn't ours, it's been handled by this point... or forgotten. | ||
| 358 | // Free our buffer and continue. | ||
| 359 | free(buffer); | ||
| 360 | buffer = NULL; | ||
| 361 | return iphone_mux_recv(client, data, datalen, recv_bytes); // recurse back in to try again | ||
| 362 | } | ||
| 363 | // The packet was absolutely meant for us if it hits this point. | ||
| 364 | // The pre-buffer has been taken care of, so, again, if we're at this point we have to read from the phone. | ||
| 365 | |||
| 366 | if ((bytes - 28) > datalen) { | ||
| 367 | // Copy what we need into the data, buffer the rest because we can. | ||
| 368 | memcpy(data + offset, buffer + 28, datalen); // data+offset: see #2b, above | ||
| 369 | complex = client->r_len + ((bytes - 28) - datalen); | ||
| 370 | client->recv_buffer = (char *) realloc(client->recv_buffer, (sizeof(char) * complex)); | ||
| 371 | client->r_len = complex; | ||
| 372 | complex = client->r_len - ((bytes - 28) - datalen); | ||
| 373 | memcpy(client->recv_buffer + complex, buffer + 28 + datalen, (bytes - 28) - datalen); | ||
| 374 | free(buffer); | ||
| 375 | client->header->ocnt += bytes - 28; | ||
| 376 | *recv_bytes = datalen; | ||
| 377 | return IPHONE_E_SUCCESS; | ||
| 378 | } else { | ||
| 379 | // Fill the data with what we have, and just return. | ||
| 380 | memcpy(data + offset, buffer + 28, bytes - 28); // data+offset: see #2b, above | ||
| 381 | client->header->ocnt += bytes - 28; | ||
| 382 | free(buffer); | ||
| 383 | *recv_bytes = bytes - 28; | ||
| 384 | return IPHONE_E_SUCCESS; | ||
| 385 | } | ||
| 386 | |||
| 387 | // If we get to this point, 'tis probably bad. | ||
| 388 | log_debug_msg("mux_recv: Heisenbug: bytes and datalen not matching up\n"); | ||
| 389 | return IPHONE_E_UNKNOWN_ERROR; | ||
| 390 | } | ||
| 391 | |||
| 392 | /** | ||
| 393 | * This function is just like 'iphone_mux_recv_timeout' but you do not need | ||
| 394 | * to specify a timeout. It simply calls iphone_mux_recv_timeout with a | ||
| 395 | * timeout value of 3500 milliseconds. | ||
| 396 | * | ||
| 397 | * @param connection The connection to receive data on. | ||
| 398 | * @param data Where to put the data we receive. | ||
| 399 | * @param datalen How much data to read. | ||
| 400 | * @param recv_bytes Pointer to a uint32_t that will be set | ||
| 401 | * to the number of bytes received. | ||
| 402 | * | ||
| 403 | * @return The return value of iphone_mux_recv_timeout. | ||
| 404 | * | ||
| 405 | * @see iphone_mux_recv_timeout | ||
| 406 | */ | ||
| 407 | iphone_error_t iphone_mux_recv(iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t * recv_bytes) | ||
| 408 | { | ||
| 409 | return iphone_mux_recv_timeout(client, data, datalen, recv_bytes, 3500); | ||
| 410 | } | ||
diff --git a/src/usbmux.h b/src/usbmux.h deleted file mode 100644 index bea83f7..0000000 --- a/src/usbmux.h +++ /dev/null | |||
| @@ -1,58 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * usbmux.h | ||
| 3 | * Defines structures and variables pertaining to the usb multiplexing. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2008 Zach C. All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <sys/types.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <stdint.h> | ||
| 25 | #include "libiphone/libiphone.h" | ||
| 26 | |||
| 27 | #ifndef USBMUX_H | ||
| 28 | #define USBMUX_H | ||
| 29 | |||
| 30 | #ifndef IPHONE_H | ||
| 31 | #include "iphone.h" | ||
| 32 | #endif | ||
| 33 | |||
| 34 | typedef struct { | ||
| 35 | uint32_t type, length; | ||
| 36 | uint16_t sport, dport; | ||
| 37 | uint32_t scnt, ocnt; | ||
| 38 | uint8_t offset, tcp_flags; | ||
| 39 | uint16_t window, nullnull, length16; | ||
| 40 | } usbmux_tcp_header; | ||
| 41 | |||
| 42 | struct iphone_umux_client_int { | ||
| 43 | usbmux_tcp_header *header; | ||
| 44 | iphone_device_t phone; | ||
| 45 | char *recv_buffer; | ||
| 46 | int r_len; | ||
| 47 | }; | ||
| 48 | |||
| 49 | usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port); | ||
| 50 | |||
| 51 | typedef struct { | ||
| 52 | uint32_t type, length, major, minor, allnull; | ||
| 53 | } usbmux_version_header; | ||
| 54 | |||
| 55 | usbmux_version_header *version_header(void); | ||
| 56 | |||
| 57 | |||
| 58 | #endif | ||
diff --git a/udev/89-libiphone.rules b/udev/89-libiphone.rules deleted file mode 100644 index aeefc68..0000000 --- a/udev/89-libiphone.rules +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | ATTR{idVendor}!="05ac", GOTO="libiphone_rules_end" | ||
| 2 | |||
| 3 | # Forces iPhone 1.0, 3G and iPodTouch 1 and 2 to USB configuration 3 | ||
| 4 | SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1290", ACTION=="add", ATTR{bConfigurationValue}="3" | ||
| 5 | SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1291", ACTION=="add", ATTR{bConfigurationValue}="3" | ||
| 6 | SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1292", ACTION=="add", ATTR{bConfigurationValue}="3" | ||
| 7 | SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1293", ACTION=="add", ATTR{bConfigurationValue}="3" | ||
| 8 | |||
| 9 | LABEL="libiphone_rules_end" | ||
diff --git a/udev/Makefile.am b/udev/Makefile.am deleted file mode 100644 index c6deb39..0000000 --- a/udev/Makefile.am +++ /dev/null | |||
| @@ -1,4 +0,0 @@ | |||
| 1 | udevdir=$(sysconfdir)/udev/rules.d/ | ||
| 2 | udev_DATA=89-libiphone.rules | ||
| 3 | |||
| 4 | EXTRA_DIST=$(udev_DATA) | ||
