summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac4
-rw-r--r--dev/Makefile.am4
-rw-r--r--dev/afccheck.c2
-rw-r--r--dev/iphoneinfo.c6
-rw-r--r--dev/main.c15
-rw-r--r--dev/msyncclient.c2
-rw-r--r--dev/syslog_relay.c25
-rw-r--r--include/libiphone/libiphone.h22
-rw-r--r--src/AFC.c75
-rw-r--r--src/AFC.h4
-rw-r--r--src/Makefile.am7
-rw-r--r--src/MobileSync.c25
-rw-r--r--src/MobileSync.h3
-rw-r--r--src/NotificationProxy.c47
-rw-r--r--src/NotificationProxy.h3
-rw-r--r--src/iphone.c295
-rw-r--r--src/iphone.h17
-rw-r--r--src/lockdown.c25
-rw-r--r--src/lockdown.h4
-rw-r--r--src/usbmux.c410
-rw-r--r--src/usbmux.h58
-rw-r--r--udev/89-libiphone.rules9
-rw-r--r--udev/Makefile.am4
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 @@
1AUTOMAKE_OPTIONS = foreign 1AUTOMAKE_OPTIONS = foreign
2ACLOCAL_AMFLAGS = -I m4 2ACLOCAL_AMFLAGS = -I m4
3SUBDIRS = src include fdi swig udev $(DEV_SUB) 3SUBDIRS = src include fdi swig $(DEV_SUB)
4 4
5DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools 5DISTCHECK_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
20AM_PROG_CC_C_O 20AM_PROG_CC_C_O
21 21
22# Checks for libraries. 22# Checks for libraries.
23PKG_CHECK_MODULES(libusb, libusb >= 0.1.12) 23PKG_CHECK_MODULES(libusbmuxd, libusbmuxd >= 0.1.0)
24PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1) 24PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1)
25PKG_CHECK_MODULES(libgthread2, gthread-2.0 >= 2.14.1) 25PKG_CHECK_MODULES(libgthread2, gthread-2.0 >= 2.14.1)
26PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 ) 26PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 )
@@ -95,4 +95,4 @@ if test "$enable_largefile" != no; then
95fi 95fi
96AC_SUBST(LFS_CFLAGS) 96AC_SUBST(LFS_CFLAGS)
97 97
98AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile udev/Makefile libiphone-1.0.pc) 98AC_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 @@
1INCLUDES = -I$(top_srcdir)/include 1INCLUDES = -I$(top_srcdir)/include
2 2
3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) 3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS)
4AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) 4AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS)
5 5
6bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneinfo iphonesyslog 6bin_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);
diff --git a/dev/main.c b/dev/main.c
index 510c75f..5c9a5a7 100644
--- a/dev/main.c
+++ b/dev/main.c
@@ -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, &noti); 214 iphone_np_get_notification(gnp, &noti);
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, &noti); 224 iphone_np_get_notification(gnp, &noti);
@@ -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
31static int quit_flag = 0; 32static 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;
68struct iphone_lckd_client_int; 69struct iphone_lckd_client_int;
69typedef struct iphone_lckd_client_int *iphone_lckd_client_t; 70typedef struct iphone_lckd_client_int *iphone_lckd_client_t;
70 71
71struct iphone_umux_client_int;
72typedef struct iphone_umux_client_int *iphone_umux_client_t;
73
74struct iphone_afc_client_int; 72struct iphone_afc_client_int;
75typedef struct iphone_afc_client_int *iphone_afc_client_t; 73typedef 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
97iphone_error_t iphone_get_device ( iphone_device_t *device ); 95iphone_error_t iphone_get_device ( iphone_device_t *device );
98iphone_error_t iphone_get_specific_device( unsigned int bus_n, int dev_n, iphone_device_t * device ); 96iphone_error_t iphone_get_device_by_uuid ( iphone_device_t *device, const char *uuid );
99iphone_error_t iphone_free_device ( iphone_device_t device ); 97iphone_error_t iphone_free_device ( iphone_device_t device );
100 98
99uint32_t iphone_get_device_handle ( iphone_device_t device );
101 100
102//lockdownd related functions 101//lockdownd related functions
103iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid); 102iphone_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);
110iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, plist_t plist); 109iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, plist_t plist);
111 110
112 111
113//usbmux related functions
114iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client );
115iphone_error_t iphone_mux_free_client ( iphone_umux_client_t client );
116
117iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t *sent_bytes );
118iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes );
119iphone_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
123iphone_error_t iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t *client ); 113iphone_error_t iphone_afc_new_client ( iphone_device_t device, int dst_port, iphone_afc_client_t *client );
124iphone_error_t iphone_afc_free_client ( iphone_afc_client_t client ); 114iphone_error_t iphone_afc_free_client ( iphone_afc_client_t client );
125int iphone_afc_get_afcerror ( iphone_afc_client_t client ); 115int iphone_afc_get_afcerror ( iphone_afc_client_t client );
126int iphone_afc_get_errno ( iphone_afc_client_t client ); 116int 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
146iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port, 136iphone_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);
148iphone_error_t iphone_msync_free_client(iphone_msync_client_t client); 138iphone_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
170iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ); 160iphone_error_t iphone_np_new_client ( iphone_device_t device, int dst_port, iphone_np_client_t *client );
171iphone_error_t iphone_np_free_client ( iphone_np_client_t client ); 161iphone_error_t iphone_np_free_client ( iphone_np_client_t client );
172 162
173iphone_error_t iphone_np_post_notification ( iphone_np_client_t client, const char *notification ); 163iphone_error_t iphone_np_post_notification ( iphone_np_client_t client, const char *notification );
diff --git a/src/AFC.c b/src/AFC.c
index e5fe526..71093df 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -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 */
64iphone_error_t iphone_afc_new_client(iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t * client) 66iphone_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 */
107iphone_error_t iphone_afc_free_client(iphone_afc_client_t client) 108iphone_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);
diff --git a/src/AFC.h b/src/AFC.h
index 41b4d67..5827518 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -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
49struct iphone_afc_client_int { 49struct 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 @@
1INCLUDES = -I$(top_srcdir)/include 1INCLUDES = -I$(top_srcdir)/include
2 2
3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) 3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusbmuxd_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS)
4AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) 4AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS)
5 5
6lib_LTLIBRARIES = libiphone.la 6lib_LTLIBRARIES = libiphone.la
7libiphone_la_SOURCES = usbmux.c usbmux.h \ 7libiphone_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
31iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port, 32iphone_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
32struct iphone_msync_client_int { 31struct 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 */
110iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ) 111iphone_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, &notification); 394 iphone_np_get_notification(npt->client, &notification);
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
27struct iphone_np_client_int { 26struct 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
38static 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 */
98iphone_error_t iphone_get_specific_device(unsigned int bus_n, int dev_n, iphone_device_t * device) 42iphone_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 */
200iphone_error_t iphone_get_device(iphone_device_t * device) 89iphone_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; 94uint32_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 */
263int 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 */
295int 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
36struct iphone_device_int { 27struct 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
43int send_to_phone(iphone_device_t phone, char *data, int datalen);
44int 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 */
470iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key) 471iphone_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
34struct iphone_lckd_client_int { 32struct 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
31static iphone_umux_client_t *connlist = NULL;
32static 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 */
41usbmux_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 */
61usbmux_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 */
80static 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
109static 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 */
126iphone_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 */
179iphone_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
217iphone_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 */
277iphone_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 */
407iphone_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
34typedef 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
42struct iphone_umux_client_int {
43 usbmux_tcp_header *header;
44 iphone_device_t phone;
45 char *recv_buffer;
46 int r_len;
47};
48
49usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port);
50
51typedef struct {
52 uint32_t type, length, major, minor, allnull;
53} usbmux_version_header;
54
55usbmux_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 @@
1ATTR{idVendor}!="05ac", GOTO="libiphone_rules_end"
2
3# Forces iPhone 1.0, 3G and iPodTouch 1 and 2 to USB configuration 3
4SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1290", ACTION=="add", ATTR{bConfigurationValue}="3"
5SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1291", ACTION=="add", ATTR{bConfigurationValue}="3"
6SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1292", ACTION=="add", ATTR{bConfigurationValue}="3"
7SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1293", ACTION=="add", ATTR{bConfigurationValue}="3"
8
9LABEL="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 @@
1udevdir=$(sysconfdir)/udev/rules.d/
2udev_DATA=89-libiphone.rules
3
4EXTRA_DIST=$(udev_DATA)