예제 #1
0
/**
 * inf_xml_connection_close:
 * @connection: A #InfXmlConnection.
 *
 * Closes the given connection.
 **/
void
inf_xml_connection_close(InfXmlConnection* connection)
{
  InfXmlConnectionInterface* iface;

  g_return_if_fail(INF_IS_XML_CONNECTION(connection));

  iface = INF_XML_CONNECTION_GET_IFACE(connection);
  g_return_if_fail(iface->close != NULL);

  iface->close(connection);
}
예제 #2
0
/**
 * inf_xml_connection_received:
 * @connection: A #InfXmlConnection.
 * @xml: (transfer none): The XML message that has been received.
 *
 * Emits the "received" signal on @connection. This will most likely only
 * be useful to implementors.
 **/
void inf_xml_connection_received(InfXmlConnection* connection,
                                 const xmlNodePtr xml)
{
  g_return_if_fail(INF_IS_XML_CONNECTION(connection));
  g_return_if_fail(xml != NULL);

  g_signal_emit(
    G_OBJECT(connection),
    connection_signals[RECEIVED],
    0,
    xml
  );
}
예제 #3
0
/**
 * inf_xml_connection_send:
 * @connection: A #InfXmlConnection.
 * @xml: (transfer full): A XML message to send. The function takes ownership
 * of the XML node.
 *
 * Sends the given XML message to the remote host.
 **/
void inf_xml_connection_send(InfXmlConnection* connection,
                             xmlNodePtr xml)
{
  InfXmlConnectionInterface* iface;

  g_return_if_fail(INF_IS_XML_CONNECTION(connection));
  g_return_if_fail(xml != NULL);

  iface = INF_XML_CONNECTION_GET_IFACE(connection);
  g_return_if_fail(iface->send != NULL);

  iface->send(connection, xml);
}
예제 #4
0
/**
 * infd_xml_server_new_connection:
 * @server: A #InfdXmlServer.
 * @connection: A #InfXmlConnection.
 *
 * Emits the "new-connection" signal on @server.
 **/
void
infd_xml_server_new_connection(InfdXmlServer* server,
                               InfXmlConnection* connection)
{
  g_return_if_fail(INFD_IS_XML_SERVER(server));
  g_return_if_fail(INF_IS_XML_CONNECTION(connection));

  g_signal_emit(
    G_OBJECT(server),
    server_signals[NEW_CONNECTION],
    0,
    connection
  );
}
예제 #5
0
/**
 * inf_xml_connection_error:
 * @connection: A #InfXmlConnection.
 * @error: The error that occurred.
 *
 * Emits the "error" signal on @connection. This will most likely only
 * be useful to implementors.
 *
 * Note that the error may or may not be fatal for the connection. If it
 * is fatal, then a status notify to %INF_XML_CONNECTION_CLOSING or
 * %INF_XML_CONNECTION_CLOSED will follow. If you are implementing a custom
 * class implementing #InfXmlConnection, make sure to always emit the "error"
 * signal before doing the status notify because many users of the connection
 * will release their reference when the connection is no longer connected.
 **/
void
inf_xml_connection_error(InfXmlConnection* connection,
                         const GError* error)
{
  g_return_if_fail(INF_IS_XML_CONNECTION(connection));
  g_return_if_fail(error != NULL);

  g_signal_emit(
    G_OBJECT(connection),
    connection_signals[ERROR],
    0,
    error
  );
}
예제 #6
0
/**
 * inf_xml_connection_open:
 * @connection: A #infXmlConnection.
 * @error: Location to store error information, if any.
 *
 * Attempts to open the given XML connection. If the process fails, @error
 * will be set. The connection needs to be in status
 * %INF_XML_CONNECTION_CLOSED for this function to be called. Even if this
 * function succeeds, the connection process can fail later. In that case
 * the status of @connection will be reset to %INF_XML_CONNECTION_CLOSED
 * and the #InfXmlConnection::error signal will be emitted.
 *
 * Returns: %TRUE on succes, or %FALSE on error.
 */
gboolean
inf_xml_connection_open(InfXmlConnection* connection,
                        GError** error)
{
  InfXmlConnectionInterface* iface;

  g_return_val_if_fail(INF_IS_XML_CONNECTION(connection), FALSE);
  g_return_val_if_fail(error == NULL || *error == NULL, FALSE);

  iface = INF_XML_CONNECTION_GET_IFACE(connection);
  g_return_val_if_fail(iface->open != NULL, FALSE);

  return iface->open(connection, error);
}
/**
 * inf_communication_object_sent:
 * @object: A #InfCommunicationObject.
 * @conn: A #InfXmlConnection.
 * @node: The sent data.
 *
 * This function is called when a XML message sent via
 * inf_communication_group_send_message() or
 * inf_communication_group_send_group_message() has actually been sent out.
 **/
void
inf_communication_object_sent(InfCommunicationObject* object,
                              InfXmlConnection* conn,
                              xmlNodePtr node)
{
  InfCommunicationObjectInterface* iface;

  g_return_if_fail(INF_COMMUNICATION_IS_OBJECT(object));
  g_return_if_fail(INF_IS_XML_CONNECTION(conn));
  g_return_if_fail(node != NULL);

  iface = INF_COMMUNICATION_OBJECT_GET_IFACE(object);

  if(iface->sent != NULL)
    (*iface->sent)(object, conn, node);
}
/**
 * infinoted_plugin_manager_get_connection_info:
 * @mgr: A #InfinotedPluginManager.
 * @plugin_info: The @plugin_info pointer of a plugin instance.
 * @connection: The #InfXmlConnection for which to retrieve plugin data.
 *
 * Queries the connection-specfic plugin data for the plugin instance
 * @plugin_info. Returns %NULL if no such object exists, i.e. when the
 * plugin's @connection_info_size is set to 0.
 *
 * Returns: A pointer to the connection-specific plugin data, or %NULL.
 */
gpointer
infinoted_plugin_manager_get_connection_info(InfinotedPluginManager* mgr,
                                             gpointer plugin_info,
                                             InfXmlConnection* connection)
{
  InfinotedPluginManagerPrivate* priv;

  g_return_val_if_fail(INFINOTED_IS_PLUGIN_MANAGER(mgr), NULL);
  g_return_val_if_fail(INF_IS_XML_CONNECTION(connection), NULL);

  priv = INFINOTED_PLUGIN_MANAGER_PRIVATE(mgr);

  return g_hash_table_lookup(
    priv->connections,
    infinoted_plugin_manager_hash(plugin_info, connection)
  );
}
예제 #9
0
/**
 * infc_session_proxy_set_connection:
 * @proxy: A #InfcSessionProxy.
 * @group: A #InfConnectionManagerGroup of subscribed connections. Ignored if
 * @connection is %NULL.
 * @connection: A #InfXmlConnection.
 *
 * Sets the subscription connection for the given session. The subscription
 * connection is the connection through which session requests are transmitted
 * during subscription.
 *
 * The subscription connection might be set even if the session is in
 * SYNCHRONIZING state in which case the session is immediately subscribed
 * after synchronization. Note that no attempt is made to tell the other end
 * about the subscription.
 *
 * When the subscription connection is being closed or replaced (by a
 * subsequent call to this function), all pending requests are dropped and
 * all users are set to be unavailable, but the session will not be closed,
 * so it may be reused by setting another subscription connection. However,
 * the session might not be synchronized again, but it is fully okay to close
 * the session by hand (using inf_session_close) and create a new session
 * that is synchronized.
 **/
void
infc_session_proxy_set_connection(InfcSessionProxy* proxy,
                                  InfConnectionManagerGroup* group,
                                  InfXmlConnection* connection)
{
  InfcSessionProxyPrivate* priv;
  xmlNodePtr xml;

  g_return_if_fail(INFC_IS_SESSION_PROXY(proxy));
  g_return_if_fail(connection == NULL || INF_IS_XML_CONNECTION(connection));
  g_return_if_fail(
    (group == NULL && connection == NULL) ||
    (group != NULL && connection != NULL)
  );

  priv = INFC_SESSION_PROXY_PRIVATE(proxy);
  g_return_if_fail(priv->session != NULL);

  g_object_freeze_notify(G_OBJECT(proxy));
  g_object_freeze_notify(G_OBJECT(priv->session));

  if(priv->connection != NULL)
  {
    /* Unsubscribe from running session. Always send the unsubscribe request
     * because synchronizations are not cancelled through this call. */
    xml = xmlNewNode(NULL, (const xmlChar*)"session-unsubscribe");

    inf_connection_manager_group_send_to_connection(
      priv->subscription_group,
      priv->connection,
      xml
    );

    /* Note that this would cause a notify on the connection property, but
     * notifications have been freezed until the end of this function call.
     * Same with the subscription-group property of priv->session. */
    infc_session_proxy_release_connection(proxy);
  }

  priv->connection = connection;

  if(connection != NULL)
  {
    priv->connection = connection;
    g_object_ref(G_OBJECT(connection));

    g_signal_connect(
      G_OBJECT(connection),
      "notify::status",
      G_CALLBACK(infc_session_proxy_connection_notify_status_cb),
      proxy
    );

    /* Set new group */
    priv->subscription_group = group;
    inf_connection_manager_group_ref(priv->subscription_group);
  }

  inf_session_set_subscription_group(priv->session, priv->subscription_group);

  g_object_notify(G_OBJECT(proxy), "connection");
  g_object_notify(G_OBJECT(proxy), "subscription-group");
  g_object_thaw_notify(G_OBJECT(priv->session));
  g_object_thaw_notify(G_OBJECT(proxy));
}
/**
 * inf_communication_manager_join_group:
 * @manager: A #InfCommunicationManager.
 * @group_name: The group to join.
 * @publisher_conn: A #InfXmlConnection to the publishing host.
 * @method: The communication method to use.
 *
 * Joins a communication group published by a remote host. @publisher_conn
 * needs to be a to the publishing host with status %INF_XML_CONNECTION_OPEN
 * or %INF_XML_CONNECTION_OPENING. @group_name specifies the name of the group
 * to join.
 *
 * @method specifies the communication method to use. It must match the
 * communication method the publisher has chosen for @publisher_conn's network
 * (see inf_communication_group_get_method_for_network()). The function
 * returns %NULL if @method is not supported (which means
 * inf_communication_manager_get_factory_for() for @publisher_conn's network
 * and @method returns %NULL).
 *
 * Returns: A new #InfCommunicationJoinedGroup, or %NULL. Free with
 * g_object_unref() to leave the group.
 */
InfCommunicationJoinedGroup*
inf_communication_manager_join_group(InfCommunicationManager* manager,
                                     const gchar* group_name,
                                     InfXmlConnection* publisher_conn,
                                     const gchar* method)
{
  InfCommunicationManagerPrivate* priv;
  InfCommunicationManagerJoinedKey* key;
  gchar* network;
  gchar* publisher_id;
  InfXmlConnectionStatus status;
  InfCommunicationJoinedGroup* group;

  g_return_val_if_fail(INF_COMMUNICATION_IS_MANAGER(manager), NULL);
  g_return_val_if_fail(group_name != NULL, NULL);
  g_return_val_if_fail(INF_IS_XML_CONNECTION(publisher_conn), NULL);
  g_return_val_if_fail(method != NULL, NULL);

  priv = INF_COMMUNICATION_MANAGER_PRIVATE(manager);

  g_object_get(
    G_OBJECT(publisher_conn),
    "network", &network,
    "remote-id", &publisher_id,
    "status", &status,
    NULL
  );

  /* TODO: Do we need to support OPENING somewhere? I don't think it's a good
   * idea to do here. When we change this remember to change docs above. */
  if(status == INF_XML_CONNECTION_CLOSING ||
     status == INF_XML_CONNECTION_CLOSED)
  {
    g_free(network);
    g_free(publisher_id);
    g_return_val_if_reached(NULL);
  }

  key = g_slice_new(InfCommunicationManagerJoinedKey);
  key->network = network;
  key->publisher_id = publisher_id;
  key->group_name = group_name;

  group = g_hash_table_lookup(priv->joined_groups, key);
  if(group != NULL)
  {
    inf_communication_manager_joined_key_free(key);
    g_return_val_if_reached(NULL);
  }

  if(!inf_communication_manager_get_factory_for(manager, network, method))
  {
    inf_communication_manager_joined_key_free(key);
    return NULL; /* ordinary failure for now */
  }

  group = g_object_new(
    INF_COMMUNICATION_TYPE_JOINED_GROUP,
    "communication-manager", manager,
    "communication-registry", priv->registry,
    "name", group_name,
    "publisher", publisher_conn,
    "method", method,
    NULL
  );

  key->group_name =
    inf_communication_group_get_name(INF_COMMUNICATION_GROUP(group));

  g_hash_table_insert(priv->joined_groups, key, group);

  g_object_weak_ref(
    G_OBJECT(group),
    inf_communication_manager_joined_group_unrefed,
    manager
  );

  return group;
}