diff options
-rw-r--r-- | src/idevice.c | 83 |
1 files changed, 76 insertions, 7 deletions
diff --git a/src/idevice.c b/src/idevice.c index 0a62907..418ee86 100644 --- a/src/idevice.c +++ b/src/idevice.c @@ -421,7 +421,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t return IDEVICE_E_INVALID_ARG; } - if (device->conn_type == CONNECTION_USBMUXD || device->conn_type == CONNECTION_NETWORK) { + if (device->conn_type == CONNECTION_USBMUXD) { int sfd = usbmuxd_connect(device->mux_id, port); if (sfd < 0) { debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd)); @@ -434,6 +434,45 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t new_connection->device = device; *connection = new_connection; return IDEVICE_E_SUCCESS; + } else if (device->conn_type == CONNECTION_NETWORK) { + unsigned char saddr_[32]; + memset(saddr_, '\0', sizeof(saddr_)); + struct sockaddr* saddr = (struct sockaddr*)&saddr_[0]; + if (((char*)device->conn_data)[1] == 0x02) { // AF_INET + saddr->sa_family = AF_INET; + memcpy(&saddr->sa_data[0], (char*)device->conn_data+2, 14); + } + else if (((char*)device->conn_data)[1] == 0x1E) { //AF_INET6 (bsd) +#ifdef AF_INET6 + saddr->sa_family = AF_INET6; + memcpy(&saddr->sa_data[0], (char*)device->conn_data+2, 26); +#else + debug_info("ERROR: Got an IPv6 address but this system doesn't support IPv6"); + return IDEVICE_E_UNKNOWN_ERROR; +#endif + } + else { + debug_info("Unsupported address family 0x%02x", ((char*)device->conn_data)[1]); + return IDEVICE_E_UNKNOWN_ERROR; + } + char addrtxt[48]; + addrtxt[0] = '\0'; + if (!socket_addr_to_string(saddr, addrtxt, sizeof(addrtxt))) { + debug_info("Failed to convert network address: %d (%s)", errno, strerror(errno)); + } + debug_info("Connecting to %s port %d...", addrtxt, port); + int sfd = socket_connect_addr(saddr, port); + if (sfd < 0) { + debug_info("ERROR: Connecting to network device failed: %d (%s)", errno, strerror(errno)); + return IDEVICE_E_NO_DEVICE; + } + idevice_connection_t new_connection = (idevice_connection_t)malloc(sizeof(struct idevice_connection_private)); + new_connection->type = CONNECTION_NETWORK; + new_connection->data = (void*)(long)sfd; + new_connection->ssl_data = NULL; + new_connection->device = device; + *connection = new_connection; + return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", device->conn_type); } @@ -451,10 +490,14 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_disconnect(idevice_connection_t con idevice_connection_disable_ssl(connection); } idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { usbmuxd_disconnect((int)(long)connection->data); connection->data = NULL; result = IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { + socket_close((int)(long)connection->data); + connection->data = NULL; + result = IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); } @@ -474,13 +517,21 @@ static idevice_error_t internal_connection_send(idevice_connection_t connection, return IDEVICE_E_INVALID_ARG; } - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { int res = usbmuxd_send((int)(long)connection->data, data, len, sent_bytes); if (res < 0) { debug_info("ERROR: usbmuxd_send returned %d (%s)", res, strerror(-res)); return IDEVICE_E_UNKNOWN_ERROR; } return IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { + int s = socket_send((int)(long)connection->data, (void*)data, len); + if (s < 0) { + *sent_bytes = 0; + return IDEVICE_E_UNKNOWN_ERROR; + } + *sent_bytes = s; + return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); } @@ -545,7 +596,7 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t return IDEVICE_E_INVALID_ARG; } - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { int conn_error = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout); idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, *recv_bytes); @@ -554,6 +605,14 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t } return error; + } else if (connection->type == CONNECTION_NETWORK) { + int res = socket_receive_timeout((int)(long)connection->data, data, len, 0, timeout); + if (res < 0) { + debug_info("ERROR: socket_receive_timeout failed: %d (%s)", res, strerror(-res)); + return (res == -EAGAIN ? IDEVICE_E_NOT_ENOUGH_DATA : IDEVICE_E_UNKNOWN_ERROR); + } + *recv_bytes = (uint32_t)res; + return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); } @@ -630,13 +689,20 @@ static idevice_error_t internal_connection_receive(idevice_connection_t connecti return IDEVICE_E_INVALID_ARG; } - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { int res = usbmuxd_recv((int)(long)connection->data, data, len, recv_bytes); if (res < 0) { debug_info("ERROR: usbmuxd_recv returned %d (%s)", res, strerror(-res)); return IDEVICE_E_UNKNOWN_ERROR; } - + return IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { + int res = socket_receive((int)(long)connection->data, data, len); + if (res < 0) { + debug_info("ERROR: socket_receive returned %d (%s)", res, strerror(-res)); + return IDEVICE_E_UNKNOWN_ERROR; + } + *recv_bytes = (uint32_t)res; return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); @@ -674,7 +740,10 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_get_fd(idevice_connectio } idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { + *fd = (int)(long)connection->data; + result = IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { *fd = (int)(long)connection->data; result = IDEVICE_E_SUCCESS; } else { |