static gboolean
claim_op (GTlsConnectionBase    *tls,
	  GTlsConnectionBaseOp   op,
	  gboolean               blocking,
	  GCancellable          *cancellable,
	  GError               **error)
{
 try_again:
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  g_mutex_lock (&tls->op_mutex);

  if (((op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE ||
        op == G_TLS_CONNECTION_BASE_OP_READ) &&
       (tls->read_closing || tls->read_closed)) ||
      ((op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE ||
        op == G_TLS_CONNECTION_BASE_OP_WRITE) &&
       (tls->write_closing || tls->write_closed)))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
			   _("Connection is closed"));
      g_mutex_unlock (&tls->op_mutex);
      return FALSE;
    }

  if (tls->handshake_error &&
      op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH &&
      op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ &&
      op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE)
    {
      if (error)
	*error = g_error_copy (tls->handshake_error);
      g_mutex_unlock (&tls->op_mutex);
      return FALSE;
    }

  if (op != G_TLS_CONNECTION_BASE_OP_HANDSHAKE)
    {
      if (op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH &&
          op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ &&
          op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE &&
          tls->need_handshake && !tls->handshaking)
	{
	  tls->handshaking = TRUE;
	  if (!do_implicit_handshake (tls, blocking, cancellable, error))
	    {
	      g_cancellable_reset (tls->waiting_for_op);
	      g_mutex_unlock (&tls->op_mutex);
	      return FALSE;
	    }
	}

      if (tls->need_finish_handshake &&
	  tls->implicit_handshake)
	{
	  GError *my_error = NULL;
	  gboolean success;

	  tls->need_finish_handshake = FALSE;

	  g_mutex_unlock (&tls->op_mutex);
	  success = finish_handshake (tls, tls->implicit_handshake, &my_error);
	  g_clear_object (&tls->implicit_handshake);
	  g_mutex_lock (&tls->op_mutex);

	  if (op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH &&
	      op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ &&
	      op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE &&
	      (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error)))
	    {
	      g_propagate_error (error, my_error);
	      g_mutex_unlock (&tls->op_mutex);
	      return FALSE;
	    }

	  g_clear_error (&my_error);
	}
    }

  if ((op != G_TLS_CONNECTION_BASE_OP_WRITE && tls->reading) ||
      (op != G_TLS_CONNECTION_BASE_OP_READ && tls->writing) ||
      (op != G_TLS_CONNECTION_BASE_OP_HANDSHAKE && tls->handshaking))
    {
      GPollFD fds[2];
      int nfds;

      g_cancellable_reset (tls->waiting_for_op);

      g_mutex_unlock (&tls->op_mutex);

      if (!blocking)
	{
	  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
			       _("Operation would block"));
	  return FALSE;
	}

      g_cancellable_make_pollfd (tls->waiting_for_op, &fds[0]);
      if (g_cancellable_make_pollfd (cancellable, &fds[1]))
	nfds = 2;
      else
	nfds = 1;

      g_poll (fds, nfds, -1);

      if (nfds > 1)
        g_cancellable_release_fd (cancellable);

      goto try_again;
    }

  if (op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE)
    tls->handshaking = TRUE;
  if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH ||
      op == G_TLS_CONNECTION_BASE_OP_CLOSE_READ)
    tls->read_closing = TRUE;
  if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH ||
      op == G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE)
    tls->write_closing = TRUE;

  if (op != G_TLS_CONNECTION_BASE_OP_WRITE)
    tls->reading = TRUE;
  if (op != G_TLS_CONNECTION_BASE_OP_READ)
    tls->writing = TRUE;

  g_mutex_unlock (&tls->op_mutex);
  return TRUE;
}
/**
 * EscalateSubprocessShutdown:
 * @self: Subprocess that won't have any more messages sent to it.
 * @timeout_ms: Maximum time in milliseconds to wait for its stdout to close
 * before sending SIGKILL to the process.
 * @error: (out)(allow-none): Error return location or #NULL.
 *
 * Returns: #TRUE if stdout closed and had no more messages, or #FALSE if @error
 * is set and SIGKILL was sent.
 */
gboolean EscalateSubprocessShutdown(EscalateSubprocess *self, guint timeout_ms,
                                    GError **error) {
  GIOChannel *child_stdout = self->child_stdout;
  g_assert(child_stdout);
  GIOStatus status = G_IO_STATUS_ERROR;
  gint64 start_time = g_get_monotonic_time();
  GPollFD poll_fd = {
    g_io_channel_unix_get_fd(child_stdout), G_IO_IN | G_IO_HUP | G_IO_ERR, 0 };
  gchar leftover = '\0';
  gsize leftover_length = 0;
  gboolean result = FALSE;

  g_assert(self->child_pid);

  if (self->child_stdin)
    g_io_channel_unref(self->child_stdin);

  self->child_stdin = NULL;
  self->child_stdout = NULL;

  do {
    status = g_io_channel_set_flags(child_stdout, G_IO_FLAG_NONBLOCK, NULL);
  } while (status == G_IO_STATUS_AGAIN);
  g_assert(status == G_IO_STATUS_NORMAL);

  do {
    // Wait for stdout to be readable.
    gint poll_timeout = timeout_ms - (g_get_monotonic_time() - start_time)/1000;
    gint poll_result = 0;
    if (poll_timeout > 0)
      poll_result = g_poll(&poll_fd, 1, poll_timeout);
    if (poll_result == 0) {
      g_set_error(error, ESCALATE_SUBPROCESS_ERROR,
                  ESCALATE_SUBPROCESS_ERROR_SHUTDOWN_TIMEOUT,
                  "Timed out waiting for subprocess to exit");
      goto done;
    }

    // Try to read one more character so we know if there are any messages
    // waiting to be read.
    status = g_io_channel_read_chars(child_stdout, &leftover, 1,
                                     &leftover_length, error);
  } while (status == G_IO_STATUS_AGAIN);

  switch (status) {
    case G_IO_STATUS_NORMAL:
      g_assert(leftover_length == 1);
      g_set_error(error, ESCALATE_SUBPROCESS_ERROR,
                  ESCALATE_SUBPROCESS_ERROR_LEFTOVER_STDOUT,
                  "Subprocess stdout had unread messages");
      break;
    case G_IO_STATUS_EOF:
      result = TRUE;
      break;
    default:
      g_assert(!error || *error);
  }

done:
  if (!result && self->child_pid > 0) {
    g_assert(kill(self->child_pid, SIGKILL) == 0);
    self->child_pid = 0;
  }
  g_io_channel_unref(child_stdout);
  return result;
}
Example #3
0
static void *
arv_gv_stream_thread (void *data)
{
	ArvGvStreamThreadData *thread_data = data;
	ArvGvStreamFrameData *frame;
	ArvGvspPacket *packet;
	guint32 packet_id;
	guint32 frame_id;
	GTimeVal current_time;
	guint64 time_us;
	GPollFD poll_fd;
	size_t read_count;
	int timeout_ms;
	int n_events;
	int i;
	gboolean first_packet = TRUE;

	thread_data->frames = NULL;

	arv_debug_stream_thread ("[GvStream::stream_thread] Packet timeout = %g ms",
				 thread_data->packet_timeout_us / 1000.0);
	arv_debug_stream_thread ("[GvStream::stream_thread] Frame retention = %g ms",
				 thread_data->frame_retention_us / 1000.0);

	if (thread_data->callback != NULL)
		thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_INIT, NULL);

	poll_fd.fd = g_socket_get_fd (thread_data->socket);
	poll_fd.events =  G_IO_IN;
	poll_fd.revents = 0;

	packet = g_malloc0 (ARV_GV_STREAM_INCOMING_BUFFER_SIZE);

	do {
		if (thread_data->frames != NULL)
			timeout_ms = thread_data->packet_timeout_us / 1000;
		else
			timeout_ms = ARV_GV_STREAM_POLL_TIMEOUT_US / 1000;

		n_events = g_poll (&poll_fd, 1, timeout_ms);

		g_get_current_time (&current_time);
		time_us = current_time.tv_sec * 1000000 + current_time.tv_usec;

		if (n_events > 0) {
			thread_data->n_received_packets++;

			read_count = g_socket_receive (thread_data->socket, (char *) packet,
						       ARV_GV_STREAM_INCOMING_BUFFER_SIZE, NULL, NULL);

			frame_id = arv_gvsp_packet_get_frame_id (packet);
			packet_id = arv_gvsp_packet_get_packet_id (packet);

			if (first_packet) {
				thread_data->last_frame_id = frame_id - 1;
				first_packet = FALSE;
			}

			frame = _find_frame_data (thread_data, frame_id, packet, packet_id, read_count, time_us);

			if (frame != NULL) {
				ArvGvspPacketType packet_type = arv_gvsp_packet_get_packet_type (packet);

				if (packet_type != ARV_GVSP_PACKET_TYPE_OK &&
				    packet_type != ARV_GVSP_PACKET_TYPE_RESEND) {
					arv_debug_stream_thread ("[GvStream::stream_thread]"
								 " Error packet at dt = %" G_GINT64_FORMAT ", packet id = %u"
								 " frame id = %u",
								 time_us - frame->first_packet_time_us,
								 packet_id, frame->frame_id);
					arv_gvsp_packet_debug (packet, read_count, ARV_DEBUG_LEVEL_DEBUG);
					frame->error_packet_received = TRUE;

					thread_data->n_error_packets++;
				} else {
					/* Check for duplicated packets */
					if (packet_id < frame->n_packets) {
						if (frame->packet_data[packet_id].received)
							thread_data->n_duplicated_packets++;
						else
							frame->packet_data[packet_id].received = TRUE;
					}

					/* Keep track of last packet of a continuous block starting from packet 0 */
					for (i = frame->last_valid_packet + 1; i < frame->n_packets; i++)
						if (!frame->packet_data[i].received)
							break;
					frame->last_valid_packet = i - 1;

					switch (arv_gvsp_packet_get_content_type (packet)) {
						case ARV_GVSP_CONTENT_TYPE_DATA_LEADER:
							_process_data_leader (thread_data, frame, packet, packet_id);
							break;
						case ARV_GVSP_CONTENT_TYPE_DATA_BLOCK:
							_process_data_block (thread_data, frame, packet, packet_id,
									     read_count);
							break;
						case ARV_GVSP_CONTENT_TYPE_DATA_TRAILER:
							_process_data_trailer (thread_data, frame, packet, packet_id);
							break;
						default:
							thread_data->n_ignored_packets++;
							break;
					}

					_missing_packet_check (thread_data, frame, packet_id, time_us);
				}
			} else
				thread_data->n_ignored_packets++;
		} else
			frame = NULL;

		_check_frame_completion (thread_data, time_us, frame);
	} while (!thread_data->cancel);

	_flush_frames (thread_data);

	if (thread_data->callback != NULL)
		thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_EXIT, NULL);

	g_free (packet);

	return NULL;
}
Example #4
0
static gssize
g_unix_input_stream_read (GInputStream  *stream,
			  void          *buffer,
			  gsize          count,
			  GCancellable  *cancellable,
			  GError       **error)
{
  GUnixInputStream *unix_stream;
  gssize res = -1;
  GPollFD poll_fds[2];
  int nfds;
  int poll_ret;

  unix_stream = G_UNIX_INPUT_STREAM (stream);

  poll_fds[0].fd = unix_stream->priv->fd;
  poll_fds[0].events = G_IO_IN;
  if (unix_stream->priv->is_pipe_or_socket &&
      g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
    nfds = 2;
  else
    nfds = 1;

  while (1)
    {
      poll_fds[0].revents = poll_fds[1].revents = 0;
      do
	poll_ret = g_poll (poll_fds, nfds, -1);
      while (poll_ret == -1 && errno == EINTR);

      if (poll_ret == -1)
	{
          int errsv = errno;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error reading from file descriptor: %s"),
		       g_strerror (errsv));
	  break;
	}

      if (g_cancellable_set_error_if_cancelled (cancellable, error))
	break;

      if (!poll_fds[0].revents)
	continue;

      res = read (unix_stream->priv->fd, buffer, count);
      if (res == -1)
	{
          int errsv = errno;

	  if (errsv == EINTR || errsv == EAGAIN)
	    continue;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error reading from file descriptor: %s"),
		       g_strerror (errsv));
	}

      break;
    }

  if (nfds == 2)
    g_cancellable_release_fd (cancellable);
  return res;
}
Example #5
0
void *
_thread (void *user_data)
{
	ArvGvFakeCamera *gv_fake_camera = user_data;
	ArvBuffer *image_buffer = NULL;
	GError *error = NULL;
	GSocketAddress *stream_address = NULL;
	void *packet_buffer;
	size_t packet_size;
	size_t payload = 0;
	guint16 block_id;
	ptrdiff_t offset;
	guint32 gv_packet_size;
	GInputVector input_vector;
	int n_events;
	gboolean is_streaming = FALSE;

	input_vector.buffer = g_malloc0 (ARV_GV_FAKE_CAMERA_BUFFER_SIZE);
	input_vector.size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE;

	packet_buffer = g_malloc (ARV_GV_FAKE_CAMERA_BUFFER_SIZE);

	do {
		guint64 next_timestamp_us;
		guint64 sleep_time_us;

		if (is_streaming) {
			sleep_time_us = arv_fake_camera_get_sleep_time_for_next_frame (gv_fake_camera->priv->camera, &next_timestamp_us);
		} else {
			sleep_time_us = 100000;
			next_timestamp_us = g_get_real_time () + sleep_time_us;
		}

		do {
			gint timeout_ms;

			timeout_ms = MIN (100, (next_timestamp_us - g_get_real_time ()) / 1000LL);
			if (timeout_ms < 0)
				timeout_ms = 0;

			n_events = g_poll (gv_fake_camera->priv->gvcp_fds, 2, timeout_ms);
			if (n_events > 0) {
				GSocketAddress *remote_address = NULL;
				int count;

				count = g_socket_receive_message (gv_fake_camera->priv->gvcp_socket,
								  &remote_address, &input_vector, 1, NULL, NULL,
								  NULL, NULL, NULL);
				if (count > 0) {
					if (handle_control_packet (gv_fake_camera, gv_fake_camera->priv->gvcp_socket,
								   remote_address, input_vector.buffer, count))
						arv_debug_device ("[GvFakeCamera::thread] Control packet received");
				}
				g_clear_object (&remote_address);

				if (gv_fake_camera->priv->discovery_socket != NULL) {
					count = g_socket_receive_message (gv_fake_camera->priv->discovery_socket,
									  &remote_address, &input_vector, 1, NULL, NULL,
									  NULL, NULL, NULL);
					if (count > 0) {
						if (handle_control_packet (gv_fake_camera, gv_fake_camera->priv->discovery_socket,
									   remote_address, input_vector.buffer, count))
							arv_debug_device ("[GvFakeCamera::thread]"
									  " Control packet received on discovery socket\n");
					}
					g_clear_object (&remote_address);
				}

				if (arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) == 0 ||
				    arv_fake_camera_get_acquisition_status (gv_fake_camera->priv->camera) == 0) {
					if (stream_address != NULL) {
						g_object_unref (stream_address);
						stream_address = NULL;
						g_object_unref (image_buffer);
						image_buffer = NULL;
						arv_debug_stream_thread ("[GvFakeCamera::thread] Stop stream");
					}
					is_streaming = FALSE;
				}
			}
		} while (!g_atomic_int_get (&gv_fake_camera->priv->cancel) && g_get_real_time () < next_timestamp_us);

		if (arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) != 0 &&
		    arv_fake_camera_get_acquisition_status (gv_fake_camera->priv->camera) != 0) {
			if (stream_address == NULL) {
				GInetAddress *inet_address;
				char *inet_address_string;

				stream_address = arv_fake_camera_get_stream_address (gv_fake_camera->priv->camera);
				inet_address = g_inet_socket_address_get_address
					(G_INET_SOCKET_ADDRESS (stream_address));
				inet_address_string = g_inet_address_to_string (inet_address);
				arv_debug_stream_thread ("[GvFakeCamera::thread] Start stream to %s (%d)",
							 inet_address_string,
							 g_inet_socket_address_get_port
							 (G_INET_SOCKET_ADDRESS (stream_address)));
				g_free (inet_address_string);

				payload = arv_fake_camera_get_payload (gv_fake_camera->priv->camera);
				image_buffer = arv_buffer_new (payload, NULL);
			}

			arv_fake_camera_fill_buffer (gv_fake_camera->priv->camera, image_buffer, &gv_packet_size);

			arv_debug_stream_thread ("[GvFakeCamera::thread] Send frame %d", image_buffer->priv->frame_id);

			block_id = 0;

			packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE;
			arv_gvsp_packet_new_data_leader (image_buffer->priv->frame_id,
							 block_id,
							 image_buffer->priv->timestamp_ns,
							 image_buffer->priv->pixel_format,
							 image_buffer->priv->width, image_buffer->priv->height,
							 image_buffer->priv->x_offset, image_buffer->priv->y_offset,
							 packet_buffer, &packet_size);

			g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address,
					  packet_buffer, packet_size, NULL, &error);
			if (error != NULL) {
				arv_warning_stream_thread ("[GvFakeCamera::thread] Failed to send leader for frame %d: %s",
							   image_buffer->priv->frame_id, error->message);
				g_clear_error (&error);
			}

			block_id++;

			offset = 0;
			while (offset < payload) {
				size_t data_size;

				data_size = MIN (gv_packet_size - ARV_GVSP_PACKET_PROTOCOL_OVERHEAD,
						 payload - offset);

				packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE;
				arv_gvsp_packet_new_data_block (image_buffer->priv->frame_id, block_id,
								data_size, ((char *) image_buffer->priv->data) + offset,
								packet_buffer, &packet_size);

				g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address,
						  packet_buffer, packet_size, NULL, &error);
				if (error != NULL) {
					arv_debug_stream_thread ("[GvFakeCamera::thread] Failed to send frame block %d for frame: %s",
								 block_id,
								 image_buffer->priv->frame_id,
								 error->message);
					g_clear_error (&error);
				}

				offset += data_size;
				block_id++;
			}

			packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE;
			arv_gvsp_packet_new_data_trailer (image_buffer->priv->frame_id, block_id,
							  packet_buffer, &packet_size);

			g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address,
					  packet_buffer, packet_size, NULL, &error);
			if (error != NULL) {
				arv_debug_stream_thread ("[GvFakeCamera::thread] Failed to send trailer for frame %d: %s",
							 image_buffer->priv->frame_id,
							 error->message);
				g_clear_error (&error);
			}

			is_streaming = TRUE;
		}

	} while (!g_atomic_int_get (&gv_fake_camera->priv->cancel));

	if (stream_address != NULL)
		g_object_unref (stream_address);
	if (image_buffer != NULL)
		g_object_unref (image_buffer);

	g_free (packet_buffer);
	g_free (input_vector.buffer);

	return NULL;
}
Example #6
0
static gboolean
_read_memory (ArvGvDeviceIOData *io_data, guint32 address, guint32 size, void *buffer, GError **error)
{
	ArvGvcpPacket *packet;
	size_t packet_size;
	size_t answer_size;
	int count;
	unsigned int n_retries = 0;
	gboolean success = FALSE;

	answer_size = arv_gvcp_packet_get_read_memory_ack_size (size);

	g_return_val_if_fail (answer_size <= ARV_GV_DEVICE_BUFFER_SIZE, FALSE);

	g_mutex_lock (io_data->mutex);

	packet = arv_gvcp_packet_new_read_memory_cmd (address,
						      ((size + sizeof (guint32) - 1)
						       / sizeof (guint32)) * sizeof (guint32),
						      0, &packet_size);

	do {
		io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id);
		arv_gvcp_packet_set_packet_id (packet, io_data->packet_id);

		arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);

		g_socket_send_to (io_data->socket, io_data->device_address,
				  (const char *) packet, packet_size,
				  NULL, NULL);

		if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) {
			count = g_socket_receive (io_data->socket, io_data->buffer,
						  ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
			if (count >= answer_size) {
				ArvGvcpPacket *ack_packet = io_data->buffer;
				ArvGvcpPacketType packet_type;
				ArvGvcpCommand command;
				guint16 packet_id;

				arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);

				packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
				command = arv_gvcp_packet_get_command (ack_packet);
				packet_id = arv_gvcp_packet_get_packet_id (ack_packet);

				if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
				    command == ARV_GVCP_COMMAND_READ_MEMORY_ACK &&
				    packet_id == io_data->packet_id) {
					memcpy (buffer, arv_gvcp_packet_get_read_memory_ack_data (ack_packet), size);
					success = TRUE;
				} else
					arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
			}
		}

		n_retries++;

	} while (!success && n_retries < io_data->gvcp_n_retries);

	arv_gvcp_packet_free (packet);

	g_mutex_unlock (io_data->mutex);

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

	return success;
}
Example #7
0
gboolean
_write_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 value, GError **error)
{
	ArvGvcpPacket *packet;
	size_t packet_size;
	int count;
	unsigned int n_retries = 0;
	gboolean success = FALSE;

	g_mutex_lock (io_data->mutex);

	packet = arv_gvcp_packet_new_write_register_cmd (address, value, io_data->packet_id, &packet_size);

	do {
		io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id);
		arv_gvcp_packet_set_packet_id (packet, io_data->packet_id);

		arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);

		g_socket_send_to (io_data->socket, io_data->device_address, (const char *) packet, packet_size,
				  NULL, NULL);

		if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) {
			count = g_socket_receive (io_data->socket, io_data->buffer,
						  ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
			if (count > 0) {
				ArvGvcpPacket *ack_packet = io_data->buffer;
				ArvGvcpPacketType packet_type;
				ArvGvcpCommand command;
				guint16 packet_id;

				arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);

				packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
				command = arv_gvcp_packet_get_command (ack_packet);
				packet_id = arv_gvcp_packet_get_packet_id (ack_packet);

				arv_log_gvcp ("%d, %d, %d", packet_type, command, packet_id);

				if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
				    command == ARV_GVCP_COMMAND_WRITE_REGISTER_ACK &&
				    packet_id == io_data->packet_id)
					success = TRUE;
				else
					arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
			}
		}

		n_retries++;

	} while (!success && n_retries < io_data->gvcp_n_retries);

	arv_gvcp_packet_free (packet);

	g_mutex_unlock (io_data->mutex);

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

	return success;
}
Example #8
0
static gboolean
g_unix_output_stream_writev (GOutputStream        *stream,
			     const GOutputVector  *vectors,
			     gsize                 n_vectors,
			     gsize                *bytes_written,
			     GCancellable         *cancellable,
			     GError              **error)
{
  GUnixOutputStream *unix_stream;
  gssize res = -1;
  GPollFD poll_fds[2];
  int nfds = 0;
  int poll_ret;
  struct iovec *iov;

  if (bytes_written)
    *bytes_written = 0;

  /* Clamp to G_MAXINT as writev() takes an integer for the number of vectors.
   * We handle this like a short write in this case
   */
  if (n_vectors > G_MAXINT)
    n_vectors = G_MAXINT;

  unix_stream = G_UNIX_OUTPUT_STREAM (stream);

  if (G_OUTPUT_VECTOR_IS_IOVEC)
    {
      /* ABI is compatible */
      iov = (struct iovec *) vectors;
    }
  else
    {
      gsize i;

      /* ABI is incompatible */
      iov = g_newa (struct iovec, n_vectors);
      for (i = 0; i < n_vectors; i++)
        {
          iov[i].iov_base = (void *)vectors[i].buffer;
          iov[i].iov_len = vectors[i].size;
        }
    }

  poll_fds[0].fd = unix_stream->priv->fd;
  poll_fds[0].events = G_IO_OUT;
  nfds++;

  if (unix_stream->priv->is_pipe_or_socket &&
      g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
    nfds++;

  while (1)
    {
      int errsv;

      poll_fds[0].revents = poll_fds[1].revents = 0;
      do
        {
          poll_ret = g_poll (poll_fds, nfds, -1);
          errsv = errno;
        }
      while (poll_ret == -1 && errsv == EINTR);

      if (poll_ret == -1)
	{
	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to file descriptor: %s"),
		       g_strerror (errsv));
	  break;
	}

      if (g_cancellable_set_error_if_cancelled (cancellable, error))
	break;

      if (!poll_fds[0].revents)
	continue;

      res = writev (unix_stream->priv->fd, iov, n_vectors);
      errsv = errno;
      if (res == -1)
	{
	  if (errsv == EINTR || errsv == EAGAIN)
	    continue;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to file descriptor: %s"),
		       g_strerror (errsv));
	}

      if (bytes_written)
        *bytes_written = res;

      break;
    }

  if (nfds == 2)
    g_cancellable_release_fd (cancellable);
  return res != -1;
}
Example #9
0
static void
arv_gv_interface_discover (ArvGvInterface *gv_interface)
{
	ArvGvDiscoverSocketList *socket_list;
	GSList *iter;
	char buffer[ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE];
	int count;
	int i;

	socket_list = arv_gv_discover_socket_list_new ();

	if (socket_list->n_sockets < 1) {
		arv_gv_discover_socket_list_free (socket_list);
		return;
	}

	arv_gv_discover_socket_list_send_discover_packet (socket_list);

	do {
		if (g_poll (socket_list->poll_fds, socket_list->n_sockets, ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0) {
			arv_gv_discover_socket_list_free (socket_list);
			return;
		}

		for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) {
			ArvGvDiscoverSocket *discover_socket = iter->data;

			do {
				g_socket_set_blocking (discover_socket->socket, FALSE);
				count = g_socket_receive (discover_socket->socket, buffer, ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE,
							  NULL, NULL);
				g_socket_set_blocking (discover_socket->socket, TRUE);

				if (count > 0) {
					ArvGvcpPacket *packet = (ArvGvcpPacket *) buffer;

					if (g_ntohs (packet->header.command) == ARV_GVCP_COMMAND_DISCOVERY_ACK &&
					    g_ntohs (packet->header.id) == 0xffff) {
						ArvGvInterfaceDeviceInfos *device_infos;
						GInetAddress *interface_address;
						char *address_string;
						char *data = buffer + sizeof (ArvGvcpHeader);

						arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);

						interface_address = g_inet_socket_address_get_address
							(G_INET_SOCKET_ADDRESS (discover_socket->interface_address));
						device_infos = arv_gv_interface_device_infos_new (interface_address,
												  data);
						address_string = g_inet_address_to_string (interface_address);

						arv_debug_interface ("[GvInterface::discovery] Device '%s' found "
								     "(interface %s) user_name '%s' - MAC_name '%s'",
								     device_infos->name, address_string,
								     device_infos->user_name,
								     device_infos->mac_string);

						g_free (address_string);

						if (device_infos->name != NULL && device_infos->name[0] != '\0') {
							arv_gv_interface_device_infos_ref (device_infos);
							g_hash_table_insert (gv_interface->priv->devices,
									     device_infos->name, device_infos);
						}
						if (device_infos->user_name != NULL && device_infos->user_name[0] != '\0') {
							arv_gv_interface_device_infos_ref (device_infos);
							g_hash_table_insert (gv_interface->priv->devices,
									     device_infos->user_name, device_infos);
						}
						arv_gv_interface_device_infos_ref (device_infos);
						g_hash_table_insert (gv_interface->priv->devices, device_infos->mac_string, device_infos);

						arv_gv_interface_device_infos_unref (device_infos);
					}
				}
			} while (count > 0);
		}
	} while (1);
}
Example #10
0
int
main (int argc, char **argv)
{
	ArvFakeGvCamera *gv_camera;
	int n_events;
	GInputVector input_vector;
	GOptionContext *context;
	GError *error = NULL;

	arv_g_thread_init (NULL);
	arv_g_type_init ();

	context = g_option_context_new (NULL);
	g_option_context_set_summary (context, "Fake GigEVision camera.");
	g_option_context_set_description (context, "Example: 'arv-fake-gv-camera-" ARAVIS_API_VERSION " -i eth0'");
	g_option_context_add_main_entries (context, arv_option_entries, NULL);

	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		g_option_context_free (context);
		g_print ("Option parsing failed: %s\n", error->message);
		g_error_free (error);
		return EXIT_FAILURE;
	}

	g_option_context_free (context);

	arv_debug_enable (arv_option_debug_domains);

	gv_camera = arv_fake_gv_camera_new (arv_option_interface_name);
	if (gv_camera == NULL) {
		g_print ("Can't instantiate a new fake camera.\n");
		g_print ("An existing instance may already use the '%s' interface.\n", arv_option_interface_name);
		return EXIT_FAILURE;
	}

	input_vector.buffer = g_malloc0 (ARV_FAKE_GV_CAMERA_BUFFER_SIZE);
	input_vector.size = ARV_FAKE_GV_CAMERA_BUFFER_SIZE;

	signal (SIGINT, set_cancel);

	do {
		n_events = g_poll (gv_camera->gvcp_fds, 2, 1000);
		g_print ("n_events = %d\n", n_events);
		if (n_events > 0) {
			GSocketAddress *remote_address;
			int count;

			count = g_socket_receive_message (gv_camera->gvcp_socket,
							  &remote_address, &input_vector, 1, NULL, NULL,
							  G_SOCKET_MSG_NONE, NULL, NULL);
			if (count > 0)
				handle_control_packet (gv_camera, gv_camera->gvcp_socket,
						       remote_address, input_vector.buffer, count);

			if (gv_camera->discovery_socket != NULL) {
				count = g_socket_receive_message (gv_camera->discovery_socket,
								  &remote_address, &input_vector, 1, NULL, NULL,
								  G_SOCKET_MSG_NONE, NULL, NULL);
				if (count > 0)
					handle_control_packet (gv_camera, gv_camera->discovery_socket,
							       remote_address, input_vector.buffer, count);
			}
		}
	} while (!cancel);

	g_free (input_vector.buffer);

	arv_fake_gv_camera_free (gv_camera);

	return EXIT_SUCCESS;
}