diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/AFC.c | 75 | ||||
| -rw-r--r-- | src/AFC.h | 4 | ||||
| -rw-r--r-- | src/Makefile.am | 7 | ||||
| -rw-r--r-- | src/MobileSync.c | 25 | ||||
| -rw-r--r-- | src/MobileSync.h | 3 | ||||
| -rw-r--r-- | src/NotificationProxy.c | 47 | ||||
| -rw-r--r-- | src/NotificationProxy.h | 3 | ||||
| -rw-r--r-- | src/iphone.c | 295 | ||||
| -rw-r--r-- | src/iphone.h | 17 | ||||
| -rw-r--r-- | src/lockdown.c | 25 | ||||
| -rw-r--r-- | src/lockdown.h | 4 | ||||
| -rw-r--r-- | src/usbmux.c | 410 | ||||
| -rw-r--r-- | src/usbmux.h | 58 | 
13 files changed, 148 insertions, 825 deletions
| @@ -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 2ae1943..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) $(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..28670de 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" @@ -53,13 +52,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 +168,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,7 +198,7 @@ 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) @@ -210,7 +211,7 @@ 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); //iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes);  			received_bytes += bytes;  		}  	} else { @@ -271,7 +272,7 @@ 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); //iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes);  	else {  		gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length));  		ret = IPHONE_E_SUCCESS; @@ -465,7 +466,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)  { @@ -1026,7 +1027,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size  	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); @@ -1059,7 +1060,7 @@ 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, &bytes)) != IPHONE_E_SUCCESS) {  			log_debug_msg("%s: ERROR: iphone_mux_recv returned %d\n", __func__, res);  			return res;  		} 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 | 
