コード例 #1
0
/**
 * tp_stream_tube_channel_dup_parameters_vardict:
 * @self: a #TpStreamTubeChannel
 *
 * Return the parameters of the dbus-tube channel in a variant of
 * type %G_VARIANT_TYPE_VARDICT whose keys are strings representing
 * parameter names and values are variants representing corresponding
 * parameter values set by the offerer when offering this channel.
 *
 * The GVariant returned is %NULL if this is an outgoing tube that has not
 * yet been offered or the parameters property has not been set.
 *
 * Use g_variant_lookup(), g_variant_lookup_value(), or tp_vardict_get_uint32()
 * and similar functions for convenient access to the values.
 *
 * Returns: (transfer full): a new reference to a #GVariant
 *
 * Since: 0.19.10
 */
GVariant *
tp_stream_tube_channel_dup_parameters_vardict (TpStreamTubeChannel *self)
{
  g_return_val_if_fail (TP_IS_STREAM_TUBE_CHANNEL (self), NULL);

  if (self->priv->parameters == NULL)
      return NULL;

  return _tp_asv_to_vardict (self->priv->parameters);
}
static void
create_channel_cb (GObject *acr,
    GAsyncResult *res,
    gpointer user_data)
{
  GSimpleAsyncResult *simple = user_data;
  CreateTubeData *data;
  GError *error = NULL;

  data = g_simple_async_result_get_op_res_gpointer (simple);

  data->channel = tp_account_channel_request_create_and_handle_channel_finish (
      TP_ACCOUNT_CHANNEL_REQUEST (acr), res, NULL, &error);
  if (!TP_IS_STREAM_TUBE_CHANNEL (data->channel))
    {
      tp_clear_object (&data->channel);

      if (error == NULL)
        error = g_error_new_literal (TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
            "Not supported channel type");

      create_tube_complete (simple, error);

      g_clear_error (&error);
      g_object_unref (simple);
      return;
    }

  g_signal_connect (data->channel, "invalidated",
      G_CALLBACK (create_tube_channel_invalidated_cb), simple);

  g_signal_connect_data (data->channel, "incoming",
      G_CALLBACK (create_tube_incoming_cb),
      g_object_ref (simple), (GClosureNotify) g_object_unref, 0);

  tp_stream_tube_channel_offer_async (TP_STREAM_TUBE_CHANNEL (data->channel),
      NULL, create_tube_offer_cb, g_object_ref (simple));

  g_object_unref (simple);
}
コード例 #3
0
static void
handle_channels_cb (TpSimpleHandler *handler,
    TpAccount *account,
    TpConnection *connection,
    GList *channels,
    GList *requests_satisfied,
    gint64 user_action_time,
    TpHandleChannelsContext *context,
    gpointer user_data)
{
  VinoTubeServersManager *self = user_data;
  VinoTubeServer *server;
  GdkDisplay *display;
  GdkScreen *screen;
  /* the server is listenning only on lo as only the tube is supposed to
  connect to it */
  gchar * network_interface = "lo";
  GList *l;
  TpStreamTubeChannel *channel = NULL;

  for (l = channels; l != NULL; l = g_list_next (l))
    {
      TpStreamTubeChannel *chan = l->data;

      if (!TP_IS_STREAM_TUBE_CHANNEL (chan))
        continue;

      if (tp_proxy_get_invalidated (chan) != NULL)
        continue;

      if (tp_strdiff (tp_stream_tube_channel_get_service (chan), "rfb"))
        continue;

      channel = chan;
      break;
    }

  if (channel == NULL)
    {
      /* No stream tube channel ?! */
      GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
          "No stream tube channel" };

      tp_handle_channels_context_fail (context, &error);
      return;
    }

  display = gdk_display_get_default ();
  screen = gdk_display_get_default_screen (display);

  server = g_object_new (VINO_TYPE_TUBE_SERVER,
      "display-status-icon",  0,
      "prompt-enabled",       0,
      "view-only",            0,
      "network-interface",    network_interface,
      "use-alternative-port", 1,
      "alternative-port",     self->priv->alternative_port,
      "auth-methods",         1,
      "require-encryption",   0,
      "vnc-password",         NULL,
      "on-hold",              0,
      "screen",               screen,
      "lock-screen",          0,
      "disable-background",   0,
      "use-upnp",             0,
      "tube",                 channel,
      NULL);

  self->priv->vino_tube_servers = g_slist_prepend
      (self->priv->vino_tube_servers, server);

  g_signal_connect (G_OBJECT (server), "disconnected", G_CALLBACK
      (vino_tube_servers_manager_disconnected_cb), self);

  self->priv->alternative_port++;

  vino_tube_server_share_with_tube (server, NULL);

  tp_handle_channels_context_accept (context);
}
コード例 #4
0
/**
 * tp_stream_tube_channel_accept_async:
 * @self: an incoming #TpStreamTubeChannel
 * @callback: a callback to call when the tube has been accepted
 * @user_data: data to pass to @callback
 *
 * Accept an incoming stream tube. When the tube has been accepted, @callback
 * will be called. You can then call tp_stream_tube_channel_accept_finish()
 * to get a #TpStreamTubeConnection connected to the tube.
 *
 * Since: 0.13.2
 */
void
tp_stream_tube_channel_accept_async (TpStreamTubeChannel *self,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  GHashTable *properties;
  GHashTable *supported_sockets;
  GError *error = NULL;

  g_return_if_fail (TP_IS_STREAM_TUBE_CHANNEL (self));
  g_return_if_fail (self->priv->result == NULL);

  if (self->priv->access_control_param != NULL)
    {
      g_simple_async_report_error_in_idle (G_OBJECT (self), callback, user_data,
          TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Tube has already be accepted");

      return;
    }

  self->priv->result = g_simple_async_result_new (G_OBJECT (self), callback,
      user_data, tp_stream_tube_channel_accept_async);

  properties = _tp_channel_get_immutable_properties (TP_CHANNEL (self));
  supported_sockets = tp_asv_get_boxed (properties,
      TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SUPPORTED_SOCKET_TYPES,
      TP_HASH_TYPE_SUPPORTED_SOCKET_MAP);

  if (!_tp_set_socket_address_type_and_access_control_type (supported_sockets,
      &self->priv->socket_type, &self->priv->access_control, &error))
    {
      operation_failed (self, error);

      g_clear_error (&error);
      return;
    }

  DEBUG ("Using socket type %u with access control %u", self->priv->socket_type,
      self->priv->access_control);

  self->priv->client_socket = _tp_create_client_socket (self->priv->socket_type,
      &error);

  if (error != NULL)
    {
      DEBUG ("Failed to create socket: %s", error->message);

      operation_failed (self, error);
      g_clear_error (&error);
      return;
    }

  switch (self->priv->access_control)
    {
      case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
        /* Put a dummy value */
        self->priv->access_control_param = tp_g_value_slice_new_uint (0);
        break;

      case TP_SOCKET_ACCESS_CONTROL_PORT:
        {
          GSocketAddress *addr;
          guint16 port;

          addr = g_socket_get_local_address (self->priv->client_socket, &error);
          if (addr == NULL)
            {
              DEBUG ("Failed to get local address of client socket: %s",
                  error->message);

              operation_failed (self, error);
              g_error_free (error);
              return;
            }

          port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
          self->priv->access_control_param = tp_g_value_slice_new_uint (port);

          g_object_unref (addr);
        }
        break;

      case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
        self->priv->access_control_param = tp_g_value_slice_new_byte (
            g_random_int_range (0, G_MAXUINT8));
        break;

      default:
        g_assert_not_reached ();
    }

  /* Call Accept */
  tp_cli_channel_type_stream_tube_call_accept (TP_CHANNEL (self), -1,
      self->priv->socket_type, self->priv->access_control,
      self->priv->access_control_param, _channel_accepted,
      NULL, NULL, G_OBJECT (self));
}
コード例 #5
0
/**
 * tp_stream_tube_channel_offer_async:
 * @self: an outgoing #TpStreamTubeChannel
 * @params: (allow-none) (transfer none): parameters of the tube, or %NULL
 * @callback: a callback to call when the tube has been offered
 * @user_data: data to pass to @callback
 *
 * Offer an outgoing stream tube. When the tube has been offered, @callback
 * will be called. You can then call tp_stream_tube_channel_offer_finish()
 * to get the result of the operation.
 *
 * You have to connect to the #TpStreamTubeChannel::incoming signal to get a
 * #TpStreamTubeConnection each time a contact establishes a connection to
 * the tube.
 *
 * Since: 0.13.2
 */
void
tp_stream_tube_channel_offer_async (TpStreamTubeChannel *self,
    GHashTable *params,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  GHashTable *properties;
  GHashTable *supported_sockets;
  GError *error = NULL;

  g_return_if_fail (TP_IS_STREAM_TUBE_CHANNEL (self));
  g_return_if_fail (self->priv->result == NULL);
  g_return_if_fail (tp_channel_get_requested (TP_CHANNEL (self)));

  if (self->priv->service != NULL)
    {
      g_critical ("Can't reoffer Tube!");
      return;
    }

  self->priv->result = g_simple_async_result_new (G_OBJECT (self), callback,
      user_data, tp_stream_tube_channel_offer_async);

  properties = _tp_channel_get_immutable_properties (TP_CHANNEL (self));
  supported_sockets = tp_asv_get_boxed (properties,
      TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SUPPORTED_SOCKET_TYPES,
      TP_HASH_TYPE_SUPPORTED_SOCKET_MAP);

  if (!_tp_set_socket_address_type_and_access_control_type (supported_sockets,
      &self->priv->socket_type, &self->priv->access_control, &error))
    {
      operation_failed (self, error);

      g_clear_error (&error);
      return;
    }

  DEBUG ("Using socket type %u with access control %u", self->priv->socket_type,
      self->priv->access_control);

  self->priv->service = g_socket_service_new ();

  switch (self->priv->socket_type)
    {
#ifdef HAVE_GIO_UNIX
      case TP_SOCKET_ADDRESS_TYPE_UNIX:
        {
          self->priv->address = _tp_create_temp_unix_socket (
              self->priv->service, &error);

          /* check there wasn't an error on the final attempt */
          if (self->priv->address == NULL)
            {
              operation_failed (self, error);

              g_clear_error (&error);
              return;
            }
        }

        break;
#endif /* HAVE_GIO_UNIX */

      case TP_SOCKET_ADDRESS_TYPE_IPV4:
      case TP_SOCKET_ADDRESS_TYPE_IPV6:
        {
          GInetAddress *localhost;
          GSocketAddress *in_address;

          localhost = g_inet_address_new_loopback (
              self->priv->socket_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
              G_SOCKET_FAMILY_IPV4 : G_SOCKET_FAMILY_IPV6);
          in_address = g_inet_socket_address_new (localhost, 0);

          g_socket_listener_add_address (
              G_SOCKET_LISTENER (self->priv->service), in_address,
              G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT,
              NULL, &self->priv->address, &error);

          g_object_unref (localhost);
          g_object_unref (in_address);

          if (error != NULL)
            {
              operation_failed (self, error);

              g_clear_error (&error);
              return;
            }

          break;
        }

      default:
        /* should have already errored */
        g_assert_not_reached ();
        break;
    }

  tp_g_signal_connect_object (self->priv->service, "incoming",
      G_CALLBACK (service_incoming_cb), self, 0);

  g_socket_service_start (self->priv->service);

  _offer_with_address (self, params);
}