summaryrefslogtreecommitdiffstats
path: root/src/idevice.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idevice.c')
-rw-r--r--src/idevice.c59
1 files changed, 48 insertions, 11 deletions
diff --git a/src/idevice.c b/src/idevice.c
index be29884..5d5c950 100644
--- a/src/idevice.c
+++ b/src/idevice.c
@@ -43,6 +43,7 @@
43 43
44#include "idevice.h" 44#include "idevice.h"
45#include "common/userpref.h" 45#include "common/userpref.h"
46#include "common/socket.h"
46#include "common/thread.h" 47#include "common/thread.h"
47#include "common/debug.h" 48#include "common/debug.h"
48 49
@@ -381,6 +382,24 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_
381 return internal_connection_send(connection, data, len, sent_bytes); 382 return internal_connection_send(connection, data, len, sent_bytes);
382} 383}
383 384
385static idevice_error_t socket_recv_to_idevice_error(int conn_error, uint32_t len, uint32_t received)
386{
387 if (conn_error < 0) {
388 switch (conn_error) {
389 case -EAGAIN:
390 debug_info("ERROR: received partial data %d/%d (%s)", received, len, strerror(-conn_error));
391 return IDEVICE_E_NOT_ENOUGH_DATA;
392 case -ETIMEDOUT:
393 debug_info("ERROR: received timeout (%s)", strerror(-conn_error));
394 return IDEVICE_E_TIMEOUT;
395 default:
396 return IDEVICE_E_UNKNOWN_ERROR;
397 }
398 }
399
400 return IDEVICE_E_SUCCESS;
401}
402
384/** 403/**
385 * Internally used function for receiving raw data over the given connection 404 * Internally used function for receiving raw data over the given connection
386 * using a timeout. 405 * using a timeout.
@@ -392,12 +411,14 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t
392 } 411 }
393 412
394 if (connection->type == CONNECTION_USBMUXD) { 413 if (connection->type == CONNECTION_USBMUXD) {
395 int res = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout); 414 int conn_error = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout);
396 if (res < 0) { 415 idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, *recv_bytes);
397 debug_info("ERROR: usbmuxd_recv_timeout returned %d (%s)", res, strerror(errno)); 416
398 return (res == -EAGAIN ? IDEVICE_E_NOT_ENOUGH_DATA : IDEVICE_E_UNKNOWN_ERROR); 417 if (error == IDEVICE_E_UNKNOWN_ERROR) {
418 debug_info("ERROR: usbmuxd_recv_timeout returned %d (%s)", conn_error, strerror(-conn_error));
399 } 419 }
400 return IDEVICE_E_SUCCESS; 420
421 return error;
401 } else { 422 } else {
402 debug_info("Unknown connection type %d", connection->type); 423 debug_info("Unknown connection type %d", connection->type);
403 } 424 }
@@ -406,13 +427,27 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t
406 427
407LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) 428LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout)
408{ 429{
409 if (!connection || (connection->ssl_data && !connection->ssl_data->session)) { 430 if (!connection || (connection->ssl_data && !connection->ssl_data->session) || len == 0) {
410 return IDEVICE_E_INVALID_ARG; 431 return IDEVICE_E_INVALID_ARG;
411 } 432 }
412 433
413 if (connection->ssl_data) { 434 if (connection->ssl_data) {
414 uint32_t received = 0; 435 uint32_t received = 0;
436
415 while (received < len) { 437 while (received < len) {
438
439 int conn_error = socket_check_fd((int)(long)connection->data, FDM_READ, timeout);
440 idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, received);
441
442 switch (error) {
443 case IDEVICE_E_SUCCESS:
444 break;
445 case IDEVICE_E_UNKNOWN_ERROR:
446 debug_info("ERROR: socket_check_fd returned %d (%s)", conn_error, strerror(-conn_error));
447 default:
448 return error;
449 }
450
416#ifdef HAVE_OPENSSL 451#ifdef HAVE_OPENSSL
417 int r = SSL_read(connection->ssl_data->session, (void*)((char*)(data+received)), (int)len-received); 452 int r = SSL_read(connection->ssl_data->session, (void*)((char*)(data+received)), (int)len-received);
418#else 453#else
@@ -424,13 +459,15 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_
424 break; 459 break;
425 } 460 }
426 } 461 }
462
427 debug_info("SSL_read %d, received %d", len, received); 463 debug_info("SSL_read %d, received %d", len, received);
428 if (received > 0) { 464 if (received < len) {
429 *recv_bytes = received; 465 *recv_bytes = 0;
430 return IDEVICE_E_SUCCESS; 466 return IDEVICE_E_SSL_ERROR;
431 } 467 }
432 *recv_bytes = 0; 468
433 return IDEVICE_E_SSL_ERROR; 469 *recv_bytes = received;
470 return IDEVICE_E_SUCCESS;
434 } 471 }
435 return internal_connection_receive_timeout(connection, data, len, recv_bytes, timeout); 472 return internal_connection_receive_timeout(connection, data, len, recv_bytes, timeout);
436} 473}