Beispiel #1
0
static void *
arv_gv_device_heartbeat_thread (void *data)
{
	ArvGvDeviceHeartbeatData *thread_data = data;
	ArvGvDeviceIOData *io_data = thread_data->io_data;
	GTimer *timer;
	guint32 value;

	timer = g_timer_new ();

	do {
		g_usleep (thread_data->period_us);

		if (io_data->is_controller) {
			guint counter = 1;

			/* TODO: Instead of reading the control register, Pylon does write the heartbeat
			 * timeout value, which is interresting, as doing this we could get an error
			 * ack packet which will indicate we lost the control access. */

			g_timer_start (timer);

			while (!_read_register (io_data, ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_OFFSET, &value, NULL) &&
			       g_timer_elapsed (timer, NULL) < ARV_GV_DEVICE_HEARTBEAT_RETRY_TIMEOUT_S &&
			       !thread_data->cancel) {
				g_usleep (ARV_GV_DEVICE_HEARTBEAT_RETRY_DELAY_US);
				counter++;
			}

			if (!thread_data->cancel) {
				arv_log_device ("[GvDevice::Heartbeat] Ack value = %d", value);

				if (counter > 1)
					arv_log_device ("[GvDevice::Heartbeat] Tried %u times", counter);

				if ((value & (ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_CONTROL |
					      ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_EXCLUSIVE)) == 0) {
					arv_warning_device ("[GvDevice::Heartbeat] Control access lost");

					arv_device_emit_control_lost_signal (ARV_DEVICE (thread_data->gv_device));

					io_data->is_controller = FALSE;
				}
			} else
				io_data->is_controller = FALSE;
		}
	} while (!thread_data->cancel);

	g_timer_destroy (timer);

	return NULL;
}
Beispiel #2
0
static gboolean
_write_memory (ArvUvDevice *uv_device, guint64 address, guint32 size, void *buffer, GError **error)
{
	ArvUvcpPacket *packet;
	void *read_packet;
	size_t packet_size;
	size_t read_packet_size;
	gboolean success = FALSE;
	unsigned n_tries = 0;
	guint32 timeout_ms = 0;

	read_packet_size = arv_uvcp_packet_get_write_memory_ack_size ();
	if (read_packet_size > uv_device->priv->ack_packet_size_max) {
		arv_debug_device ("Invalid acknowledge packet size (%d / max: %d)",
				  read_packet_size, uv_device->priv->ack_packet_size_max);
		return FALSE;
	}

	packet = arv_uvcp_packet_new_write_memory_cmd (address, size, 0, &packet_size);
	if (packet_size > uv_device->priv->cmd_packet_size_max) {
		arv_debug_device ("Invalid command packet size (%d / max: %d)", packet_size, uv_device->priv->cmd_packet_size_max);
		arv_uvcp_packet_free (packet);
		return FALSE;
	}

	memcpy (arv_uvcp_packet_get_write_memory_cmd_data (packet), buffer, size);
	read_packet = g_malloc (read_packet_size);

	do {
		GError *error = NULL;
		size_t transferred;

		uv_device->priv->packet_id = arv_uvcp_next_packet_id (uv_device->priv->packet_id);
		arv_uvcp_packet_set_packet_id (packet, uv_device->priv->packet_id);

		arv_uvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);

		success = TRUE;
		success = success && arv_uv_device_bulk_transfer (uv_device, ARV_UV_ENDPOINT_CONTROL, LIBUSB_ENDPOINT_OUT,
								  packet, packet_size, NULL, 0, &error);
		if (success ) {
			gboolean expected_answer;

			do {
				success = TRUE;
				success = success && arv_uv_device_bulk_transfer (uv_device, ARV_UV_ENDPOINT_CONTROL, LIBUSB_ENDPOINT_IN,
										  read_packet, read_packet_size, &transferred,
										  timeout_ms, &error);

				if (success) {
					ArvUvcpPacketType packet_type;
					ArvUvcpCommand command;
					guint16 packet_id;

					packet_type = arv_uvcp_packet_get_packet_type (read_packet);
					command = arv_uvcp_packet_get_command (read_packet);
					packet_id = arv_uvcp_packet_get_packet_id (read_packet);

					if (command == ARV_UVCP_COMMAND_PENDING_ACK) {
						expected_answer = FALSE;
						timeout_ms = arv_uvcp_packet_get_pending_ack_timeout (read_packet);

						arv_log_device ("[UvDevice::write_memory] Pending ack timeout = %d", timeout_ms);
					} else
						expected_answer = packet_type == ARV_UVCP_PACKET_TYPE_ACK &&
							command == ARV_UVCP_COMMAND_WRITE_MEMORY_ACK &&
							packet_id == uv_device->priv->packet_id;
				} else {
					expected_answer = FALSE;
					if (error != NULL)
						g_warning ("[UvDevice::write_memory] Ack reception error: %s", error->message);
					g_clear_error (&error);
				}

			} while (success && !expected_answer);

			success = success && expected_answer;

			if (success)
				arv_uvcp_packet_debug (read_packet, ARV_DEBUG_LEVEL_LOG);
		} else {
			if (error != NULL)
				g_warning ("[UvDevice::write_memory] Command sending error: %s", error->message);
			g_clear_error (&error);
		}

		n_tries++;
	} while (!success && n_tries < ARV_UV_DEVICE_N_TRIES_MAX);

	g_free (read_packet);
	arv_uvcp_packet_free (packet);

	if (!success) {
		if (error != NULL && *error == NULL)
			*error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT,
					      "[ArvDevice::write_memory] Timeout");
	}

	return success;
}