From eac909b522bb405cd34a8fb48259ea3952d2360a Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Fri, 5 Nov 2010 18:03:51 +0100 Subject: afc: new function afc_client_new_from_connection This function allows creating an afc client upon an already established connection. This is for example required for the house_arrest service. --- include/libimobiledevice/afc.h | 1 + src/afc.c | 80 +++++++++++++++++++++++++++++++----------- src/afc.h | 1 + 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/include/libimobiledevice/afc.h b/include/libimobiledevice/afc.h index 5b06e2c..8d47696 100644 --- a/include/libimobiledevice/afc.h +++ b/include/libimobiledevice/afc.h @@ -92,6 +92,7 @@ typedef struct afc_client_private afc_client_private; typedef afc_client_private *afc_client_t; /**< The client handle. */ /* Interface */ +afc_error_t afc_client_new_from_connection(idevice_connection_t connection, afc_client_t *client); afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t *client); afc_error_t afc_client_free(afc_client_t client); afc_error_t afc_get_device_info(afc_client_t client, char ***infos); diff --git a/src/afc.c b/src/afc.c index 825ccd4..989d0ec 100644 --- a/src/afc.c +++ b/src/afc.c @@ -54,39 +54,35 @@ static void afc_unlock(afc_client_t client) } /** - * Makes a connection to the AFC service on the phone. - * - * @param device The device to connect to. - * @param port The destination port. + * Makes a connection to the AFC service on the device using the given + * connection. + * + * @param connection An idevice_connection_t that must have been previously + * connected using idevice_connect(). Note that this connection will + * not be closed by calling afc_client_free(). * @param client Pointer that will be set to a newly allocated afc_client_t * upon successful return. * - * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG when device or port is - * invalid, AFC_E_MUX_ERROR when the connection failed, or AFC_E_NO_MEM if - * there is a memory allocation problem. + * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG if connection is + * invalid, or AFC_E_NO_MEM if there is a memory allocation problem. */ -afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * client) + +afc_error_t afc_client_new_from_connection(idevice_connection_t connection, afc_client_t *client) { /* makes sure thread environment is available */ if (!g_thread_supported()) g_thread_init(NULL); - if (!device || port==0) + if (!connection) return AFC_E_INVALID_ARG; - /* attempt connection */ - idevice_connection_t connection = NULL; - if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) { - return AFC_E_MUX_ERROR; - } - afc_client_t client_loc = (afc_client_t) malloc(sizeof(struct afc_client_private)); client_loc->connection = connection; + client_loc->own_connection = 0; /* allocate a packet */ client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); if (!client_loc->afc_packet) { - idevice_disconnect(client_loc->connection); free(client_loc); return AFC_E_NO_MEM; } @@ -104,16 +100,60 @@ afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * clien } /** - * Disconnects an AFC client from the phone. + * Makes a connection to the AFC service on the device. + * This function calls afc_client_new_from_connection() after creating + * a connection to the specified device and port. + * + * @see afc_client_new_from_connection * - * @param client The client to disconnect. + * @param device The device to connect to. + * @param port The destination port. + * @param client Pointer that will be set to a newly allocated afc_client_t + * upon successful return. + * + * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG if device or port is + * invalid, AFC_E_MUX_ERROR if the connection cannot be established, + * or AFC_E_NO_MEM if there is a memory allocation problem. + */ +afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * client) +{ + /* makes sure thread environment is available */ + if (!g_thread_supported()) + g_thread_init(NULL); + + if (!device || port==0) + return AFC_E_INVALID_ARG; + + /* attempt connection */ + idevice_connection_t connection = NULL; + if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) { + return AFC_E_MUX_ERROR; + } + + afc_error_t err = afc_client_new_from_connection(connection, client); + if (err != AFC_E_SUCCESS) { + idevice_disconnect(connection); + } else { + (*client)->own_connection = 1; + } + return err; +} + +/** + * Frees up an AFC client. If the connection was created by the + * client itself, the connection will be closed. + * + * @param client The client to free. */ afc_error_t afc_client_free(afc_client_t client) { - if (!client || !client->connection || !client->afc_packet) + if (!client || !client->afc_packet) return AFC_E_INVALID_ARG; - idevice_disconnect(client->connection); + if (client->own_connection && client->connection) { + idevice_disconnect(client->connection); + client->connection = NULL; + } free(client->afc_packet); if (client->mutex) { g_mutex_free(client->mutex); diff --git a/src/afc.h b/src/afc.h index 15ecbd8..9c9f12d 100644 --- a/src/afc.h +++ b/src/afc.h @@ -54,6 +54,7 @@ struct afc_client_private { int file_handle; int lock; GMutex *mutex; + int own_connection; }; /* AFC Operations */ -- cgit v1.1-32-gdbae