diff options
| author | 2009-05-24 00:25:03 +0200 | |
|---|---|---|
| committer | 2009-05-24 00:25:03 +0200 | |
| commit | 36ea32e0064f33d6a285684c3069f4d75bbac7a8 (patch) | |
| tree | 039291b47e954fe8529f52e1fc71f7e924761a6a | |
| parent | 46f8d46845355e6a33a6dcb97ba11d4c4cab62eb (diff) | |
| parent | 435f5feb4b5c501db52743a170908687d3ba6f60 (diff) | |
| download | libimobiledevice-36ea32e0064f33d6a285684c3069f4d75bbac7a8.tar.gz libimobiledevice-36ea32e0064f33d6a285684c3069f4d75bbac7a8.tar.bz2 | |
Merge branch 'master' of git://github.com/MattColyer/libiphone into martin
Conflicts:
	src/Makefile.am
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | README | 1 | ||||
| -rw-r--r-- | configure.ac | 4 | ||||
| -rw-r--r-- | dev/Makefile.am | 11 | ||||
| -rw-r--r-- | dev/afccheck.c | 2 | ||||
| -rw-r--r-- | dev/iphone_id.c | 93 | ||||
| -rw-r--r-- | dev/iphoneinfo.c | 18 | ||||
| -rw-r--r-- | dev/main.c | 15 | ||||
| -rw-r--r-- | dev/msyncclient.c | 2 | ||||
| -rw-r--r-- | dev/syslog_relay.c | 34 | ||||
| -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 | 89 | ||||
| -rw-r--r-- | src/lockdown.h | 4 | ||||
| -rw-r--r-- | src/usbmux.c | 410 | ||||
| -rw-r--r-- | src/usbmux.h | 58 | ||||
| -rw-r--r-- | swig/iphone.i | 2 | ||||
| -rw-r--r-- | udev/89-libiphone.rules | 9 | ||||
| -rw-r--r-- | udev/Makefile.am | 4 | 
27 files changed, 338 insertions, 918 deletions
| diff --git a/Makefile.am b/Makefile.am index a691d73..39ee8e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@  AUTOMAKE_OPTIONS = foreign  ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src include fdi swig udev $(DEV_SUB) +SUBDIRS = src include fdi swig $(DEV_SUB)  DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools @@ -12,6 +12,7 @@ You must have:  	libfuse-dev (and the associated kernel modules)  	libglib2.0-dev  	libplist-dev +	usbmuxd (http://pims.selfip.net/git/usbmuxd)  	make  	autoheader  	automake diff --git a/configure.ac b/configure.ac index 4f0fff2..62023c7 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PROG_CC  AM_PROG_CC_C_O  # Checks for libraries. -PKG_CHECK_MODULES(libusb, libusb >= 0.1.12) +PKG_CHECK_MODULES(libusbmuxd, libusbmuxd >= 0.1.0)  PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1)  PKG_CHECK_MODULES(libgthread2, gthread-2.0 >= 2.14.1)  PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 ) @@ -96,4 +96,4 @@ if test "$enable_largefile" != no; then  fi  AC_SUBST(LFS_CFLAGS) -AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile udev/Makefile libiphone-1.0.pc) +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..9e06339 100644 --- a/dev/Makefile.am +++ b/dev/Makefile.am @@ -1,9 +1,9 @@  INCLUDES = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) -AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) -bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneinfo iphonesyslog +bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneinfo iphonesyslog iphone_id  iphoneclient_SOURCES = main.c  iphoneclient_LDADD = ../src/libiphone.la @@ -32,3 +32,8 @@ iphonesyslog_SOURCES = syslog_relay.c  iphonesyslog_CFLAGS = $(AM_CFLAGS)  iphonesyslog_LDFLAGS = $(AM_LDFLAGS)  iphonesyslog_LDADD = ../src/libiphone.la + +iphone_id_SOURCES = iphone_id.c +iphone_id_CFLAGS = $(AM_CFLAGS) +iphone_id_LDFLAGS = $(AM_LDFLAGS) +iphone_id_LDADD = ../src/libiphone.la 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[])  		return 1;  	} -	iphone_afc_new_client(phone, 3432, port, &afc); +	iphone_afc_new_client(phone, port, &afc);  	//makes sure thread environment is available  	if (!g_thread_supported()) diff --git a/dev/iphone_id.c b/dev/iphone_id.c new file mode 100644 index 0000000..c191608 --- /dev/null +++ b/dev/iphone_id.c @@ -0,0 +1,93 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <libiphone/libiphone.h> +#include <usbmuxd.h> + +static void usage() +{ +	printf("usage: iphone_id <device_uuid>\n" +		"\tdevice_uuid is the 40-digit hexadecimal UUID of the device\n" +		"\tfor which the name should be retrieved.\n\n" +		"usage: iphone_id -l\n" +		"\tList all attached devices.\n"); +	exit(0); +} + +int main(int argc, char **argv) +{ +	iphone_device_t phone = NULL; +	iphone_lckd_client_t control = NULL; +	usbmuxd_scan_result *dev_list; +	char *devname = NULL; +	int ret = 0; +	int c; +	int i; +	int opt_list = 0; + +	while ((c = getopt(argc, argv, "lh")) != -1) { +		switch (c) { +		    case 'l': +			opt_list = 1; +			break; +		    case 'h': +		    default: +			usage(); +		} +	} + +	if (argc < 2) { +		usage(); +	} + +	argc -= optind; +	argv += optind; + +	if ((!opt_list) && (strlen(argv[0]) != 40)) { +		usage(); +	} + +	if (opt_list) { +		if (usbmuxd_scan(&dev_list) < 0) { +			fprintf(stderr, "ERROR: usbmuxd is not running!\n"); +			return -1; +		} +		for (i = 0; dev_list[i].handle > 0; i++) { +			printf("handle=%d product_id=%04x uuid=%s\n", dev_list[i].handle, dev_list[i].product_id, dev_list[i].serial_number); +		} +		return 0; +	} + +	iphone_set_debug(0); + +	iphone_get_device_by_uuid(&phone, argv[0]); +	if (!phone) { +		fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", argv[0]); +		return -2; +	} + +	if (IPHONE_E_SUCCESS != iphone_lckd_new_client(phone, &control)) { +		iphone_free_device(phone); +		fprintf(stderr, "ERROR: Connecting to device failed!\n"); +		return -2; +	} + +	if ((IPHONE_E_SUCCESS != lockdownd_get_device_name(control, &devname)) || !devname) { +		fprintf(stderr, "ERROR: Could not get device name!\n"); +		ret = -2; +	} + +	iphone_lckd_free_client(control); +	iphone_free_device(phone); + +	if (ret == 0) { +		printf("%s\n", devname); +	} + +	if (devname) { +		free(devname); +	} + +	return ret; +} diff --git a/dev/iphoneinfo.c b/dev/iphoneinfo.c index 4995b9b..c28eb9e 100644 --- a/dev/iphoneinfo.c +++ b/dev/iphoneinfo.c @@ -22,7 +22,6 @@  #include <stdio.h>  #include <string.h>  #include <errno.h> -#include <usb.h>  #include <libiphone/libiphone.h> @@ -37,7 +36,8 @@ int main(int argc, char *argv[])  	iphone_device_t phone = NULL;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;  	int i; -	int bus_n = -1, dev_n = -1; +	char uuid[41]; +	uuid[0] = 0;  	/* parse cmdline args */  	for (i = 1; i < argc; i++) { @@ -45,11 +45,13 @@ int main(int argc, char *argv[])  			iphone_set_debug_mask(DBGMASK_ALL);  			continue;  		} -		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--usb")) { -			if (sscanf(argv[++i], "%d,%d", &bus_n, &dev_n) < 2) { +		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { +			i++; +			if (!argv[i] || (strlen(argv[i]) != 40)) {  				print_usage(argc, argv);  				return 0;  			} +			strcpy(uuid, argv[i]);  			continue;  		}  		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { @@ -62,10 +64,10 @@ int main(int argc, char *argv[])  		}  	} -	if (bus_n != -1) { -		ret = iphone_get_specific_device(bus_n, dev_n, &phone); +	if (uuid[0] != 0) { +		ret = iphone_get_device_by_uuid(&phone, uuid);  		if (ret != IPHONE_E_SUCCESS) { -			printf("No device found for usb bus %d and dev %d, is it plugged in?\n", bus_n, dev_n); +			printf("No device found with uuid %s, is it plugged in?\n", uuid);  			return -1;  		}  	} @@ -108,7 +110,7 @@ void print_usage(int argc, char **argv)  	printf("Usage: %s [OPTIONS]\n", (strrchr(argv[0], '/') + 1));  	printf("Show information about the first connected iPhone/iPod Touch.\n\n");  	printf("  -d, --debug\t\tenable communication debugging\n"); -	printf("  -u, --usb=BUS,DEV\ttarget specific device by usb bus/dev number\n"); +	printf("  -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n");  	printf("  -h, --help\t\tprints usage information\n");  	printf("\n");  } @@ -42,7 +42,7 @@ void perform_notification(iphone_device_t phone, iphone_lckd_client_t control, c  	iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &nport);  	if (nport) {  		printf("::::::::::::::: np was started ::::::::::::\n"); -		iphone_np_new_client(phone, 3555, nport, &np); +		iphone_np_new_client(phone, nport, &np);  		if (np) {  			printf("::::::::: PostNotification %s\n", notification);  			iphone_np_post_notification(np, notification); @@ -98,12 +98,12 @@ int main(int argc, char *argv[])  	if (port) {  		iphone_afc_client_t afc = NULL; -		iphone_afc_new_client(phone, 3432, port, &afc); +		iphone_afc_new_client(phone, port, &afc);  		if (afc) {  			iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &npp);  			if (npp) {  				printf("Notification Proxy started.\n"); -				iphone_np_new_client(phone, 3756, npp, &gnp); +				iphone_np_new_client(phone, npp, &gnp);  			} else {  				printf("ERROR: Notification proxy could not be started.\n");  			} @@ -115,7 +115,7 @@ int main(int argc, char *argv[])  					NULL  				};  				iphone_np_observe_notifications(gnp, nspec); -				//iphone_np_set_notify_callback(gnp, notifier); +				iphone_np_set_notify_callback(gnp, notifier);  			}  			perform_notification(phone, control, NP_SYNC_WILL_START); @@ -209,15 +209,16 @@ int main(int argc, char *argv[])  		if (gnp && lockfile) {  			char *noti; +			/*  			noti = NULL;  			iphone_np_get_notification(gnp, ¬i);  			if (noti) {  				printf("------> received notification '%s'\n", noti);  				free(noti); -			} +			}*/  			printf("XXX sleeping\n"); -			for (i = 0; i < 5; i++) { +			/*for (i = 0; i < 5; i++) {  				noti = NULL;  				printf("--- getting notification\n");  				iphone_np_get_notification(gnp, ¬i); @@ -229,6 +230,8 @@ int main(int argc, char *argv[])  				}  				sleep(1);  			} +			*/ +			sleep(5);  			//perform_notification(phone, control, NP_SYNC_DID_FINISH); 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[])  	if (port) {  		iphone_msync_client_t msync = NULL; -		iphone_msync_new_client(phone, 3432, port, &msync); +		iphone_msync_new_client(phone, port, &msync);  		if (msync) {  			iphone_msync_get_all_contacts(msync);  			iphone_msync_free_client(msync); diff --git a/dev/syslog_relay.c b/dev/syslog_relay.c index 56cf56c..3407f2f 100644 --- a/dev/syslog_relay.c +++ b/dev/syslog_relay.c @@ -24,9 +24,9 @@  #include <errno.h>  #include <netinet/in.h>  #include <signal.h> -#include <usb.h>  #include <libiphone/libiphone.h> +#include <usbmuxd.h>  static int quit_flag = 0; @@ -47,8 +47,9 @@ int main(int argc, char *argv[])  	iphone_device_t phone = NULL;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;  	int i; -	int bus_n = -1, dev_n = -1; +	char uuid[41];  	int port = 0; +	uuid[0] = 0;  	signal(SIGINT, clean_exit);  	signal(SIGQUIT, clean_exit); @@ -61,11 +62,13 @@ int main(int argc, char *argv[])  			iphone_set_debug_mask(DBGMASK_ALL);  			continue;  		} -		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--usb")) { -			if (sscanf(argv[++i], "%d,%d", &bus_n, &dev_n) < 2) { +		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { +			i++; +			if (!argv[i] || (strlen(argv[i]) != 40)) {  				print_usage(argc, argv);  				return 0;  			} +			strcpy(uuid, argv[i]);  			continue;  		}  		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { @@ -78,10 +81,10 @@ int main(int argc, char *argv[])  		}  	} -	if (bus_n != -1) { -		ret = iphone_get_specific_device(bus_n, dev_n, &phone); +	if (uuid[0] != 0) { +		ret = iphone_get_device_by_uuid(&phone, uuid);  		if (ret != IPHONE_E_SUCCESS) { -			printf("No device found for usb bus %d and dev %d, is it plugged in?\n", bus_n, dev_n); +			printf("No device found with uuid %s, is it plugged in?\n", uuid);  			return -1;  		}  	} @@ -103,15 +106,16 @@ int main(int argc, char *argv[])  	ret = iphone_lckd_start_service(control, "com.apple.syslog_relay", &port);  	if ((ret == IPHONE_E_SUCCESS) && port) {  		/* connect to socket relay messages */ -		iphone_umux_client_t syslog_client = NULL; -		ret = iphone_mux_new_client(phone, 514, port, &syslog_client); -		if (ret == IPHONE_E_SUCCESS) { +		int sfd = usbmuxd_connect(iphone_get_device_handle(phone), port); +		if (sfd < 0) { +			printf("ERROR: Could not open usbmux connection.\n"); +		} else {  			while (!quit_flag) {  				char *receive = NULL;  				uint32_t datalen = 0, bytes = 0, recv_bytes = 0; -				ret = iphone_mux_recv(syslog_client, (char *) &datalen, sizeof(datalen), &bytes); +				ret = usbmuxd_recv(sfd, (char *) &datalen, sizeof(datalen), &bytes);  				datalen = ntohl(datalen);  				if (datalen == 0) @@ -121,7 +125,7 @@ int main(int argc, char *argv[])  				receive = (char *) malloc(sizeof(char) * datalen);  				while (!quit_flag && (recv_bytes <= datalen)) { -					ret = iphone_mux_recv(syslog_client, receive, datalen, &bytes); +					ret = usbmuxd_recv(sfd, receive, datalen, &bytes);  					if (bytes == 0)  						break; @@ -133,10 +137,8 @@ int main(int argc, char *argv[])  				free(receive);  			} -		} else { -			printf("ERROR: Could not open usbmux connection.\n");  		} -		iphone_mux_free_client(syslog_client); +		usbmuxd_disconnect(sfd);  	} else {  		printf("ERROR: Could not start service com.apple.syslog_relay.\n");  	} @@ -152,7 +154,7 @@ void print_usage(int argc, char **argv)  	printf("Usage: %s [OPTIONS]\n", (strrchr(argv[0], '/') + 1));  	printf("Relay syslog of a connected iPhone/iPod Touch.\n\n");  	printf("  -d, --debug\t\tenable communication debugging\n"); -	printf("  -u, --usb=BUS,DEV\ttarget specific device by usb bus/dev number\n"); +	printf("  -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n");  	printf("  -h, --help\t\tprints usage information\n");  	printf("\n");  } 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" {  #include <sys/types.h>  #include <sys/stat.h>  #include <plist/plist.h> +#include <usbmuxd.h>  //general errors  #define IPHONE_E_SUCCESS                0 @@ -68,9 +69,6 @@ typedef struct iphone_device_int *iphone_device_t;  struct iphone_lckd_client_int;  typedef struct iphone_lckd_client_int *iphone_lckd_client_t; -struct iphone_umux_client_int; -typedef struct iphone_umux_client_int *iphone_umux_client_t; -  struct iphone_afc_client_int;  typedef struct iphone_afc_client_int *iphone_afc_client_t; @@ -95,9 +93,10 @@ void iphone_set_debug(int level);  //device related functions  iphone_error_t iphone_get_device ( iphone_device_t *device ); -iphone_error_t iphone_get_specific_device( unsigned int bus_n, int dev_n, iphone_device_t * device ); +iphone_error_t iphone_get_device_by_uuid ( iphone_device_t *device, const char *uuid );  iphone_error_t iphone_free_device ( iphone_device_t device ); +uint32_t iphone_get_device_handle ( iphone_device_t device );  //lockdownd related functions  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);  iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, plist_t plist); -//usbmux related functions -iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ); -iphone_error_t iphone_mux_free_client ( iphone_umux_client_t client ); - -iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t *sent_bytes ); -iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes  ); -iphone_error_t iphone_mux_recv_timeout ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes, int timeout); - -  //afc related functions -iphone_error_t iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t *client ); +iphone_error_t iphone_afc_new_client ( iphone_device_t device, int dst_port, iphone_afc_client_t *client );  iphone_error_t iphone_afc_free_client ( iphone_afc_client_t client );  int iphone_afc_get_afcerror ( iphone_afc_client_t client );  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, -iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port, +iphone_error_t iphone_msync_new_client(iphone_device_t device, int dst_port,  									   iphone_msync_client_t * client);  iphone_error_t iphone_msync_free_client(iphone_msync_client_t client); @@ -167,7 +157,7 @@ iphone_error_t iphone_msync_send(iphone_msync_client_t client, plist_t plist);  #define NP_APP_INSTALLED        "com.apple.mobile.application_installed"  #define NP_APP_UNINSTALLED      "com.apple.mobile.application_uninstalled" -iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ); +iphone_error_t iphone_np_new_client ( iphone_device_t device, int dst_port, iphone_np_client_t *client );  iphone_error_t iphone_np_free_client ( iphone_np_client_t client );  iphone_error_t iphone_np_post_notification ( iphone_np_client_t client, const char *notification ); @@ -20,7 +20,9 @@   */  #include <stdio.h> +#include <stdlib.h>  #include <errno.h> +#include <unistd.h>  #include "AFC.h"  #include "utils.h" @@ -61,29 +63,28 @@ static void afc_unlock(iphone_afc_client_t client)   *    * @return A handle to the newly-connected client or NULL upon error.   */ -iphone_error_t iphone_afc_new_client(iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t * client) +iphone_error_t iphone_afc_new_client(iphone_device_t device, int dst_port, iphone_afc_client_t * client)  { -	int ret = IPHONE_E_SUCCESS; -  	//makes sure thread environment is available  	if (!g_thread_supported())  		g_thread_init(NULL); -	iphone_afc_client_t client_loc = (iphone_afc_client_t) malloc(sizeof(struct iphone_afc_client_int));  	if (!device)  		return IPHONE_E_INVALID_ARG;  	// Attempt connection -	client_loc->connection = NULL; -	ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); -	if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { -		free(client_loc); -		return ret; +	int sfd = usbmuxd_connect(device->handle, dst_port); +	if (sfd < 0) { +		return IPHONE_E_UNKNOWN_ERROR; // ret;  	} + +	iphone_afc_client_t client_loc = (iphone_afc_client_t) malloc(sizeof(struct iphone_afc_client_int)); +	client_loc->sfd = sfd; +  	// Allocate a packet  	client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket));  	if (!client_loc->afc_packet) { -		iphone_mux_free_client(client_loc->connection); +		usbmuxd_disconnect(client_loc->sfd);  		free(client_loc);  		return IPHONE_E_UNKNOWN_ERROR;  	} @@ -106,10 +107,10 @@ iphone_error_t iphone_afc_new_client(iphone_device_t device, int src_port, int d   */  iphone_error_t iphone_afc_free_client(iphone_afc_client_t client)  { -	if (!client || !client->connection || !client->afc_packet) +	if (!client || client->sfd < 0 || !client->afc_packet)  		return IPHONE_E_INVALID_ARG; -	iphone_mux_free_client(client->connection); +	usbmuxd_disconnect(client->sfd);  	free(client->afc_packet);  	if (client->mutex) {  		g_mutex_free(client->mutex); @@ -217,7 +218,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int  	int bytes = 0, offset = 0;  	char *buffer; -	if (!client || !client->connection || !client->afc_packet) +	if (!client || client->sfd < 0 || !client->afc_packet)  		return 0;  	if (!data || !length)  		length = 0; @@ -248,7 +249,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int  			return -1;  		}  		memcpy(buffer + sizeof(AFCPacket), data, offset); -		iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); +		usbmuxd_send(client->sfd, buffer, client->afc_packet->this_length, (uint32_t*)&bytes);  		free(buffer);  		if (bytes <= 0) {  			return bytes; @@ -259,7 +260,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int  		log_debug_msg("Buffer: \n");  		log_debug_buffer(data + offset, length - offset); -		iphone_mux_send(client->connection, data + offset, length - offset, (uint32_t*)&bytes); +		usbmuxd_send(client->sfd, data + offset, length - offset, (uint32_t*)&bytes);  		return bytes;  	} else {  		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  		}  		log_debug_buffer(buffer, client->afc_packet->this_length);  		log_debug_msg("\n"); -		iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); +		usbmuxd_send(client->sfd, buffer, client->afc_packet->this_length, (uint32_t*)&bytes);  		if (buffer) {  			free(buffer); @@ -307,7 +308,7 @@ static int receive_AFC_data(iphone_afc_client_t client, char **dump_here)  	client->afcerror = 0;  	// first, read the AFC header -	iphone_mux_recv(client->connection, (char*)&header, sizeof(AFCPacket), (uint32_t*)&bytes); +	usbmuxd_recv(client->sfd, (char*)&header, sizeof(AFCPacket), (uint32_t*)&bytes);  	if (bytes <= 0) {  		log_debug_msg("%s: Just didn't get enough.\n", __func__);  		*dump_here = NULL; @@ -359,24 +360,26 @@ static int receive_AFC_data(iphone_afc_client_t client, char **dump_here)  	}  	*dump_here = (char*)malloc(entire_len); -	iphone_mux_recv(client->connection, *dump_here, this_len, (uint32_t*)&bytes); -	if (bytes <= 0) { -		free(*dump_here); -		*dump_here = NULL; -		log_debug_msg("%s: Did not get packet contents!\n", __func__); -		return -1; -	} else if ((uint32_t)bytes < this_len) { -		free(*dump_here); -		*dump_here = NULL; -		log_debug_msg("%s: Could not receive this_len=%d bytes\n", __func__, this_len); -		return -1; +	if (this_len > 0) { +		usbmuxd_recv(client->sfd, *dump_here, this_len, (uint32_t*)&bytes); +		if (bytes <= 0) { +			free(*dump_here); +			*dump_here = NULL; +			log_debug_msg("%s: Did not get packet contents!\n", __func__); +			return -1; +		} else if ((uint32_t)bytes < this_len) { +			free(*dump_here); +			*dump_here = NULL; +			log_debug_msg("%s: Could not receive this_len=%d bytes\n", __func__, this_len); +			return -1; +		}  	}  	current_count = this_len;  	if (entire_len > this_len) {  		while (current_count < entire_len) { -			iphone_mux_recv(client->connection, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)&bytes); +			usbmuxd_recv(client->sfd, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)&bytes);  			if (bytes <= 0) {  				log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, bytes);  				break; @@ -559,7 +562,7 @@ iphone_error_t iphone_afc_delete_file(iphone_afc_client_t client, const char *pa  	char *response = NULL;  	int bytes; -	if (!client || !path || !client->afc_packet || !client->connection) +	if (!client || !path || !client->afc_packet || client->sfd < 0)  		return IPHONE_E_INVALID_ARG;  	afc_lock(client); @@ -600,7 +603,7 @@ iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *fr  	char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t)));  	int bytes = 0; -	if (!client || !from || !to || !client->afc_packet || !client->connection) +	if (!client || !from || !to || !client->afc_packet || client->sfd < 0)  		return IPHONE_E_INVALID_ARG;  	afc_lock(client); @@ -748,7 +751,7 @@ iphone_error_t iphone_afc_get_file_attr(iphone_afc_client_t client, const char *  {  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; -	if (!client || !client->connection || !client->afc_packet || !stbuf) +	if (!client || client->sfd < 0 || !client->afc_packet || !stbuf)  		return IPHONE_E_INVALID_ARG;  	memset(stbuf, 0, sizeof(struct stat)); @@ -793,7 +796,7 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename,  	int bytes = 0, length = 0;  	char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); -	if (!client || !client->connection || !client->afc_packet) +	if (!client || client->sfd < 0|| !client->afc_packet)  		return IPHONE_E_INVALID_ARG;  	afc_lock(client); @@ -851,7 +854,7 @@ iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *d  	int current_count = 0, bytes_loc = 0;  	const int MAXIMUM_READ_SIZE = 1 << 16; -	if (!client || !client->afc_packet || !client->connection || !file) +	if (!client || !client->afc_packet || client->sfd < 0 || !file)  		return IPHONE_E_INVALID_ARG;  	log_debug_msg("afc_read_file called for length %i\n", length); @@ -926,7 +929,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,  	int bytes_loc = 0;  	char *out_buffer = NULL; -	if (!client || !client->afc_packet || !client->connection || !file || !bytes) +	if (!client || !client->afc_packet || client->sfd < 0 || !file || !bytes)  		return IPHONE_E_INVALID_ARG;  	afc_lock(client); @@ -1219,7 +1222,7 @@ iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path,  	int bytes = 0;  	uint64_t size_requested = newsize; -	if (!client || !path || !client->afc_packet || !client->connection) +	if (!client || !path || !client->afc_packet || client->sfd < 0)  		return IPHONE_E_INVALID_ARG;  	afc_lock(client); @@ -19,7 +19,7 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA    */ -#include "usbmux.h" +#include "libiphone/libiphone.h"  #include "iphone.h"  #include <string.h> @@ -47,7 +47,7 @@ typedef struct __AFCToken {  } AFCToken;  struct iphone_afc_client_int { -	iphone_umux_client_t connection; +	int sfd;  	AFCPacket *afc_packet;  	int file_handle;  	int lock; diff --git a/src/Makefile.am b/src/Makefile.am index 0cae16b..5489684 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,11 +1,10 @@  INCLUDES = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) -AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libgcrypt_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusbmuxd_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS)  lib_LTLIBRARIES = libiphone.la -libiphone_la_SOURCES = usbmux.c usbmux.h \ -		       iphone.c iphone.h \ +libiphone_la_SOURCES = iphone.c iphone.h \  		       lockdown.c lockdown.h\  		       AFC.c AFC.h\  		       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 @@  #include "MobileSync.h"  #include <plist/plist.h>  #include <string.h> +#include <stdlib.h>  #include <arpa/inet.h>  #define MSYNC_VERSION_INT1 100  #define MSYNC_VERSION_INT2 100 -iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port, +iphone_error_t iphone_msync_new_client(iphone_device_t device, int dst_port,  									   iphone_msync_client_t * client)  { -	if (!device || src_port == 0 || dst_port == 0 || !client || *client) +	if (!device || dst_port == 0 || !client || *client)  		return IPHONE_E_INVALID_ARG;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; -	iphone_msync_client_t client_loc = (iphone_msync_client_t) malloc(sizeof(struct iphone_msync_client_int)); -  	// Attempt connection -	client_loc->connection = NULL; -	ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); -	if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { -		free(client_loc); +	int sfd = usbmuxd_connect(device->handle, dst_port); +	if (sfd < 0) {  		return ret;  	} + +	iphone_msync_client_t client_loc = (iphone_msync_client_t) malloc(sizeof(struct iphone_msync_client_int)); +	client_loc->sfd = sfd; +  	//perform handshake  	plist_t array = NULL; @@ -120,7 +121,7 @@ iphone_error_t iphone_msync_free_client(iphone_msync_client_t client)  		return IPHONE_E_INVALID_ARG;  	iphone_msync_stop_session(client); -	return iphone_mux_free_client(client->connection); +	return usbmuxd_disconnect(client->sfd);  }  /** Polls the iPhone for MobileSync data. @@ -138,14 +139,14 @@ iphone_error_t iphone_msync_recv(iphone_msync_client_t client, plist_t * plist)  	char *receive = NULL;  	uint32_t datalen = 0, bytes = 0, received_bytes = 0; -	ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes); +	ret = usbmuxd_recv(client->sfd, (char *) &datalen, sizeof(datalen), &bytes);  	datalen = ntohl(datalen);  	receive = (char *) malloc(sizeof(char) * datalen);  	/* fill buffer and request more packets if needed */  	while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { -		ret = iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes); +		ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes);  		received_bytes += bytes;  	} @@ -201,7 +202,7 @@ iphone_error_t iphone_msync_send(iphone_msync_client_t client, plist_t plist)  	memcpy(real_query, &length, sizeof(length));  	memcpy(real_query + 4, content, ntohl(length)); -	ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes); +	ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes);  	free(real_query);  	return ret;  } 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 @@  #ifndef MOBILESYNC_H  #define MOBILESYNC_H -#include "usbmux.h"  #include "iphone.h"  #include "utils.h" @@ -30,7 +29,7 @@  struct iphone_msync_client_int { -	iphone_umux_client_t connection; +	int sfd;  }; 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 @@  #include <string.h>  #include <stdio.h> +#include <stdlib.h>  #include <arpa/inet.h>  #include <plist/plist.h>  #include "NotificationProxy.h" @@ -79,9 +80,9 @@ static iphone_error_t np_plist_send(iphone_np_client_t client, plist_t dict)  	}  	nlen = htonl(length); -	iphone_mux_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); +	usbmuxd_send(client->sfd, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes);  	if (bytes == sizeof(nlen)) { -		iphone_mux_send(client->connection, XML_content, length, (uint32_t*)&bytes); +		usbmuxd_send(client->sfd, XML_content, length, (uint32_t*)&bytes);  		if (bytes > 0) {  			if ((uint32_t)bytes == length) {  				res = IPHONE_E_SUCCESS; @@ -107,26 +108,24 @@ static iphone_error_t np_plist_send(iphone_np_client_t client, plist_t dict)   *    * @return A handle to the newly-connected client or NULL upon error.   */ -iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ) +iphone_error_t iphone_np_new_client ( iphone_device_t device, int dst_port, iphone_np_client_t *client )  { -	int ret = IPHONE_E_SUCCESS; -  	//makes sure thread environment is available  	if (!g_thread_supported())  		g_thread_init(NULL); -	iphone_np_client_t client_loc = (iphone_np_client_t) malloc(sizeof(struct iphone_np_client_int));  	if (!device)  		return IPHONE_E_INVALID_ARG;  	// Attempt connection -	client_loc->connection = NULL; -	ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); -	if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { -		free(client_loc); -		return ret; +	int sfd = usbmuxd_connect(device->handle, dst_port); +	if (sfd < 0) { +		return IPHONE_E_UNKNOWN_ERROR; //ret;  	} +	iphone_np_client_t client_loc = (iphone_np_client_t) malloc(sizeof(struct iphone_np_client_int)); +	client_loc->sfd = sfd; +  	client_loc->mutex = g_mutex_new();  	client_loc->notifier = NULL; @@ -144,13 +143,11 @@ iphone_error_t iphone_np_free_client ( iphone_np_client_t client )  	if (!client)  		return IPHONE_E_INVALID_ARG; -	if (client->connection) { -		iphone_mux_free_client(client->connection); -		client->connection = NULL; -		if (client->notifier) { -			log_debug_msg("joining np callback\n"); -			g_thread_join(client->notifier); -		} +	usbmuxd_disconnect(client->sfd); +	client->sfd = -1; +	if (client->notifier) { +		log_debug_msg("joining np callback\n"); +		g_thread_join(client->notifier);  	}  	if (client->mutex) {  		g_mutex_free(client->mutex); @@ -295,13 +292,13 @@ iphone_error_t iphone_np_get_notification( iphone_np_client_t client, char **not  	char *XML_content = NULL;  	plist_t dict = NULL; -	if (!client || !client->connection || *notification) { +	if (!client || client->sfd < 0 || *notification) {  		return IPHONE_E_INVALID_ARG;  	}  	np_lock(client); -	iphone_mux_recv_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, 500); +	usbmuxd_recv_timeout(client->sfd, (char*)&pktlen, sizeof(pktlen), &bytes, 500);  	log_debug_msg("NotificationProxy: initial read=%i\n", bytes);  	if (bytes < 4) {  		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  			XML_content = (char*)malloc(pktlen);  			log_debug_msg("pointer %p\n", XML_content); -			iphone_mux_recv_timeout(client->connection, XML_content, pktlen, &bytes, 1000); +			usbmuxd_recv_timeout(client->sfd, XML_content, pktlen, &bytes, 1000);  			if (bytes <= 0) {  				res = IPHONE_E_UNKNOWN_ERROR;  			} else { @@ -393,7 +390,7 @@ gpointer iphone_np_notifier( gpointer arg )  	if (!npt) return NULL;  	log_debug_msg("%s: starting callback.\n", __func__); -	while (npt->client->connection) { +	while (npt->client->sfd >= 0) {  		iphone_np_get_notification(npt->client, ¬ification);  		if (notification) {  			npt->cbfunc(notification); @@ -432,11 +429,11 @@ iphone_error_t iphone_np_set_notify_callback( iphone_np_client_t client, iphone_  	np_lock(client);  	if (client->notifier) {  		log_debug_msg("%s: callback already set, removing\n"); -		iphone_umux_client_t conn = client->connection; -		client->connection = NULL; +		int conn = client->sfd; +		client->sfd = -1;  		g_thread_join(client->notifier);  		client->notifier = NULL; -		client->connection = conn; +		client->sfd = conn;  	}  	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 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA    */  #include "libiphone/libiphone.h" -#include "usbmux.h"  #include "iphone.h"  #include <glib.h>  struct iphone_np_client_int { -	iphone_umux_client_t connection; +	int sfd;  	GMutex *mutex;  	GThread *notifier;  }; 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 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA    */ -#include "usbmux.h"  #include "iphone.h"  #include "utils.h" -#include <arpa/inet.h> -#include <usb.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h> +#include <errno.h> +#include <libiphone/libiphone.h>  /** - * This function sets the configuration of the given device to 3 - * and claims the interface 1. If usb_set_configuration fails, it detaches - * the kernel driver that blocks the device, and retries configuration. + * Retrieves a list of connected devices from usbmuxd and matches their + * UUID with the given UUID. If the given UUID is NULL then the first + * device reported by usbmuxd is used.   * - * @param phone which device to configure - */ -static void iphone_config_usb_device(iphone_device_t phone) -{ -	int ret; -	int bytes; -	unsigned char buf[512]; - -	log_debug_msg("setting configuration... "); -	ret = usb_set_configuration(phone->device, 3); -	if (ret != 0) { -		log_debug_msg("Hm, usb_set_configuration returned %d: %s, trying to fix:\n", ret, strerror(-ret)); -		log_debug_msg("-> detaching kernel driver... "); -		ret = -			usb_detach_kernel_driver_np(phone->device, -										phone->__device->config->interface->altsetting->bInterfaceNumber); -		if (ret != 0) { -			log_debug_msg("usb_detach_kernel_driver_np returned %d: %s\n", ret, strerror(-ret)); -		} else { -			log_debug_msg("done.\n"); -			log_debug_msg("setting configuration again... "); -			ret = usb_set_configuration(phone->device, 3); -			if (ret != 0) { -				log_debug_msg("Error: usb_set_configuration returned %d: %s\n", ret, strerror(-ret)); -			} else { -				log_debug_msg("done.\n"); -			} -		} -	} else { -		log_debug_msg("done.\n"); -	} - -	log_debug_msg("claiming interface... "); -	ret = usb_claim_interface(phone->device, 1); -	if (ret != 0) { -		log_debug_msg("Error: usb_claim_interface returned %d: %s\n", ret, strerror(-ret)); -	} else { -		log_debug_msg("done.\n"); -	} - -	do { -		bytes = usb_bulk_read(phone->device, BULKIN, (void *) &buf, 512, 800); -		if (bytes > 0) { -			log_debug_msg("iphone_config_usb_device: initial read returned %d bytes of data.\n", bytes); -			log_debug_buffer(buf, bytes); -		} -	} while (bytes > 0); -} - -/** - * Given a USB bus and device number, returns a device handle to the iPhone on - * that bus. To aid compatibility with future devices, this function does not - * check the vendor and device IDs! To do that, you should use - * iphone_get_device() or a system-specific API (e.g. HAL). + * @param device Upon calling this function, a pointer to a location of type + *  iphone_device_t, which must have the value NULL. On return, this location + *  will be filled with a handle to the device. + * @param uuid The UUID to match.   * - * @param bus_n The USB bus number. - * @param dev_n The USB device number. - * @param device A pointer to a iphone_device_t, which must be set to NULL upon - *      calling iphone_get_specific_device, which will be filled with a device - *      descriptor on return.    * @return IPHONE_E_SUCCESS if ok, otherwise an error code.   */ -iphone_error_t iphone_get_specific_device(unsigned int bus_n, int dev_n, iphone_device_t * device) +iphone_error_t iphone_get_device_by_uuid(iphone_device_t * device, const char *uuid)  { -	struct usb_bus *bus, *busses; -	struct usb_device *dev; -	usbmux_version_header *version; -	int bytes = 0; - -	//check we can actually write in device -	if (!device || (device && *device)) -		return IPHONE_E_INVALID_ARG; - -	iphone_device_t phone = (iphone_device_t) malloc(sizeof(struct iphone_device_int)); +	iphone_device_t phone; +	uint32_t handle = 0; +	usbmuxd_scan_result *dev_list = NULL; +	int i; -	// Initialize the struct -	phone->device = NULL; -	phone->__device = NULL; -	phone->buffer = NULL; - -	// Initialize libusb -	usb_init(); -	usb_find_busses(); -	usb_find_devices(); -	busses = usb_get_busses(); - -	// Set the device configuration -	for (bus = busses; bus; bus = bus->next) -		if (strtoul(bus->dirname, NULL, 10) == bus_n) -			for (dev = bus->devices; dev != NULL; dev = dev->next) -				if (strtol(dev->filename, NULL, 10) == dev_n) { -					phone->__device = dev; -					phone->device = usb_open(phone->__device); -					iphone_config_usb_device(phone); -					goto found; +	if (usbmuxd_scan(&dev_list) < 0) { +		log_debug_msg("%s: usbmuxd_scan returned an error, is usbmuxd running?\n", __func__); +	} +	if (dev_list && dev_list[0].handle > 0) { +		if (!uuid) { +			// select first device found if no UUID specified +			handle = dev_list[0].handle; +		} else { +			// otherwise walk through the list +			for (i = 0; dev_list[i].handle > 0; i++) { +				log_debug_msg("%s: device handle=%d, uuid=%s\n", __func__, dev_list[i].handle, dev_list[i].serial_number); +				if (strcasecmp(uuid, dev_list[i].serial_number) == 0) { +					handle = dev_list[i].handle; +					break;  				} - -	iphone_free_device(phone); - -	log_debug_msg("iphone_get_specific_device: iPhone not found\n"); -	return IPHONE_E_NO_DEVICE; - -  found: -	// Send the version command to the phone -	version = version_header(); -	bytes = usb_bulk_write(phone->device, BULKOUT, (char *) version, sizeof(*version), 800); -	if (bytes < 20) { -		log_debug_msg("get_iPhone(): libusb did NOT send enough!\n"); -		if (bytes < 0) { -			log_debug_msg("get_iPhone(): libusb gave me the error %d: %s (%s)\n", -						  bytes, usb_strerror(), strerror(-bytes)); +			}  		} -	} -	// Read the phone's response -	bytes = usb_bulk_read(phone->device, BULKIN, (char *) version, sizeof(*version), 800); +		free(dev_list); -	// Check for bad response -	if (bytes < 20) { -		free(version); -		iphone_free_device(phone); -		log_debug_msg("get_iPhone(): Invalid version message -- header too short.\n"); -		if (bytes < 0) -			log_debug_msg("get_iPhone(): libusb error message %d: %s (%s)\n", bytes, usb_strerror(), strerror(-bytes)); -		return IPHONE_E_NOT_ENOUGH_DATA; -	} -	// Check for correct version -	if (ntohl(version->major) == 1 && ntohl(version->minor) == 0) { -		// We're all ready to roll. -		log_debug_msg("get_iPhone() success\n"); -		free(version); -		*device = phone; -		return IPHONE_E_SUCCESS; -	} else { -		// Bad header -		log_debug_msg("get_iPhone(): Received a bad header/invalid version number.\n"); -		log_debug_buffer((char *) version, sizeof(*version)); -		iphone_free_device(phone); -		free(version); -		return IPHONE_E_BAD_HEADER; +		if (handle > 0) { +			phone = (iphone_device_t) malloc(sizeof(struct iphone_device_int)); +			phone->handle = handle; +			*device = phone; +			return IPHONE_E_SUCCESS; +		}  	} -	// If it got to this point it's gotta be bad -	log_debug_msg("get_iPhone(): Unknown error.\n"); -	iphone_free_device(phone); -	free(version); -	return IPHONE_E_UNKNOWN_ERROR;	// if it got to this point it's gotta be bad +	return IPHONE_E_NO_DEVICE;  }  /** - * Scans all USB busses and devices for a known AFC-compatible device and - * returns a handle to the first such device it finds. Known devices include - * those with vendor ID 0x05ac and product ID between 0x1290 and 0x1293 - * inclusive. + * This function has the purpose to retrieve a handle to the first + *  attached iPhone/iPod reported by usbmuxd.   * - * This function is convenient, but on systems where higher-level abstractions - * (such as HAL) are available it may be preferable to use - * iphone_get_specific_device instead, because it can deal with multiple - * connected devices as well as devices not known to libiphone. - *  - * @param device Upon calling this function, a pointer to a location of type + * @param Upon calling this function, a pointer to a location of type   *  iphone_device_t, which must have the value NULL. On return, this location   *  will be filled with a handle to the device. + *   * @return IPHONE_E_SUCCESS if ok, otherwise an error code.   */  iphone_error_t iphone_get_device(iphone_device_t * device)  { -	struct usb_bus *bus; -	struct usb_device *dev; - -	usb_init(); -	usb_find_busses(); -	usb_find_devices(); - -	for (bus = usb_get_busses(); bus != NULL; bus = bus->next) -		for (dev = bus->devices; dev != NULL; dev = dev->next) -			if (dev->descriptor.idVendor == 0x05ac -				&& dev->descriptor.idProduct >= 0x1290 && dev->descriptor.idProduct <= 0x1293) -				return iphone_get_specific_device(strtoul(bus->dirname, NULL, 10), strtol(dev->filename, NULL, 10), device); +	return iphone_get_device_by_uuid(device, NULL); +} -	return IPHONE_E_NO_DEVICE; +uint32_t iphone_get_device_handle(iphone_device_t device) +{ +	if (device) { +		return device->handle; +	} else { +		return 0; +	}  }  /** Cleans up an iPhone structure, then frees the structure itself.   @@ -226,88 +111,10 @@ iphone_error_t iphone_free_device(iphone_device_t device)  	if (!device)  		return IPHONE_E_INVALID_ARG;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; -	int bytes; -	unsigned char buf[512]; -	// read final package(s) -	if (device->device != NULL) { -		do { -			bytes = usb_bulk_read(device->device, BULKIN, (void *) &buf, 512, 800); -			if (bytes > 0) { -				log_debug_msg("iphone_free_device: final read returned\n"); -				log_debug_buffer(buf, bytes); -			} -		} while (bytes > 0); -	} +	ret = IPHONE_E_SUCCESS; -	if (device->buffer) { -		free(device->buffer); -	} -	if (device->device) { -		usb_release_interface(device->device, 1); -		usb_close(device->device); -		ret = IPHONE_E_SUCCESS; -	}  	free(device);  	return ret;  } -/** Sends data to the phone - * This is a low-level (i.e. directly to phone) function. - *  - * @param phone The iPhone to send data to - * @param data The data to send to the iPhone - * @param datalen The length of the data - * @return The number of bytes sent, or -1 on error or something. - */ -int send_to_phone(iphone_device_t phone, char *data, int datalen) -{ -	if (!phone) -		return -1; -	int bytes = 0; - -	if (!phone) -		return -1; -	log_debug_msg("send_to_phone: Attempting to send datalen = %i data = %p\n", datalen, data); - -	bytes = usb_bulk_write(phone->device, BULKOUT, data, datalen, 800); -	if (bytes < datalen) { -		if (bytes < 0) -			log_debug_msg("send_to_iphone(): libusb gave me the error %d: %s - %s\n", bytes, usb_strerror(), -						  strerror(-bytes)); -		return -1; -	} else { -		return bytes; -	} -	/* Should not be reached */ -	return -1; -} - -/** This function is a low-level (i.e. direct to iPhone) function. - *  - * @param phone The iPhone to receive data from - * @param data Where to put data read - * @param datalen How much data to read in - * @param timeout How many milliseconds to wait for data - *  - * @return How many bytes were read in, or -1 on error. - */ -int recv_from_phone(iphone_device_t phone, char *data, int datalen, int timeout) -{ -	if (!phone) -		return -1; -	int bytes = 0; - -	if (!phone) -		return -1; -	log_debug_msg("recv_from_phone(): attempting to receive %i bytes\n", datalen); - -	bytes = usb_bulk_read(phone->device, BULKIN, data, datalen, timeout); -	if (bytes < 0) { -		log_debug_msg("recv_from_phone(): libusb gave me the error %d: %s (%s)\n", bytes, usb_strerror(), -					  strerror(-bytes)); -		return -1; -	} - -	return bytes; -} 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 @@  #ifndef IPHONE_H  #define IPHONE_H -#ifndef USBMUX_H -#include "usbmux.h" -#warning usbmux not included? -#endif - -#include <usb.h> -#include <libiphone/libiphone.h> - -#define BULKIN 0x85 -#define BULKOUT 0x04 +#include <stdint.h>  struct iphone_device_int {  	char *buffer; -	struct usb_dev_handle *device; -	struct usb_device *__device; +	uint32_t handle;  }; -// Function definitions -int send_to_phone(iphone_device_t phone, char *data, int datalen); -int recv_from_phone(iphone_device_t phone, char *data, int datalen, int timeout);  #endif diff --git a/src/lockdown.c b/src/lockdown.c index 5ade79a..ae408be 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -19,7 +19,6 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#include "usbmux.h"  #include "utils.h"  #include "iphone.h"  #include "lockdown.h" @@ -27,6 +26,7 @@  #include <arpa/inet.h>  #include <errno.h>  #include <string.h> +#include <stdlib.h>  #include <glib.h>  #include <libtasn1.h>  #include <gnutls/x509.h> @@ -53,13 +53,15 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone)  {  	if (!phone)  		return NULL; -	iphone_lckd_client_t control = (iphone_lckd_client_t) malloc(sizeof(struct iphone_lckd_client_int)); -	if (IPHONE_E_SUCCESS != iphone_mux_new_client(phone, 0x0a00, 0xf27e, &control->connection)) { -		free(control); +	int sfd = usbmuxd_connect(phone->handle, 0xf27e); +	if (sfd < 0) { +		log_debug_msg("%s: could not connect to lockdownd (device handle %d)\n", __func__, phone->handle);  		return NULL;  	} +	iphone_lckd_client_t control = (iphone_lckd_client_t) malloc(sizeof(struct iphone_lckd_client_int)); +	control->sfd = sfd;  	control->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t));  	control->in_SSL = 0;  	return control; @@ -167,13 +169,13 @@ iphone_error_t iphone_lckd_free_client(iphone_lckd_client_t client)  	iphone_lckd_stop_SSL_session(client); -	if (client->connection) { +	if (client->sfd > 0) {  		lockdownd_close(client);  		// IMO, read of final "sessionUpcall connection closed" packet  		//  should come here instead of in iphone_free_device -		ret = iphone_mux_free_client(client->connection); +		ret = usbmuxd_disconnect(client->sfd);  	}  	free(client); @@ -197,11 +199,16 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)  	uint32_t datalen = 0, bytes = 0, received_bytes = 0;  	if (!client->in_SSL) -		ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes); +		ret = usbmuxd_recv(client->sfd, (char *) &datalen, sizeof(datalen), &bytes);  	else { -		bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); -		if (bytes > 0) +		ssize_t res = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); +		if (res < 0) { +			log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_recv: Error occured: %s\n", gnutls_strerror(res)); +			return IPHONE_E_SSL_ERROR; +		} else { +			bytes = res;  			ret = IPHONE_E_SUCCESS; +		}  	}  	datalen = ntohl(datalen); @@ -210,13 +217,18 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)  	if (!client->in_SSL) {  		/* fill buffer and request more packets if needed */  		while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { -			ret = iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes); +			ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes);  			received_bytes += bytes;  		}  	} else { -		received_bytes = gnutls_record_recv(*client->ssl_session, receive, datalen); -		if (received_bytes > 0) +		ssize_t res = gnutls_record_recv(*client->ssl_session, receive, datalen); +		if (res < 0) { +			log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_recv: Error occured: %s\n", gnutls_strerror(res)); +			ret = IPHONE_E_SSL_ERROR; +		} else { +			received_bytes = res;  			ret = IPHONE_E_SUCCESS; +		}  	}  	if (ret != IPHONE_E_SUCCESS) { @@ -224,7 +236,7 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)  		return ret;  	} -	if (received_bytes <= 0) { +	if ((ssize_t)received_bytes <= 0) {  		free(receive);  		return IPHONE_E_NOT_ENOUGH_DATA;  	} @@ -271,12 +283,22 @@ iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, plist_t plist)  	log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): made the query, sending it along\n");  	if (!client->in_SSL) -		ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes); +		ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes);  	else { -		gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); -		ret = IPHONE_E_SUCCESS; +		ssize_t res = gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); +		if (res < 0) { +			log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_send: Error occured: %s\n", gnutls_strerror(res)); +			ret = IPHONE_E_SSL_ERROR; +		} else { +			bytes = res; +			ret = IPHONE_E_SUCCESS; +		} +	} +	if (ret == IPHONE_E_SUCCESS) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): sent it!\n"); +	} else { +		log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): sending failed!\n");  	} -	log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): sent it!\n");  	free(real_query);  	return ret; @@ -425,7 +447,7 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c  				char *value_value = NULL;  				plist_get_string_val(value_value_node, &value_value); -				value->data = value_value; +				value->data = (unsigned char*)value_value;  				value->size = strlen(value_value);  				ret = IPHONE_E_SUCCESS;  			} @@ -435,7 +457,7 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c  				uint64_t size = 0;  				plist_get_data_val(value_value_node, &value_value, &size); -				value->data = value_value; +				value->data = (unsigned char*)value_value;  				value->size = size;  				ret = IPHONE_E_SUCCESS;  			} @@ -457,7 +479,7 @@ iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid  {  	gnutls_datum_t temp = { NULL, 0 };  	iphone_error_t ret = lockdownd_generic_get_value(control, "Key", "UniqueDeviceID", &temp); -	*uid = temp.data; +	*uid = (char*)temp.data;  	return ret;  } @@ -465,7 +487,7 @@ iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid   *   * @note You most likely want lockdownd_init unless you are doing something special.   * - * @return 1 on success and 0 on failure. + * @return IPHONE_E_SUCCESS on succes or an error value < 0 on failure.   */  iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key)  { @@ -733,14 +755,14 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t  			if (ASN1_SUCCESS == asn1_der_decoding(&asn1_pub_key, der_pub_key.data, der_pub_key.size, NULL)) {  				/* get size to read */ -				int ret1 = asn1_read_value(asn1_pub_key, "modulus", NULL, &modulus.size); -				int ret2 = asn1_read_value(asn1_pub_key, "publicExponent", NULL, &exponent.size); +				int ret1 = asn1_read_value(asn1_pub_key, "modulus", NULL, (int*)&modulus.size); +				int ret2 = asn1_read_value(asn1_pub_key, "publicExponent", NULL, (int*)&exponent.size);  				modulus.data = gnutls_malloc(modulus.size);  				exponent.data = gnutls_malloc(exponent.size); -				ret1 = asn1_read_value(asn1_pub_key, "modulus", modulus.data, &modulus.size); -				ret2 = asn1_read_value(asn1_pub_key, "publicExponent", exponent.data, &exponent.size); +				ret1 = asn1_read_value(asn1_pub_key, "modulus", modulus.data, (int*)&modulus.size); +				ret2 = asn1_read_value(asn1_pub_key, "publicExponent", exponent.data, (int*)&exponent.size);  				if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2)  					ret = IPHONE_E_SUCCESS;  			} @@ -755,7 +777,7 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t  	if (IPHONE_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) {  		gnutls_global_init(); -		gnutls_datum_t essentially_null = { strdup("abababababababab"), strlen("abababababababab") }; +		gnutls_datum_t essentially_null = { (unsigned char*)strdup("abababababababab"), strlen("abababababababab") };  		gnutls_x509_privkey_t fake_privkey, root_privkey, host_privkey;  		gnutls_x509_crt_t dev_cert, root_cert, host_cert; @@ -1021,12 +1043,12 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c   */  ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length)  { -	int bytes = 0; +	uint32_t bytes = 0;  	iphone_lckd_client_t control;  	control = (iphone_lckd_client_t) transport;  	log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_secuwrite() called\n");  	log_dbg_msg(DBGMASK_LOCKDOWND, "pre-send\nlength = %zi\n", length); -	iphone_mux_send(control->connection, buffer, length, &bytes); +	usbmuxd_send(control->sfd, buffer, length, &bytes);  	log_dbg_msg(DBGMASK_LOCKDOWND, "post-send\nsent %i bytes\n", bytes);  	dump_debug_buffer("sslpacketwrite.out", buffer, length); @@ -1044,7 +1066,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size  ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length)  {  	int bytes = 0, pos_start_fill = 0; -	int tbytes = 0; +	size_t tbytes = 0;  	int this_len = length;  	iphone_error_t res;  	iphone_lckd_client_t control; @@ -1059,19 +1081,12 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_  	// repeat until we have the full data or an error occurs.  	do { -		if ((res = iphone_mux_recv(control->connection, recv_buffer, this_len, &bytes)) != IPHONE_E_SUCCESS) { +		if ((res = usbmuxd_recv(control->sfd, recv_buffer, this_len, (uint32_t*)&bytes)) != IPHONE_E_SUCCESS) {  			log_debug_msg("%s: ERROR: iphone_mux_recv returned %d\n", __func__, res);  			return res;  		}  		log_debug_msg("post-read\nwe got %i bytes\n", bytes); -		if (bytes < 0) { -			log_debug_msg("lockdownd_securead(): uh oh\n"); -			log_debug_msg -				("I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n", -				 usb_strerror(), strerror(errno)); -			return bytes;		// + 28;      // an errno -		}  		// increase read count  		tbytes += bytes; 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 @@  #ifndef LOCKDOWND_H  #define LOCKDOWND_H -#include "usbmux.h" -  #include <gnutls/gnutls.h>  #include <string.h>  #include <libiphone/libiphone.h> @@ -32,7 +30,7 @@  struct iphone_lckd_client_int { -	iphone_umux_client_t connection; +	int sfd;  	gnutls_session_t *ssl_session;  	int in_SSL;  	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 @@ -/* - * usbmux.c - * Interprets the usb multiplexing protocol used by the iPhone. - * - * Copyright (c) 2008 Zach C. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  - */ - -#include <sys/types.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "usbmux.h" -#include "utils.h" - -static iphone_umux_client_t *connlist = NULL; -static int clients = 0; - -/** Creates a USBMux packet for the given set of ports. - *  - * @param s_port The source port for the connection. - * @param d_port The destination port for the connection. - * - * @return A USBMux packet - */ -usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port) -{ -	usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); -	conn->type = htonl(6); -	conn->length = 28; -	conn->sport = htons(s_port); -	conn->dport = htons(d_port); -	conn->scnt = 0; -	conn->ocnt = 0; -	conn->offset = 0x50; -	conn->window = htons(0x0200); -	conn->nullnull = 0x0000; -	conn->length16 = 28; -	return conn; -} - -/** Creates a USBMux header containing version information - *  - * @return A USBMux header - */ -usbmux_version_header *version_header(void) -{ -	usbmux_version_header *version = (usbmux_version_header *) malloc(sizeof(usbmux_version_header)); -	version->type = 0; -	version->length = htonl(20); -	version->major = htonl(1); -	version->minor = 0; -	version->allnull = 0; -	return version; -} - - -// Maintenance functions. - -/** Removes a connection from the list of connections made. - * The list of connections is necessary for buffering. - *  - * @param connection The connection to delete from the tracking list. - */ -static void delete_connection(iphone_umux_client_t connection) -{ -	iphone_umux_client_t *newlist = (iphone_umux_client_t *) malloc(sizeof(iphone_umux_client_t) * (clients - 1)); -	int i = 0, j = 0; -	for (i = 0; i < clients; i++) { -		if (connlist[i] == connection) -			continue; -		else { -			newlist[j] = connlist[i]; -			j++; -		} -	} -	free(connlist); -	connlist = newlist; -	clients--; -	if (connection->recv_buffer) -		free(connection->recv_buffer); -	if (connection->header) -		free(connection->header); -	connection->r_len = 0; -	free(connection); -} - -/** Adds a connection to the list of connections made. - * The connection list is necessary for buffering. - * - * @param connection The connection to add to the global list of connections. - */ - -static void add_connection(iphone_umux_client_t connection) -{ -	iphone_umux_client_t *newlist = -		(iphone_umux_client_t *) realloc(connlist, sizeof(iphone_umux_client_t) * (clients + 1)); -	newlist[clients] = connection; -	connlist = newlist; -	clients++; -} - -/** Initializes a connection on phone, with source port s_port and destination port d_port - * - * @param device The iPhone to initialize a connection on. - * @param src_port The source port - * @param dst_port The destination port -- 0xf27e for lockdownd.  - * @param client A mux TCP header for the connection which is used for tracking and data transfer. - * @return IPHONE_E_SUCCESS on success, an error code otherwise. - */ -iphone_error_t iphone_mux_new_client(iphone_device_t device, uint16_t src_port, uint16_t dst_port, -									 iphone_umux_client_t * client) -{ -	if (!device || !src_port || !dst_port) -		return IPHONE_E_INVALID_ARG; - -	int bytes = 0; -	// Initialize connection stuff -	iphone_umux_client_t new_connection = (iphone_umux_client_t) malloc(sizeof(struct iphone_umux_client_int)); -	new_connection->header = new_mux_packet(src_port, dst_port); - -	// blargg -	if (new_connection && new_connection->header) { -		new_connection->header->tcp_flags = 0x02; -		new_connection->header->length = htonl(new_connection->header->length); -		new_connection->header->length16 = htons(new_connection->header->length16); - -		if (send_to_phone(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { -			usbmux_tcp_header *response; -			response = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); -			bytes = recv_from_phone(device, (char *) response, sizeof(*response), 3500); -			if (response->tcp_flags != 0x12) { -				free(response); -				return IPHONE_E_UNKNOWN_ERROR; -			} else { -				free(response); - -				log_debug_msg("mux_connect: connection success\n"); -				new_connection->header->tcp_flags = 0x10; -				new_connection->header->scnt = 1; -				new_connection->header->ocnt = 1; -				new_connection->phone = device; -				new_connection->recv_buffer = NULL; -				new_connection->r_len = 0; -				add_connection(new_connection); -				*client = new_connection; -				return IPHONE_E_SUCCESS; -			} -		} else { -			return IPHONE_E_NOT_ENOUGH_DATA; -		} -	} -	// if we get to this point it's probably bad -	return IPHONE_E_UNKNOWN_ERROR; -} - -/** Cleans up the given USBMux connection. - * @note Once a connection is closed it may not be used again. - *  - * @param connection The connection to close. - * - * @return IPHONE_E_SUCCESS on success. - */ -iphone_error_t iphone_mux_free_client(iphone_umux_client_t client) -{ -	if (!client || !client->phone) -		return IPHONE_E_INVALID_ARG; - -	client->header->tcp_flags = 0x04; -	client->header->length = htonl(0x1C); -	client->header->scnt = htonl(client->header->scnt); -	client->header->ocnt = htonl(client->header->ocnt); -	client->header->window = 0; -	client->header->length16 = htons(0x1C); -	int bytes = 0; - -	bytes = usb_bulk_write(client->phone->device, BULKOUT, (char *) client->header, sizeof(usbmux_tcp_header), 800); -	if (bytes < 0) -		log_debug_msg("iphone_muxèfree_client(): when writing, libusb gave me the error: %s\n", usb_strerror()); - -	bytes = usb_bulk_read(client->phone->device, BULKIN, (char *) client->header, sizeof(usbmux_tcp_header), 800); -	if (bytes < 0) -		log_debug_msg("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); - -	delete_connection(client); - -	return IPHONE_E_SUCCESS; -} - - -/** Sends the given data over the selected connection. - * - * @param phone The iPhone to send to. - * @param client The client we're sending data on. - * @param data A pointer to the data to send. - * @param datalen How much data we're sending. - * @param sent_bytes The number of bytes sent, minus the header (28) - * - * @return IPHONE_E_SUCCESS on success. - */ - -iphone_error_t iphone_mux_send(iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t * sent_bytes) -{ -	if (!client->phone || !client || !data || datalen == 0 || !sent_bytes) -		return IPHONE_E_INVALID_ARG; -	// client->scnt and client->ocnt should already be in host notation... -	// we don't need to change them juuuust yet.  -	*sent_bytes = 0; -	log_debug_msg("mux_send(): client wants to send %i bytes\n", datalen); -	char *buffer = (char *) malloc(sizeof(usbmux_tcp_header) + datalen + 2);	// allow 2 bytes of safety padding -	// Set the length and pre-emptively htonl/htons it -	client->header->length = htonl(sizeof(usbmux_tcp_header) + datalen); -	client->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen); - -	// Put scnt and ocnt into big-endian notation -	client->header->scnt = htonl(client->header->scnt); -	client->header->ocnt = htonl(client->header->ocnt); -	// Concatenation of stuff in the buffer. -	memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); -	memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen); - -	// We have a buffer full of data, we should now send it to the phone. -	log_debug_msg("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header) + datalen, buffer); - - -	*sent_bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header) + datalen); -	log_debug_msg("mux_send: sent %i bytes!\n", *sent_bytes); -	// Now that we've sent it off, we can clean up after our sloppy selves. -	dump_debug_buffer("packet", buffer, *sent_bytes); -	if (buffer) -		free(buffer); -	// Re-calculate scnt and ocnt -	client->header->scnt = ntohl(client->header->scnt) + datalen; -	client->header->ocnt = ntohl(client->header->ocnt); - -	// Revert lengths -	client->header->length = ntohl(client->header->length); -	client->header->length16 = ntohs(client->header->length16); - -	// Now return the bytes. -	if (*sent_bytes < sizeof(usbmux_tcp_header) + datalen) { -		*sent_bytes = 0; -		return IPHONE_E_NOT_ENOUGH_DATA; -	} else { -		*sent_bytes = *sent_bytes - 28;	// actual length sent. :/ -	} - -	return IPHONE_E_SUCCESS; -} - -/** This is a higher-level USBMuxTCP-like function - * - * @param connection The connection to receive data on. - * @param data Where to put the data we receive.  - * @param datalen How much data to read. - * @param recv_bytes Pointer to a uint32_t that will be set - *        to the number of bytes received. - * @param timeout How many milliseconds to wait for data. - * - * @return IPHONE_E_SUCCESS on success, or and error value. - */ -iphone_error_t iphone_mux_recv_timeout(iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t * recv_bytes, int timeout) -{ - -	if (!client || !data || datalen == 0 || !recv_bytes) -		return IPHONE_E_INVALID_ARG; -	/* -	 * Order of operation: -	 * 1.) Check if the client has a pre-received buffer. -	 * 2.) If so, fill data with the buffer, as much as needed. -	 *      a.) Return quickly if the buffer has enough -	 *      b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return) -	 * 3.) If not, receive directly from the phone.  -	 *      a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation. -	 *      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. -	 */ -	log_debug_msg("mux_recv: datalen == %i\n", datalen); -	int bytes = 0, i = 0, complex = 0, offset = 0; -	*recv_bytes = 0; -	char *buffer = NULL; -	usbmux_tcp_header *header = NULL; - -	if (client->recv_buffer) { -		if (client->r_len >= datalen) { -			memcpy(data, client->recv_buffer, datalen); -			if (client->r_len == datalen) { -				// reset everything -				free(client->recv_buffer); -				client->r_len = 0; -				client->recv_buffer = NULL; -			} else { -				buffer = (char *) malloc(sizeof(char) * (client->r_len - datalen)); -				memcpy(buffer, client->recv_buffer + datalen, (client->r_len - datalen)); -				client->r_len -= datalen; -				free(client->recv_buffer); -				client->recv_buffer = buffer; -			} - -			// Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above. -			*recv_bytes = datalen; -			return IPHONE_E_SUCCESS; -		} else { -			memcpy(data, client->recv_buffer, client->r_len); -			free(client->recv_buffer);	// don't need to deal with anymore, but... -			client->recv_buffer = NULL; -			offset = client->r_len;	// see #2b, above -			client->r_len = 0; -		} -	}							// End of what to do if we have a pre-buffer. See #1 and #2 above.  - -	buffer = (char *) malloc(sizeof(char) * 131072);	// make sure we get enough ;) - -	// See #3. -	bytes = recv_from_phone(client->phone, buffer, 131072, timeout); -	if (bytes < 28) { -		free(buffer); -		log_debug_msg("mux_recv: Did not even get the header.\n"); -		return IPHONE_E_NOT_ENOUGH_DATA; -	} - -	header = (usbmux_tcp_header *) buffer; -	if (header->sport != client->header->dport || header->dport != client->header->sport) { -		// Ooooops -- we got someone else's packet. -		// We gotta stick it in their buffer. (Take that any old way you want ;) ) -		for (i = 0; i < clients; i++) { -			if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) { -				// we have a winner. -				char *nfb = (char *) malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); -				if (connlist[i]->recv_buffer && connlist[i]->r_len) { -					memcpy(nfb, connlist[i]->recv_buffer, connlist[i]->r_len); -					free(connlist[i]->recv_buffer); -				} -				connlist[i]->r_len += bytes - 28; -				//connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * client->r_len); // grow their buffer -				connlist[i]->recv_buffer = nfb; -				nfb = NULL;		// A cookie for you if you can guess what "nfb" means.  -				complex = connlist[i]->r_len - (bytes - 28); -				memcpy(connlist[i]->recv_buffer + complex, buffer + 28, bytes - 28);	// paste into their buffer -				connlist[i]->header->ocnt += bytes - 28; -			} -		} -		// If it wasn't ours, it's been handled by this point... or forgotten. -		// Free our buffer and continue. -		free(buffer); -		buffer = NULL; -		return iphone_mux_recv(client, data, datalen, recv_bytes);	// recurse back in to try again -	} -	// The packet was absolutely meant for us if it hits this point. -	// The pre-buffer has been taken care of, so, again, if we're at this point we have to read from the phone. - -	if ((bytes - 28) > datalen) { -		// Copy what we need into the data, buffer the rest because we can. -		memcpy(data + offset, buffer + 28, datalen);	// data+offset: see #2b, above -		complex = client->r_len + ((bytes - 28) - datalen); -		client->recv_buffer = (char *) realloc(client->recv_buffer, (sizeof(char) * complex)); -		client->r_len = complex; -		complex = client->r_len - ((bytes - 28) - datalen); -		memcpy(client->recv_buffer + complex, buffer + 28 + datalen, (bytes - 28) - datalen); -		free(buffer); -		client->header->ocnt += bytes - 28; -		*recv_bytes = datalen; -		return IPHONE_E_SUCCESS; -	} else { -		// Fill the data with what we have, and just return. -		memcpy(data + offset, buffer + 28, bytes - 28);	// data+offset: see #2b, above -		client->header->ocnt += bytes - 28; -		free(buffer); -		*recv_bytes = bytes - 28; -		return IPHONE_E_SUCCESS; -	} - -	// If we get to this point, 'tis probably bad. -	log_debug_msg("mux_recv: Heisenbug: bytes and datalen not matching up\n"); -	return IPHONE_E_UNKNOWN_ERROR; -} - -/** - * This function is just like 'iphone_mux_recv_timeout' but you do not need - * to specify a timeout. It simply calls iphone_mux_recv_timeout with a - * timeout value of 3500 milliseconds. - * - * @param connection The connection to receive data on. - * @param data Where to put the data we receive. - * @param datalen How much data to read. - * @param recv_bytes Pointer to a uint32_t that will be set - *        to the number of bytes received. - * - * @return The return value of iphone_mux_recv_timeout. - * - * @see iphone_mux_recv_timeout - */ -iphone_error_t iphone_mux_recv(iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t * recv_bytes) -{ -	return iphone_mux_recv_timeout(client, data, datalen, recv_bytes, 3500); -} 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 @@ -/* - * usbmux.h - * Defines structures and variables pertaining to the usb multiplexing. - * - * Copyright (c) 2008 Zach C. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  - */ - -#include <sys/types.h> -#include <stdlib.h> -#include <stdint.h> -#include "libiphone/libiphone.h" - -#ifndef USBMUX_H -#define USBMUX_H - -#ifndef IPHONE_H -#include "iphone.h" -#endif - -typedef struct { -	uint32_t type, length; -	uint16_t sport, dport; -	uint32_t scnt, ocnt; -	uint8_t offset, tcp_flags; -	uint16_t window, nullnull, length16; -} usbmux_tcp_header; - -struct iphone_umux_client_int { -	usbmux_tcp_header *header; -	iphone_device_t phone; -	char *recv_buffer; -	int r_len; -}; - -usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port); - -typedef struct { -	uint32_t type, length, major, minor, allnull; -} usbmux_version_header; - -usbmux_version_header *version_header(void); - - -#endif diff --git a/swig/iphone.i b/swig/iphone.i index ae2e97f..4e604e0 100644 --- a/swig/iphone.i +++ b/swig/iphone.i @@ -92,7 +92,7 @@ MobileSync* my_new_MobileSync(Lockdownd* lckd) {  		client = (MobileSync*) malloc(sizeof(MobileSync));  		client->lckd = lckd;  		client->client = NULL; -		iphone_msync_new_client ( lckd->dev->dev, 3432, port, &(client->client)); +		iphone_msync_new_client ( lckd->dev->dev, port, &(client->client));  	}  	return client;  } 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 @@ -ATTR{idVendor}!="05ac", GOTO="libiphone_rules_end" - -# Forces iPhone 1.0, 3G and iPodTouch 1 and 2 to USB configuration 3 -SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1290", ACTION=="add", ATTR{bConfigurationValue}="3" -SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1291", ACTION=="add", ATTR{bConfigurationValue}="3" -SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1292", ACTION=="add", ATTR{bConfigurationValue}="3"  -SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1293", ACTION=="add", ATTR{bConfigurationValue}="3" - -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 @@ -udevdir=$(sysconfdir)/udev/rules.d/ -udev_DATA=89-libiphone.rules - -EXTRA_DIST=$(udev_DATA) | 
