diff options
author | Nikias Bassen | 2010-11-05 18:03:51 +0100 |
---|---|---|
committer | Nikias Bassen | 2010-11-05 18:03:51 +0100 |
commit | eac909b522bb405cd34a8fb48259ea3952d2360a (patch) | |
tree | 31d084bd251c1fc9a3bac949aa24c52befe66de5 | |
parent | 8dff982f54ea9fc2a3a4366b1958120d89f862b5 (diff) | |
download | libimobiledevice-eac909b522bb405cd34a8fb48259ea3952d2360a.tar.gz libimobiledevice-eac909b522bb405cd34a8fb48259ea3952d2360a.tar.bz2 |
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.
-rw-r--r-- | include/libimobiledevice/afc.h | 1 | ||||
-rw-r--r-- | src/afc.c | 80 | ||||
-rw-r--r-- | 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); @@ -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); @@ -54,6 +54,7 @@ struct afc_client_private { int file_handle; int lock; GMutex *mutex; + int own_connection; }; /* AFC Operations */ |