Exemplo n.º 1
0
void *th_communication_tcp(void *args)
{
	idevice_t device;
	idevice_connection_t device_connection;

	int c_sockfd, len, sent_bytes, r;

	device = ((comm_snippet_t)args)->device;
	device_connection = ((comm_snippet_t)args)->device_connection;
	c_sockfd = ((comm_snippet_t)args)->c_sockfd;

	char *buf = (char *)malloc(sizeof(char) * COM_SIZE);
	((comm_snippet_t)args)->tcp_buf = buf;
	while(1) {
		if((len = recv(c_sockfd, buf, COM_SIZE - 1, 0)) > 0) {
			r = idevice_connection_send(device_connection, buf, len, &sent_bytes);
			if(r) {
				sign_free(((comm_snippet_t)args));
			}
		}
		else if(!len) {
			sign_free(((comm_snippet_t)args));
		}
	}
	return 0;
}
/**
 * Sends a plist using the given property list service client.
 * Internally used generic plist send function.
 *
 * @param client The property list service client to use for sending.
 * @param plist plist to send
 * @param binary 1 = send binary plist, 0 = send xml plist
 *
 * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success,
 *      PROPERTY_LIST_SERVICE_E_INVALID_ARG when one or more parameters are
 *      invalid, PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid
 *      plist, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified
 *      error occurs.
 */
static property_list_service_error_t internal_plist_send(property_list_service_client_t client, plist_t plist, int binary)
{
	property_list_service_error_t res = PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR;
	char *content = NULL;
	uint32_t length = 0;
	uint32_t nlen = 0;
	int bytes = 0;

	if (!client || (client && !client->connection) || !plist) {
		return PROPERTY_LIST_SERVICE_E_INVALID_ARG;
	}

	if (binary) {
		plist_to_bin(plist, &content, &length);
	} else {
		plist_to_xml(plist, &content, &length);
	}

	if (!content || length == 0) {
		return PROPERTY_LIST_SERVICE_E_PLIST_ERROR;
	}

	nlen = htobe32(length);
	debug_info("sending %d bytes", length);
	idevice_connection_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes);
	if (bytes == sizeof(nlen)) {
		idevice_connection_send(client->connection, content, length, (uint32_t*)&bytes);
		if (bytes > 0) {
			debug_info("sent %d bytes", bytes);
			debug_plist(plist);
			if ((uint32_t)bytes == length) {
				res = PROPERTY_LIST_SERVICE_E_SUCCESS;
			} else {
				debug_info("ERROR: Could not send all data (%d of %d)!", bytes, length);
			}
		}
	}
	if (bytes <= 0) {
		debug_info("ERROR: sending to device failed.");
	}

	free(content);

	return res;
}
Exemplo n.º 3
0
int asr_send_buffer(asr_client_t asr, const char* data, uint32_t size) {
	uint32_t bytes = 0;
	idevice_error_t device_error = IDEVICE_E_SUCCESS;

	device_error = idevice_connection_send(asr->connection, data, size, &bytes);
	if (device_error != IDEVICE_E_SUCCESS || bytes != size) {
		error("ERROR: Unable to send data to ASR. Sent %u of %u bytes.\n", bytes, size);
		return -1;
	}

	return 0;
}
Exemplo n.º 4
0
int asr_send_buffer(idevice_connection_t asr, const char* data, uint32_t size) {
	uint32_t bytes = 0;
	idevice_error_t device_error = IDEVICE_E_SUCCESS;

	device_error = idevice_connection_send(asr, data, size, &bytes);
	if (device_error != IDEVICE_E_SUCCESS || bytes != size) {
		error("ERROR: Unable to send data to ASR\n");
		return -1;
	}

	debug("Sent %d bytes buffer\n", bytes);

	return 0;
}
Exemplo n.º 5
0
/**
 * Sends data using the given service client.
 *
 * @param client The service client to use for sending.
 * @param data Data to send
 * @param size Size of the data to send
 * @param sent Number of bytes sent (can be NULL to ignore)
 *
 * @return SERVICE_E_SUCCESS on success,
 *      SERVICE_E_INVALID_ARG when one or more parameters are
 *      invalid, or SERVICE_E_UNKNOWN_ERROR when an unspecified
 *      error occurs.
 */
service_error_t service_send(service_client_t client, const char* data, uint32_t size, uint32_t *sent)
{
	service_error_t res = SERVICE_E_UNKNOWN_ERROR;
	int bytes = 0;

	if (!client || (client && !client->connection) || !data || (size == 0)) {
		return SERVICE_E_INVALID_ARG;
	}

	debug_info("sending %d bytes", size);
	res = idevice_to_service_error(idevice_connection_send(client->connection, data, size, (uint32_t*)&bytes));
	if (bytes <= 0) {
		debug_info("ERROR: sending to device failed.");
	}
	if (sent) {
		*sent = (uint32_t)bytes;
	}

	return res;
}
Exemplo n.º 6
0
/* TODO: Move idevice_connection_send_all\idevice_connection_receive_all to libimobiledevice? */
static idevice_error_t idevice_connection_send_all(idevice_connection_t connection, const char * data, uint32_t length)
{
    size_t cur_bytes_sent = 0;
    size_t total_bytes_sent = 0;
    size_t bytes_left = length;
    idevice_error_t res = IDEVICE_E_SUCCESS;

    while (total_bytes_sent < length) {
        res = idevice_connection_send(connection, data + total_bytes_sent, bytes_left, &cur_bytes_sent);
        if (IDEVICE_E_SUCCESS != res) {
            error("ERROR: Unable to send data\n");
            break;
        }

        total_bytes_sent += cur_bytes_sent;
        bytes_left -= cur_bytes_sent;
    }

    return res;
}
Exemplo n.º 7
0
SWIGEXPORT jshort JNICALL Java_org_robovm_libimobiledevice_binding_libimobiledeviceJNI_idevice_1connection_1send(JNIEnv *jenv, jclass jcls, jlong jarg1, jstring jarg2, jint jarg3, jlong jarg4, jobject jarg4_) {
  jshort jresult = 0 ;
  idevice_connection_t arg1 = (idevice_connection_t) 0 ;
  char *arg2 = (char *) 0 ;
  uint32_t arg3 ;
  uint32_t *arg4 = (uint32_t *) 0 ;
  idevice_error_t result;
  
  (void)jenv;
  (void)jcls;
  (void)jarg4_;
  arg1 = *(idevice_connection_t *)&jarg1; 
  arg2 = 0;
  if (jarg2) {
    arg2 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg2, 0);
    if (!arg2) return 0;
  }
  arg3 = (uint32_t)jarg3; 
  arg4 = *(uint32_t **)&jarg4; 
  result = (idevice_error_t)idevice_connection_send(arg1,(char const *)arg2,arg3,arg4);
  jresult = (jshort)result; 
  if (arg2) (*jenv)->ReleaseStringUTFChars(jenv, jarg2, (const char *)arg2);
  return jresult;
}
Exemplo n.º 8
0
static void *thread_client_to_device(void *data)
{
	socket_info_t* socket_info = (socket_info_t*)data;
	idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR;

	int recv_len;
	int sent;
	char buffer[131072];
	thread_t dtoc;

	debug("%s: started thread...\n", __func__);

	debug("%s: client_fd = %d\n", __func__, socket_info->client_fd);
	debug("%s: server_fd = %d\n", __func__, socket_info->server_fd);

	/* spawn server to client thread */
	socket_info->stop_dtoc = 0;
	if (thread_create(&dtoc, thread_device_to_client, data) != 0) {
		fprintf(stderr, "Failed to start device to client thread...\n");
	}

	while (!quit_flag && !socket_info->stop_ctod && socket_info->client_fd > 0 && socket_info->server_fd > 0) {
		debug("%s: receiving data from client...\n", __func__);

		/* attempt to read incoming data from client */
		recv_len = socket_receive_timeout(socket_info->client_fd, buffer, sizeof(buffer), 0, 5000);

		/* any data received? */
		if (recv_len <= 0) {
			if (recv_len == 0) {
				/* try again */
				continue;
			} else {
				fprintf(stderr, "Receive failed: %s\n", strerror(errno));
				break;
			}
		} else {
			/* forward data to device */
			debug("%s: sending data to device...\n", __func__);
			res = idevice_connection_send(socket_info->device_connection, buffer, recv_len, (uint32_t*)&sent);

			if (sent < recv_len || res != IDEVICE_E_SUCCESS) {
				if (sent <= 0) {
					fprintf(stderr, "send failed: %s\n", strerror(errno));
					break;
				} else {
					fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len);
				}
			} else {
				// sending succeeded, receive from device
				debug("%s: sent %d bytes to device\n", __func__, sent);
			}
		}
	}

	debug("%s: shutting down...\n", __func__);

	socket_shutdown(socket_info->client_fd, SHUT_RDWR);
	socket_close(socket_info->client_fd);

	socket_info->client_fd = -1;
	socket_info->stop_dtoc = 1;

	/* join other thread to allow it to stop */
	thread_join(dtoc);

	return NULL;
}
Exemplo n.º 9
0
/**
 * Dispatches an AFC packet over a client.
 * 
 * @param client The client to send data through.
 * @param data The data to send.
 * @param length The length to send.
 * @param bytes_sent The number of bytes actually sent.
 *
 * @return AFC_E_SUCCESS on success or an AFC_E_* error value.
 * 
 * @warning set client->afc_packet->this_length and
 *          client->afc_packet->entire_length to 0 before calling this.  The
 *          reason is that if you set them to different values, it indicates
 *          you want to send the data as two packets.
 */
static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, uint32_t length, uint32_t *bytes_sent)
{
	uint32_t offset = 0;
	uint32_t sent = 0;

	if (!client || !client->connection || !client->afc_packet)
		return AFC_E_INVALID_ARG;

	*bytes_sent = 0;

	if (!data || !length)
		length = 0;

	client->afc_packet->packet_num++;
	if (!client->afc_packet->entire_length) {
		client->afc_packet->entire_length = (length) ? sizeof(AFCPacket) + length : sizeof(AFCPacket);
		client->afc_packet->this_length = client->afc_packet->entire_length;
	}
	if (!client->afc_packet->this_length) {
		client->afc_packet->this_length = sizeof(AFCPacket);
	}
	/* We want to send two segments; buffer+sizeof(AFCPacket) to this_length
	   is the parameters and everything beyond that is the next packet.
	   (for writing) */
	if (client->afc_packet->this_length != client->afc_packet->entire_length) {
		offset = client->afc_packet->this_length - sizeof(AFCPacket);

		debug_info("Offset: %i", offset);
		if ((length) < (client->afc_packet->entire_length - client->afc_packet->this_length)) {
			debug_info("Length did not resemble what it was supposed to based on packet");
			debug_info("length minus offset: %i", length - offset);
			debug_info("rest of packet: %i\n", client->afc_packet->entire_length - client->afc_packet->this_length);
			return AFC_E_INTERNAL_ERROR;
		}

		/* send AFC packet header */
		AFCPacket_to_LE(client->afc_packet);
		sent = 0;
		idevice_connection_send(client->connection, (void*)client->afc_packet, sizeof(AFCPacket), &sent);
		AFCPacket_from_LE(client->afc_packet);
		if (sent == 0) {
			/* FIXME: should this be handled as success?! */
			return AFC_E_SUCCESS;
		}
		*bytes_sent += sent;

		/* send AFC packet data */
		sent = 0;
		idevice_connection_send(client->connection, data, offset, &sent);
		if (sent == 0) {
			return AFC_E_SUCCESS;
		}
		*bytes_sent += sent;

		debug_info("sent the first now go with the second");
		debug_info("Length: %i", length - offset);
		debug_info("Buffer: ");
		debug_buffer(data + offset, length - offset);

		sent = 0;
		idevice_connection_send(client->connection, data + offset, length - offset, &sent);

		*bytes_sent = sent;
		return AFC_E_SUCCESS;
	} else {
		debug_info("doin things the old way");
		debug_info("packet length = %i", client->afc_packet->this_length);

		debug_buffer((char*)client->afc_packet, sizeof(AFCPacket));

		/* send AFC packet header */
		AFCPacket_to_LE(client->afc_packet);
		sent = 0;
		idevice_connection_send(client->connection, (void*)client->afc_packet, sizeof(AFCPacket), &sent);
		AFCPacket_from_LE(client->afc_packet);
		if (sent == 0) {
			return AFC_E_SUCCESS;
		}
		*bytes_sent += sent;
		/* send AFC packet data (if there's data to send) */
		if (length > 0) {
			debug_info("packet data follows");

			debug_buffer(data, length);
			idevice_connection_send(client->connection, data, length, &sent);
			*bytes_sent += sent;
		}
		return AFC_E_SUCCESS;
	}
	return AFC_E_INTERNAL_ERROR;
}