summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2010-11-05 18:03:51 +0100
committerGravatar Nikias Bassen2010-11-05 18:03:51 +0100
commiteac909b522bb405cd34a8fb48259ea3952d2360a (patch)
tree31d084bd251c1fc9a3bac949aa24c52befe66de5 /src
parent8dff982f54ea9fc2a3a4366b1958120d89f862b5 (diff)
downloadlibimobiledevice-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.
Diffstat (limited to 'src')
-rw-r--r--src/afc.c80
-rw-r--r--src/afc.h1
2 files changed, 61 insertions, 20 deletions
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)
54} 54}
55 55
56/** 56/**
57 * Makes a connection to the AFC service on the phone. 57 * Makes a connection to the AFC service on the device using the given
58 * 58 * connection.
59 * @param device The device to connect to. 59 *
60 * @param port The destination port. 60 * @param connection An idevice_connection_t that must have been previously
61 * connected using idevice_connect(). Note that this connection will
62 * not be closed by calling afc_client_free().
61 * @param client Pointer that will be set to a newly allocated afc_client_t 63 * @param client Pointer that will be set to a newly allocated afc_client_t
62 * upon successful return. 64 * upon successful return.
63 * 65 *
64 * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG when device or port is 66 * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG if connection is
65 * invalid, AFC_E_MUX_ERROR when the connection failed, or AFC_E_NO_MEM if 67 * invalid, or AFC_E_NO_MEM if there is a memory allocation problem.
66 * there is a memory allocation problem.
67 */ 68 */
68afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * client) 69
70afc_error_t afc_client_new_from_connection(idevice_connection_t connection, afc_client_t *client)
69{ 71{
70 /* makes sure thread environment is available */ 72 /* makes sure thread environment is available */
71 if (!g_thread_supported()) 73 if (!g_thread_supported())
72 g_thread_init(NULL); 74 g_thread_init(NULL);
73 75
74 if (!device || port==0) 76 if (!connection)
75 return AFC_E_INVALID_ARG; 77 return AFC_E_INVALID_ARG;
76 78
77 /* attempt connection */
78 idevice_connection_t connection = NULL;
79 if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) {
80 return AFC_E_MUX_ERROR;
81 }
82
83 afc_client_t client_loc = (afc_client_t) malloc(sizeof(struct afc_client_private)); 79 afc_client_t client_loc = (afc_client_t) malloc(sizeof(struct afc_client_private));
84 client_loc->connection = connection; 80 client_loc->connection = connection;
81 client_loc->own_connection = 0;
85 82
86 /* allocate a packet */ 83 /* allocate a packet */
87 client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); 84 client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket));
88 if (!client_loc->afc_packet) { 85 if (!client_loc->afc_packet) {
89 idevice_disconnect(client_loc->connection);
90 free(client_loc); 86 free(client_loc);
91 return AFC_E_NO_MEM; 87 return AFC_E_NO_MEM;
92 } 88 }
@@ -104,16 +100,60 @@ afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * clien
104} 100}
105 101
106/** 102/**
107 * Disconnects an AFC client from the phone. 103 * Makes a connection to the AFC service on the device.
104 * This function calls afc_client_new_from_connection() after creating
105 * a connection to the specified device and port.
106 *
107 * @see afc_client_new_from_connection
108 * 108 *
109 * @param client The client to disconnect. 109 * @param device The device to connect to.
110 * @param port The destination port.
111 * @param client Pointer that will be set to a newly allocated afc_client_t
112 * upon successful return.
113 *
114 * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG if device or port is
115 * invalid, AFC_E_MUX_ERROR if the connection cannot be established,
116 * or AFC_E_NO_MEM if there is a memory allocation problem.
117 */
118afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * client)
119{
120 /* makes sure thread environment is available */
121 if (!g_thread_supported())
122 g_thread_init(NULL);
123
124 if (!device || port==0)
125 return AFC_E_INVALID_ARG;
126
127 /* attempt connection */
128 idevice_connection_t connection = NULL;
129 if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) {
130 return AFC_E_MUX_ERROR;
131 }
132
133 afc_error_t err = afc_client_new_from_connection(connection, client);
134 if (err != AFC_E_SUCCESS) {
135 idevice_disconnect(connection);
136 } else {
137 (*client)->own_connection = 1;
138 }
139 return err;
140}
141
142/**
143 * Frees up an AFC client. If the connection was created by the
144 * client itself, the connection will be closed.
145 *
146 * @param client The client to free.
110 */ 147 */
111afc_error_t afc_client_free(afc_client_t client) 148afc_error_t afc_client_free(afc_client_t client)
112{ 149{
113 if (!client || !client->connection || !client->afc_packet) 150 if (!client || !client->afc_packet)
114 return AFC_E_INVALID_ARG; 151 return AFC_E_INVALID_ARG;
115 152
116 idevice_disconnect(client->connection); 153 if (client->own_connection && client->connection) {
154 idevice_disconnect(client->connection);
155 client->connection = NULL;
156 }
117 free(client->afc_packet); 157 free(client->afc_packet);
118 if (client->mutex) { 158 if (client->mutex) {
119 g_mutex_free(client->mutex); 159 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 {
54 int file_handle; 54 int file_handle;
55 int lock; 55 int lock;
56 GMutex *mutex; 56 GMutex *mutex;
57 int own_connection;
57}; 58};
58 59
59/* AFC Operations */ 60/* AFC Operations */