summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2025-11-25 01:02:31 +0100
committerGravatar Nikias Bassen2025-11-25 01:02:31 +0100
commitca85a1829c275635f7b2854887f6490dcb3c5e40 (patch)
treed236c9d1329abd6a8f1600ff2c5c742878b716aa
parentc194db388fb7f1f65ef0a08817f26ed0e8d078b3 (diff)
downloadlibimobiledevice-ca85a1829c275635f7b2854887f6490dcb3c5e40.tar.gz
libimobiledevice-ca85a1829c275635f7b2854887f6490dcb3c5e40.tar.bz2
afc: Improve error handling
-rw-r--r--include/libimobiledevice/afc.h1
-rw-r--r--src/afc.c78
2 files changed, 64 insertions, 15 deletions
diff --git a/include/libimobiledevice/afc.h b/include/libimobiledevice/afc.h
index 3dcb5da..6e404c3 100644
--- a/include/libimobiledevice/afc.h
+++ b/include/libimobiledevice/afc.h
@@ -64,6 +64,7 @@ typedef enum {
64 AFC_E_NO_MEM = 31, 64 AFC_E_NO_MEM = 31,
65 AFC_E_NOT_ENOUGH_DATA = 32, 65 AFC_E_NOT_ENOUGH_DATA = 32,
66 AFC_E_DIR_NOT_EMPTY = 33, 66 AFC_E_DIR_NOT_EMPTY = 33,
67 AFC_E_SSL_ERROR = 34,
67 AFC_E_FORCE_SIGNED_TYPE = -1 68 AFC_E_FORCE_SIGNED_TYPE = -1
68} afc_error_t; 69} afc_error_t;
69 70
diff --git a/src/afc.c b/src/afc.c
index c7eed5c..e2e5ba1 100644
--- a/src/afc.c
+++ b/src/afc.c
@@ -59,6 +59,27 @@ static void afc_unlock(afc_client_t client)
59 mutex_unlock(&client->mutex); 59 mutex_unlock(&client->mutex);
60} 60}
61 61
62static afc_error_t service_to_afc_error(service_error_t err)
63{
64 switch (err) {
65 case SERVICE_E_SUCCESS:
66 return AFC_E_SUCCESS;
67 case SERVICE_E_INVALID_ARG:
68 return AFC_E_INVALID_ARG;
69 case SERVICE_E_MUX_ERROR:
70 return AFC_E_MUX_ERROR;
71 case SERVICE_E_SSL_ERROR:
72 return AFC_E_SSL_ERROR;
73 case SERVICE_E_NOT_ENOUGH_DATA:
74 return AFC_E_NOT_ENOUGH_DATA;
75 case SERVICE_E_TIMEOUT:
76 return AFC_E_OP_TIMEOUT;
77 default:
78 break;
79 }
80 return AFC_E_UNKNOWN_ERROR;
81}
82
62/** 83/**
63 * Makes a connection to the AFC service on the device using the given 84 * Makes a connection to the AFC service on the device using the given
64 * connection. 85 * connection.
@@ -174,11 +195,16 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation,
174 AFCPacket_to_LE(client->afc_packet); 195 AFCPacket_to_LE(client->afc_packet);
175 debug_buffer((char*)client->afc_packet, sizeof(AFCPacket) + data_length); 196 debug_buffer((char*)client->afc_packet, sizeof(AFCPacket) + data_length);
176 sent = 0; 197 sent = 0;
177 service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket) + data_length, &sent); 198 afc_error_t err = service_to_afc_error(service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket) + data_length, &sent));
178 AFCPacket_from_LE(client->afc_packet); 199 AFCPacket_from_LE(client->afc_packet);
200 if (err != AFC_E_SUCCESS) {
201 debug_info("Failed to send packet (sent %i/%i): %s (%d)", sent, sizeof(AFCPacket) + data_length, afc_strerror(err), err);
202 return err;
203 }
179 *bytes_sent += sent; 204 *bytes_sent += sent;
180 if (sent < sizeof(AFCPacket) + data_length) { 205 if (sent < sizeof(AFCPacket) + data_length) {
181 return AFC_E_SUCCESS; 206 debug_info("Failed to send entire packet (sent %i/%i)", sent, sizeof(AFCPacket) + data_length);
207 return AFC_E_NOT_ENOUGH_DATA;
182 } 208 }
183 209
184 sent = 0; 210 sent = 0;
@@ -190,11 +216,16 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation,
190 debug_info("packet payload follows"); 216 debug_info("packet payload follows");
191 debug_buffer(payload, payload_length); 217 debug_buffer(payload, payload_length);
192 } 218 }
193 service_send(client->parent, payload, payload_length, &sent); 219 err = service_to_afc_error(service_send(client->parent, payload, payload_length, &sent));
220 if (err != AFC_E_SUCCESS) {
221 debug_info("Failed to send payload (sent: %i/%i): %s (%d)", sent, payload_length, afc_strerror(err), err);
222 return err;
223 }
194 } 224 }
195 *bytes_sent += sent; 225 *bytes_sent += sent;
196 if (sent < payload_length) { 226 if (sent < payload_length) {
197 return AFC_E_SUCCESS; 227 debug_info("Failed to send entire payload (sent: %i/%i): %s (%d)", sent, payload_length, afc_strerror(err), err);
228 return AFC_E_NOT_ENOUGH_DATA;
198 } 229 }
199 230
200 return AFC_E_SUCCESS; 231 return AFC_E_SUCCESS;
@@ -227,21 +258,28 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t
227 } 258 }
228 259
229 /* first, read the AFC header */ 260 /* first, read the AFC header */
230 service_receive(client->parent, (char*)&header, sizeof(AFCPacket), &recv_len); 261 afc_error_t err = service_to_afc_error(service_receive(client->parent, (char*)&header, sizeof(AFCPacket), &recv_len));
231 AFCPacket_from_LE(&header); 262 if (err != AFC_E_SUCCESS) {
263 debug_info("Failed to receive AFC header: %s (%d)", afc_strerror(err), err);
264 return err;
265 }
232 if (recv_len == 0) { 266 if (recv_len == 0) {
233 debug_info("Just didn't get enough."); 267 debug_info("Just didn't get enough.");
234 return AFC_E_MUX_ERROR; 268 return AFC_E_NOT_ENOUGH_DATA;
235 } 269 }
236 270
237 if (recv_len < sizeof(AFCPacket)) { 271 if (recv_len < sizeof(AFCPacket)) {
238 debug_info("Did not even get the AFCPacket header"); 272 debug_info("Did not even get the AFCPacket header");
239 return AFC_E_MUX_ERROR; 273 return AFC_E_NOT_ENOUGH_DATA;
240 } 274 }
241 275
276 /* make sure endianness is correct */
277 AFCPacket_from_LE(&header);
278
242 /* check if it's a valid AFC header */ 279 /* check if it's a valid AFC header */
243 if (strncmp(header.magic, AFC_MAGIC, AFC_MAGIC_LEN) != 0) { 280 if (strncmp(header.magic, AFC_MAGIC, AFC_MAGIC_LEN) != 0) {
244 debug_info("Invalid AFC packet received (magic != " AFC_MAGIC ")!"); 281 debug_info("Invalid AFC packet received (magic != " AFC_MAGIC ")!");
282 return AFC_E_UNKNOWN_PACKET_TYPE;
245 } 283 }
246 284
247 /* check if it has the correct packet number */ 285 /* check if it has the correct packet number */
@@ -273,16 +311,20 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t
273 buf = (char*)malloc(entire_len); 311 buf = (char*)malloc(entire_len);
274 if (this_len > 0) { 312 if (this_len > 0) {
275 recv_len = 0; 313 recv_len = 0;
276 service_receive(client->parent, buf, this_len, &recv_len); 314 err = service_to_afc_error(service_receive(client->parent, buf, this_len, &recv_len));
315 if (err != AFC_E_SUCCESS) {
316 free(buf);
317 debug_info("Failed to receive data: %s (%d)", afc_strerror(err), err);
318 }
277 if (recv_len <= 0) { 319 if (recv_len <= 0) {
278 free(buf); 320 free(buf);
279 debug_info("Did not get packet contents!"); 321 debug_info("Did not get packet contents!");
280 return AFC_E_NOT_ENOUGH_DATA; 322 return (err == AFC_E_SUCCESS) ? AFC_E_NOT_ENOUGH_DATA : err;
281 } 323 }
282 if (recv_len < this_len) { 324 if (recv_len < this_len) {
283 free(buf); 325 free(buf);
284 debug_info("Could not receive this_len=%d bytes", this_len); 326 debug_info("Could not receive this_len=%d bytes", this_len);
285 return AFC_E_NOT_ENOUGH_DATA; 327 return (err == AFC_E_SUCCESS) ? AFC_E_END_OF_DATA : err;
286 } 328 }
287 } 329 }
288 330
@@ -291,7 +333,11 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t
291 if (entire_len > this_len) { 333 if (entire_len > this_len) {
292 while (current_count < entire_len) { 334 while (current_count < entire_len) {
293 recv_len = 0; 335 recv_len = 0;
294 service_receive(client->parent, buf+current_count, entire_len - current_count, &recv_len); 336 err = service_to_afc_error(service_receive(client->parent, buf+current_count, entire_len - current_count, &recv_len));
337 if (err != AFC_E_SUCCESS) {
338 debug_info("Error receiving data: %s (%d)", afc_strerror(err), err);
339 break;
340 }
295 if (recv_len <= 0) { 341 if (recv_len <= 0) {
296 debug_info("Error receiving data (recv returned %d)", recv_len); 342 debug_info("Error receiving data (recv returned %d)", recv_len);
297 break; 343 break;
@@ -299,7 +345,9 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t
299 current_count += recv_len; 345 current_count += recv_len;
300 } 346 }
301 if (current_count < entire_len) { 347 if (current_count < entire_len) {
302 debug_info("WARNING: could not receive full packet (read %s, size %d)", current_count, entire_len); 348 free(buf);
349 debug_info("ERROR: Could not receive entire packet (read %i/%i)", current_count, entire_len);
350 return (err == AFC_E_SUCCESS) ? AFC_E_END_OF_DATA : err;
303 } 351 }
304 } 352 }
305 353
@@ -1299,14 +1347,14 @@ const char* afc_strerror(afc_error_t err)
1299 return "Internal error"; 1347 return "Internal error";
1300 case AFC_E_MUX_ERROR: 1348 case AFC_E_MUX_ERROR:
1301 return "MUX error"; 1349 return "MUX error";
1350 case AFC_E_SSL_ERROR:
1351 return "SSL error";
1302 case AFC_E_NO_MEM: 1352 case AFC_E_NO_MEM:
1303 return "Out of memory"; 1353 return "Out of memory";
1304 case AFC_E_NOT_ENOUGH_DATA: 1354 case AFC_E_NOT_ENOUGH_DATA:
1305 return "Not enough data"; 1355 return "Not enough data";
1306 case AFC_E_DIR_NOT_EMPTY: 1356 case AFC_E_DIR_NOT_EMPTY:
1307 return "Directory not empty"; 1357 return "Directory not empty";
1308 case AFC_E_FORCE_SIGNED_TYPE:
1309 return "Force signed type";
1310 default: 1358 default:
1311 break; 1359 break;
1312 } 1360 }