void
gabble_jingle_content_produce_node (GabbleJingleContent *c,
    WockyNode *parent,
    gboolean include_description,
    gboolean include_transport,
    WockyNode **trans_node_out)
{
  GabbleJingleContentPrivate *priv = c->priv;
  WockyNode *content_node, *trans_node;
  JingleDialect dialect = gabble_jingle_session_get_dialect (c->session);
  void (*produce_desc)(GabbleJingleContent *, WockyNode *) =
    GABBLE_JINGLE_CONTENT_GET_CLASS (c)->produce_description;

  if ((dialect == JINGLE_DIALECT_GTALK3) ||
      (dialect == JINGLE_DIALECT_GTALK4))
    {
      content_node = parent;
    }
  else
    {
      content_node = wocky_node_add_child_with_content (parent, "content", NULL);
      wocky_node_set_attributes (content_node,
          "name", priv->name,
          "senders", produce_senders (priv->senders),
          NULL);

      if (gabble_jingle_content_creator_is_initiator (c))
        wocky_node_set_attribute (content_node, "creator", "initiator");
      else
        wocky_node_set_attribute (content_node, "creator", "responder");
    }

  if (include_description)
    produce_desc (c, content_node);

  if (include_transport)
    {
      if (dialect == JINGLE_DIALECT_GTALK3)
        {
          /* GTalk 03 doesn't use a transport, but assumes gtalk-p2p */
          trans_node = parent;
        }
      else
        {
          trans_node = wocky_node_add_child_with_content (content_node, "transport", NULL);
          trans_node->ns = g_quark_from_string (priv->transport_ns);
        }

      if (trans_node_out != NULL)
        *trans_node_out = trans_node;
    }
}
static void
transmit_candidates (GabbleJingleTransportGoogle *transport,
    const gchar *name,
    GList *candidates)
{
  GabbleJingleTransportGooglePrivate *priv = transport->priv;
  GList *li;
  WockyStanza *msg;
  WockyNode *trans_node, *sess_node;

  if (candidates == NULL)
    return;

  msg = gabble_jingle_session_new_message (priv->content->session,
    JINGLE_ACTION_TRANSPORT_INFO, &sess_node);

  gabble_jingle_content_produce_node (priv->content, sess_node, FALSE, TRUE,
      &trans_node);

  for (li = candidates; li; li = li->next)
    {
      JingleCandidate *c = (JingleCandidate *) li->data;
      gchar port_str[16], pref_str[16], comp_str[16], *type_str, *proto_str;
      WockyNode *cnode;

      sprintf (port_str, "%d", c->port);
      sprintf (pref_str, "%lf", c->preference / 65536.0);
      sprintf (comp_str, "%d", c->component);

      switch (c->type) {
        case JINGLE_CANDIDATE_TYPE_LOCAL:
          type_str = "local";
          break;
        case JINGLE_CANDIDATE_TYPE_STUN:
          type_str = "stun";
          break;
        case JINGLE_CANDIDATE_TYPE_RELAY:
          type_str = "relay";
          break;
        default:
          g_assert_not_reached ();
      }

      switch (c->protocol) {
        case JINGLE_TRANSPORT_PROTOCOL_UDP:
          proto_str = "udp";
          break;
        case JINGLE_TRANSPORT_PROTOCOL_TCP:
          if ((c->port == 443) && (c->type == JINGLE_CANDIDATE_TYPE_RELAY))
            proto_str = "ssltcp";
          else
            proto_str = "tcp";
          break;
        default:
          g_assert_not_reached ();
      }

      cnode = wocky_node_add_child_with_content (trans_node, "candidate", NULL);
      wocky_node_set_attributes (cnode,
          "address", c->address,
          "port", port_str,
          "username", c->username,
          "password", c->password != NULL ? c->password : "",
          "preference", pref_str,
          "protocol", proto_str,
          "type", type_str,
          "component", comp_str,
          "network", "0",
          "generation", "0",
          NULL);

      wocky_node_set_attribute (cnode, "name", name);
    }

  wocky_porter_send_iq_async (
      gabble_jingle_session_get_porter (priv->content->session), msg,
      NULL, NULL, NULL);
  g_object_unref (msg);
}
示例#3
0
void
gabble_tube_iface_publish_in_node (GabbleTubeIface *tube,
                                   TpBaseConnection *conn,
                                   WockyNode *node)
{
  WockyNode *parameters_node;
  GHashTable *parameters;
  TpTubeType type;
  gchar *service, *id_str;
  guint tube_id;
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
    conn, TP_HANDLE_TYPE_CONTACT);
  TpHandle initiator_handle;

  g_object_get (G_OBJECT (tube),
      "type", &type,
      "initiator-handle", &initiator_handle,
      "service", &service,
      "parameters", &parameters,
      "id", &tube_id,
      NULL);

  id_str = g_strdup_printf ("%u", tube_id);

  wocky_node_set_attributes (node,
      "service", service,
      "id", id_str,
      NULL);

  g_free (id_str);

  switch (type)
    {
      case TP_TUBE_TYPE_DBUS:
        {
          gchar *name, *stream_id;

          g_object_get (G_OBJECT (tube),
              "stream-id", &stream_id,
              "dbus-name", &name,
              NULL);

          wocky_node_set_attributes (node,
              "type", "dbus",
              "stream-id", stream_id,
              "initiator", tp_handle_inspect (contact_repo, initiator_handle),
              NULL);

          if (name != NULL)
            wocky_node_set_attribute (node, "dbus-name", name);

          g_free (name);
          g_free (stream_id);
        }
        break;
      case TP_TUBE_TYPE_STREAM:
        {
          wocky_node_set_attribute (node, "type", "stream");
        }
        break;
      default:
        {
          g_return_if_reached ();
        }
    }

  parameters_node = wocky_node_add_child_with_content (node, "parameters",
      NULL);
  lm_message_node_add_children_from_properties (parameters_node, parameters,
      "parameter");

  g_free (service);
  g_hash_table_unref (parameters);
}
static void
inject_candidates (WockyJingleTransportIface *obj,
    WockyNode *transport_node)
{
  WockyJingleTransportIceUdp *self = WOCKY_JINGLE_TRANSPORT_ICEUDP (obj);
  WockyJingleTransportIceUdpPrivate *priv = self->priv;
  const gchar *username = NULL;

  for (; priv->pending_candidates != NULL;
      priv->pending_candidates = priv->pending_candidates->next)
    {
      WockyJingleCandidate *c = (WockyJingleCandidate *) priv->pending_candidates->data;
      gchar port_str[16], pref_str[16], comp_str[16], id_str[16],
          *type_str, *proto_str;
      WockyNode *cnode;

      if (username == NULL)
        {
          username = c->username;
        }
      else if (wocky_strdiff (username, c->username))
        {
          DEBUG ("found a candidate with a different username (%s not %s); "
              "will send in a separate batch", c->username, username);
          break;
        }

      sprintf (pref_str, "%d", c->preference);
      sprintf (port_str, "%d", c->port);
      sprintf (comp_str, "%d", c->component);
      sprintf (id_str, "%d", priv->id_sequence++);

      switch (c->type) {
        case WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL:
          type_str = "host";
          break;
        case WOCKY_JINGLE_CANDIDATE_TYPE_STUN:
          type_str = "srflx";
          break;
        case WOCKY_JINGLE_CANDIDATE_TYPE_RELAY:
          type_str = "relay";
          break;
        default:
          DEBUG ("skipping candidate with unknown type %u", c->type);
          continue;
      }

      switch (c->protocol) {
        case WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP:
          proto_str = "udp";
          break;
        case WOCKY_JINGLE_TRANSPORT_PROTOCOL_TCP:
          DEBUG ("ignoring TCP candidate");
          continue;
        default:
          DEBUG ("skipping candidate with unknown protocol %u", c->protocol);
          continue;
      }

      wocky_node_set_attributes (transport_node,
          "ufrag", c->username,
          "pwd", c->password,
          NULL);

      cnode = wocky_node_add_child (transport_node, "candidate");
      wocky_node_set_attributes (cnode,
          "ip", c->address,
          "port", port_str,
          "priority", pref_str,
          "protocol", proto_str,
          "type", type_str,
          "component", comp_str,
          "foundation", c->id,
          "id", id_str,
          "network", "0",
          "generation", "0",
          NULL);
    }
}