Fri, 22 Mar 2019 02:42:46 +0000
Merged in default (pull request #479)
Update most things to use G_DEFINE_DYNAMIC_TYPE and a host of other updates
Approved-by: Elliott Sales de Andrade
--- a/libpurple/protocols/jabber/google/google_p2p.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/google/google_p2p.c Fri Mar 22 02:42:46 2019 +0000 @@ -31,23 +31,11 @@ #include <string.h> -struct _JingleGoogleP2PPrivate +typedef struct { GList *local_candidates; GList *remote_candidates; -}; - -#define JINGLE_GOOGLE_P2P_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_GOOGLE_P2P, JingleGoogleP2PPrivate)) - -static void jingle_google_p2p_class_init (JingleGoogleP2PClass *klass); -static void jingle_google_p2p_init (JingleGoogleP2P *google_p2p); -static void jingle_google_p2p_finalize (GObject *object); -static void jingle_google_p2p_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void jingle_google_p2p_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static JingleTransport *jingle_google_p2p_parse_internal(PurpleXmlNode *google_p2p); -static PurpleXmlNode *jingle_google_p2p_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action); -static void jingle_google_p2p_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); -static GList *jingle_google_p2p_get_remote_candidates(JingleTransport *transport); +} JingleGoogleP2PPrivate; enum { PROP_0, @@ -56,163 +44,25 @@ PROP_LAST }; -static JingleTransportClass *parent_class = NULL; static GParamSpec *properties[PROP_LAST]; -static JingleGoogleP2PCandidate * -jingle_google_p2p_candidate_copy(JingleGoogleP2PCandidate *candidate) -{ - JingleGoogleP2PCandidate *new_candidate = g_new0(JingleGoogleP2PCandidate, 1); - new_candidate->id = g_strdup(candidate->id); - new_candidate->address = g_strdup(candidate->address); - new_candidate->port = candidate->port; - new_candidate->preference = candidate->preference; - new_candidate->type = g_strdup(candidate->type); - new_candidate->protocol = g_strdup(candidate->protocol); - new_candidate->username = g_strdup(candidate->username); - new_candidate->password = g_strdup(candidate->password); - new_candidate->generation = candidate->generation; - - new_candidate->rem_known = candidate->rem_known; - - return new_candidate; -} - -static void -jingle_google_p2p_candidate_free(JingleGoogleP2PCandidate *candidate) -{ - g_free(candidate->id); - g_free(candidate->address); - g_free(candidate->type); - g_free(candidate->protocol); - g_free(candidate->username); - g_free(candidate->password); -} - -G_DEFINE_BOXED_TYPE(JingleGoogleP2PCandidate, jingle_google_p2p_candidate, - jingle_google_p2p_candidate_copy, jingle_google_p2p_candidate_free) - -JingleGoogleP2PCandidate * -jingle_google_p2p_candidate_new(const gchar *id, guint generation, - const gchar *address, guint port, guint preference, - const gchar *type, const gchar *protocol, - const gchar *username, const gchar *password) -{ - JingleGoogleP2PCandidate *candidate = g_new0(JingleGoogleP2PCandidate, 1); - candidate->id = g_strdup(id); - candidate->address = g_strdup(address); - candidate->port = port; - candidate->preference = preference; - candidate->type = g_strdup(type); - candidate->protocol = g_strdup(protocol); - candidate->username = g_strdup(username); - candidate->password = g_strdup(password); - candidate->generation = generation; - - candidate->rem_known = FALSE; - return candidate; -} - -PURPLE_DEFINE_TYPE(JingleGoogleP2P, jingle_google_p2p, JINGLE_TYPE_TRANSPORT); - -static void -jingle_google_p2p_class_init(JingleGoogleP2PClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass *)klass; - parent_class = g_type_class_peek_parent(klass); - - gobject_class->finalize = jingle_google_p2p_finalize; - gobject_class->set_property = jingle_google_p2p_set_property; - gobject_class->get_property = jingle_google_p2p_get_property; - klass->parent_class.to_xml = jingle_google_p2p_to_xml_internal; - klass->parent_class.parse = jingle_google_p2p_parse_internal; - klass->parent_class.transport_type = NS_GOOGLE_TRANSPORT_P2P; - klass->parent_class.add_local_candidate = jingle_google_p2p_add_local_candidate; - klass->parent_class.get_remote_candidates = jingle_google_p2p_get_remote_candidates; - - g_type_class_add_private(klass, sizeof(JingleGoogleP2PPrivate)); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + JingleGoogleP2P, + jingle_google_p2p, + JINGLE_TYPE_TRANSPORT, + 0, + G_ADD_PRIVATE_DYNAMIC(JingleGoogleP2P) +); - properties[PROP_LOCAL_CANDIDATES] = g_param_spec_pointer("local-candidates", - "Local candidates", - "The local candidates for this transport.", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_REMOTE_CANDIDATES] = g_param_spec_pointer("remote-candidates", - "Remote candidates", - "The remote candidates for this transport.", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, PROP_LAST, properties); -} - -static void -jingle_google_p2p_init(JingleGoogleP2P *google_p2p) -{ - google_p2p->priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(google_p2p); - google_p2p->priv->local_candidates = NULL; - google_p2p->priv->remote_candidates = NULL; -} - -static void -jingle_google_p2p_finalize(GObject *google_p2p) -{ -/* JingleGoogleP2PPrivate *priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(google_p2p); */ - purple_debug_info("jingle","jingle_google_p2p_finalize\n"); - - G_OBJECT_CLASS(parent_class)->finalize(google_p2p); -} - -static void -jingle_google_p2p_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - JingleGoogleP2P *google_p2p; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_GOOGLE_P2P(object)); - - google_p2p = JINGLE_GOOGLE_P2P(object); - - switch (prop_id) { - case PROP_LOCAL_CANDIDATES: - google_p2p->priv->local_candidates = g_value_get_pointer(value); - break; - case PROP_REMOTE_CANDIDATES: - google_p2p->priv->remote_candidates = g_value_get_pointer(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -jingle_google_p2p_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - JingleGoogleP2P *google_p2p; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_GOOGLE_P2P(object)); - - google_p2p = JINGLE_GOOGLE_P2P(object); - - switch (prop_id) { - case PROP_LOCAL_CANDIDATES: - g_value_set_pointer(value, google_p2p->priv->local_candidates); - break; - case PROP_REMOTE_CANDIDATES: - g_value_set_pointer(value, google_p2p->priv->remote_candidates); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - +/****************************************************************************** + * JingleGoogleP2P Transport Implementation + *****************************************************************************/ static void jingle_google_p2p_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) { JingleGoogleP2P *google_p2p = JINGLE_GOOGLE_P2P(transport); + JingleGoogleP2PPrivate *priv = jingle_google_p2p_get_instance_private(google_p2p); JingleGoogleP2PCandidate *google_p2p_candidate; gchar *ip; gchar *username; @@ -242,19 +92,19 @@ g_free(username); g_free(ip); - for (iter = google_p2p->priv->local_candidates; iter; iter = g_list_next(iter)) { + for (iter = priv->local_candidates; iter; iter = g_list_next(iter)) { JingleGoogleP2PCandidate *c = iter->data; if (!strcmp(c->id, id)) { generation = c->generation + 1; g_boxed_free(JINGLE_TYPE_GOOGLE_P2P_CANDIDATE, c); - google_p2p->priv->local_candidates = g_list_delete_link( - google_p2p->priv->local_candidates, iter); + priv->local_candidates = g_list_delete_link( + priv->local_candidates, iter); google_p2p_candidate->generation = generation; - google_p2p->priv->local_candidates = g_list_append( - google_p2p->priv->local_candidates, candidate); + priv->local_candidates = g_list_append( + priv->local_candidates, candidate); g_object_notify_by_pspec(G_OBJECT(google_p2p), properties[PROP_LOCAL_CANDIDATES]); @@ -262,17 +112,50 @@ } } - google_p2p->priv->local_candidates = g_list_append( - google_p2p->priv->local_candidates, google_p2p_candidate); + priv->local_candidates = g_list_append( + priv->local_candidates, google_p2p_candidate); g_object_notify_by_pspec(G_OBJECT(google_p2p), properties[PROP_LOCAL_CANDIDATES]); } +static JingleGoogleP2PCandidate * +jingle_google_p2p_get_remote_candidate_by_id(JingleGoogleP2P *google_p2p, + const gchar *id) +{ + JingleGoogleP2PPrivate *priv = jingle_google_p2p_get_instance_private(google_p2p); + GList *iter = priv->remote_candidates; + for (; iter; iter = g_list_next(iter)) { + JingleGoogleP2PCandidate *candidate = iter->data; + if (!strcmp(candidate->id, id)) { + return candidate; + } + } + return NULL; +} + +static void +jingle_google_p2p_add_remote_candidate(JingleGoogleP2P *google_p2p, JingleGoogleP2PCandidate *candidate) +{ + JingleGoogleP2PPrivate *priv = jingle_google_p2p_get_instance_private(google_p2p); + JingleGoogleP2PCandidate *google_p2p_candidate = + jingle_google_p2p_get_remote_candidate_by_id(google_p2p, + candidate->id); + if (google_p2p_candidate != NULL) { + priv->remote_candidates = g_list_remove(priv->remote_candidates, + google_p2p_candidate); + g_boxed_free(JINGLE_TYPE_GOOGLE_P2P_CANDIDATE, google_p2p_candidate); + } + priv->remote_candidates = g_list_append(priv->remote_candidates, candidate); + + g_object_notify_by_pspec(G_OBJECT(google_p2p), properties[PROP_REMOTE_CANDIDATES]); +} + static GList * jingle_google_p2p_get_remote_candidates(JingleTransport *transport) { JingleGoogleP2P *google_p2p = JINGLE_GOOGLE_P2P(transport); - GList *candidates = google_p2p->priv->remote_candidates; + JingleGoogleP2PPrivate *priv = jingle_google_p2p_get_instance_private(google_p2p); + GList *candidates = priv->remote_candidates; GList *ret = NULL; for (; candidates; candidates = g_list_next(candidates)) { @@ -301,85 +184,17 @@ return ret; } -static JingleGoogleP2PCandidate * -jingle_google_p2p_get_remote_candidate_by_id(JingleGoogleP2P *google_p2p, - const gchar *id) -{ - GList *iter = google_p2p->priv->remote_candidates; - for (; iter; iter = g_list_next(iter)) { - JingleGoogleP2PCandidate *candidate = iter->data; - if (!strcmp(candidate->id, id)) { - return candidate; - } - } - return NULL; -} - -static void -jingle_google_p2p_add_remote_candidate(JingleGoogleP2P *google_p2p, JingleGoogleP2PCandidate *candidate) -{ - JingleGoogleP2PPrivate *priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(google_p2p); - JingleGoogleP2PCandidate *google_p2p_candidate = - jingle_google_p2p_get_remote_candidate_by_id(google_p2p, - candidate->id); - if (google_p2p_candidate != NULL) { - priv->remote_candidates = g_list_remove(priv->remote_candidates, - google_p2p_candidate); - g_boxed_free(JINGLE_TYPE_GOOGLE_P2P_CANDIDATE, google_p2p_candidate); - } - priv->remote_candidates = g_list_append(priv->remote_candidates, candidate); - - g_object_notify_by_pspec(G_OBJECT(google_p2p), properties[PROP_REMOTE_CANDIDATES]); -} - -static JingleTransport * -jingle_google_p2p_parse_internal(PurpleXmlNode *google_p2p) -{ - JingleTransport *transport = parent_class->parse(google_p2p); - PurpleXmlNode *candidate = purple_xmlnode_get_child(google_p2p, "candidate"); - JingleGoogleP2PCandidate *google_p2p_candidate = NULL; - - for (; candidate; candidate = purple_xmlnode_get_next_twin(candidate)) { - const gchar *generation = purple_xmlnode_get_attrib(candidate, "generation"); - const gchar *id = purple_xmlnode_get_attrib(candidate, "name"); - const gchar *address = purple_xmlnode_get_attrib(candidate, "address"); - const gchar *port = purple_xmlnode_get_attrib(candidate, "port"); - const gchar *preference = purple_xmlnode_get_attrib(candidate, "preference"); - const gchar *type = purple_xmlnode_get_attrib(candidate, "type"); - const gchar *protocol = purple_xmlnode_get_attrib(candidate, "protocol"); - const gchar *username = purple_xmlnode_get_attrib(candidate, "username"); - const gchar *password = purple_xmlnode_get_attrib(candidate, "password"); - - if (!generation || !id || !address || !port || !preference || - !type || !protocol || !username || !password) - continue; - - google_p2p_candidate = jingle_google_p2p_candidate_new(id, - atoi(generation), - address, - atoi(port), - atoi(preference), - type, - protocol, - username, password); - google_p2p_candidate->rem_known = TRUE; - jingle_google_p2p_add_remote_candidate(JINGLE_GOOGLE_P2P(transport), google_p2p_candidate); - } - - return transport; -} - static PurpleXmlNode * jingle_google_p2p_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action) { - PurpleXmlNode *node = parent_class->to_xml(transport, content, action); + PurpleXmlNode *node = JINGLE_TRANSPORT_CLASS(jingle_google_p2p_parent_class)->to_xml(transport, content, action); if (action == JINGLE_SESSION_INITIATE || action == JINGLE_SESSION_ACCEPT || action == JINGLE_TRANSPORT_INFO || action == JINGLE_CONTENT_ADD || action == JINGLE_TRANSPORT_REPLACE) { - JingleGoogleP2PPrivate *priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(transport); + JingleGoogleP2PPrivate *priv = jingle_google_p2p_get_instance_private(JINGLE_GOOGLE_P2P(transport)); GList *iter = priv->local_candidates; for (; iter; iter = g_list_next(iter)) { @@ -419,3 +234,193 @@ return node; } +static JingleTransport * +jingle_google_p2p_parse_internal(PurpleXmlNode *google_p2p) +{ + JingleTransport *transport = JINGLE_TRANSPORT_CLASS(jingle_google_p2p_parent_class)->parse(google_p2p); + PurpleXmlNode *candidate = purple_xmlnode_get_child(google_p2p, "candidate"); + JingleGoogleP2PCandidate *google_p2p_candidate = NULL; + + for (; candidate; candidate = purple_xmlnode_get_next_twin(candidate)) { + const gchar *generation = purple_xmlnode_get_attrib(candidate, "generation"); + const gchar *id = purple_xmlnode_get_attrib(candidate, "name"); + const gchar *address = purple_xmlnode_get_attrib(candidate, "address"); + const gchar *port = purple_xmlnode_get_attrib(candidate, "port"); + const gchar *preference = purple_xmlnode_get_attrib(candidate, "preference"); + const gchar *type = purple_xmlnode_get_attrib(candidate, "type"); + const gchar *protocol = purple_xmlnode_get_attrib(candidate, "protocol"); + const gchar *username = purple_xmlnode_get_attrib(candidate, "username"); + const gchar *password = purple_xmlnode_get_attrib(candidate, "password"); + + if (!generation || !id || !address || !port || !preference || + !type || !protocol || !username || !password) + continue; + + google_p2p_candidate = jingle_google_p2p_candidate_new(id, + atoi(generation), + address, + atoi(port), + atoi(preference), + type, + protocol, + username, password); + google_p2p_candidate->rem_known = TRUE; + jingle_google_p2p_add_remote_candidate(JINGLE_GOOGLE_P2P(transport), google_p2p_candidate); + } + + return transport; +} + +/****************************************************************************** + * JingleGoogleP2P GObject stuff + *****************************************************************************/ +static void +jingle_google_p2p_init(JingleGoogleP2P *google_p2p) +{ +} + +static void +jingle_google_p2p_finalize(GObject *google_p2p) +{ +/* JingleGoogleP2PPrivate *priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(google_p2p); */ + purple_debug_info("jingle","jingle_google_p2p_finalize\n"); + + G_OBJECT_CLASS(jingle_google_p2p_parent_class)->finalize(google_p2p); +} + +static void +jingle_google_p2p_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + JingleGoogleP2P *google_p2p = JINGLE_GOOGLE_P2P(object); + JingleGoogleP2PPrivate *priv = jingle_google_p2p_get_instance_private(google_p2p); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + priv->local_candidates = g_value_get_pointer(value); + break; + case PROP_REMOTE_CANDIDATES: + priv->remote_candidates = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +jingle_google_p2p_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + JingleGoogleP2P *google_p2p = JINGLE_GOOGLE_P2P(object); + JingleGoogleP2PPrivate *priv = jingle_google_p2p_get_instance_private(google_p2p); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + g_value_set_pointer(value, priv->local_candidates); + break; + case PROP_REMOTE_CANDIDATES: + g_value_set_pointer(value, priv->remote_candidates); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_google_p2p_class_finalize(JingleGoogleP2PClass *klass) { +} + +static void +jingle_google_p2p_class_init(JingleGoogleP2PClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + JingleTransportClass *transport_class = JINGLE_TRANSPORT_CLASS(klass); + + obj_class->finalize = jingle_google_p2p_finalize; + obj_class->set_property = jingle_google_p2p_set_property; + obj_class->get_property = jingle_google_p2p_get_property; + + transport_class->to_xml = jingle_google_p2p_to_xml_internal; + transport_class->parse = jingle_google_p2p_parse_internal; + transport_class->transport_type = NS_GOOGLE_TRANSPORT_P2P; + transport_class->add_local_candidate = jingle_google_p2p_add_local_candidate; + transport_class->get_remote_candidates = jingle_google_p2p_get_remote_candidates; + + properties[PROP_LOCAL_CANDIDATES] = g_param_spec_pointer("local-candidates", + "Local candidates", + "The local candidates for this transport.", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_REMOTE_CANDIDATES] = g_param_spec_pointer("remote-candidates", + "Remote candidates", + "The remote candidates for this transport.", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, PROP_LAST, properties); +} + +/****************************************************************************** + * JingleGoogleP2PCandidate Boxed Implementation + *****************************************************************************/ +static JingleGoogleP2PCandidate * +jingle_google_p2p_candidate_copy(JingleGoogleP2PCandidate *candidate) +{ + JingleGoogleP2PCandidate *new_candidate = g_new0(JingleGoogleP2PCandidate, 1); + new_candidate->id = g_strdup(candidate->id); + new_candidate->address = g_strdup(candidate->address); + new_candidate->port = candidate->port; + new_candidate->preference = candidate->preference; + new_candidate->type = g_strdup(candidate->type); + new_candidate->protocol = g_strdup(candidate->protocol); + new_candidate->username = g_strdup(candidate->username); + new_candidate->password = g_strdup(candidate->password); + new_candidate->generation = candidate->generation; + + new_candidate->rem_known = candidate->rem_known; + + return new_candidate; +} + +static void +jingle_google_p2p_candidate_free(JingleGoogleP2PCandidate *candidate) +{ + g_free(candidate->id); + g_free(candidate->address); + g_free(candidate->type); + g_free(candidate->protocol); + g_free(candidate->username); + g_free(candidate->password); +} + +G_DEFINE_BOXED_TYPE(JingleGoogleP2PCandidate, jingle_google_p2p_candidate, + jingle_google_p2p_candidate_copy, jingle_google_p2p_candidate_free) + + +/****************************************************************************** + * Public API + *****************************************************************************/ +void +jingle_google_p2p_register(PurplePlugin *plugin) { + jingle_google_p2p_register_type(G_TYPE_MODULE(plugin)); +} + +JingleGoogleP2PCandidate * +jingle_google_p2p_candidate_new(const gchar *id, guint generation, + const gchar *address, guint port, guint preference, + const gchar *type, const gchar *protocol, + const gchar *username, const gchar *password) +{ + JingleGoogleP2PCandidate *candidate = g_new0(JingleGoogleP2PCandidate, 1); + candidate->id = g_strdup(id); + candidate->address = g_strdup(address); + candidate->port = port; + candidate->preference = preference; + candidate->type = g_strdup(type); + candidate->protocol = g_strdup(protocol); + candidate->username = g_strdup(username); + candidate->password = g_strdup(password); + candidate->generation = generation; + + candidate->rem_known = FALSE; + return candidate; +}
--- a/libpurple/protocols/jabber/google/google_p2p.h Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/google/google_p2p.h Fri Mar 22 02:42:46 2019 +0000 @@ -33,7 +33,6 @@ G_BEGIN_DECLS #define JINGLE_TYPE_GOOGLE_P2P (jingle_google_p2p_get_type()) -#define JINGLE_TYPE_GOOGLE_P2P_CANDIDATE (jingle_google_p2p_candidate_get_type()) #define JINGLE_GOOGLE_P2P(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), JINGLE_TYPE_GOOGLE_P2P, JingleGoogleP2P)) #define JINGLE_GOOGLE_P2P_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), JINGLE_TYPE_GOOGLE_P2P, JingleGoogleP2PClass)) #define JINGLE_IS_GOOGLE_P2P(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), JINGLE_TYPE_GOOGLE_P2P)) @@ -44,8 +43,9 @@ typedef struct _JingleGoogleP2P JingleGoogleP2P; /** @copydoc _JingleGoogleP2PClass */ typedef struct _JingleGoogleP2PClass JingleGoogleP2PClass; -/** @copydoc _JingleGoogleP2PPrivate */ -typedef struct _JingleGoogleP2PPrivate JingleGoogleP2PPrivate; + +#define JINGLE_TYPE_GOOGLE_P2P_CANDIDATE (jingle_google_p2p_candidate_get_type()) + /** @copydoc _JingleGoogleP2PCandidate */ typedef struct _JingleGoogleP2PCandidate JingleGoogleP2PCandidate; @@ -62,7 +62,6 @@ struct _JingleGoogleP2P { JingleTransport parent; /**< The parent of this object. */ - JingleGoogleP2PPrivate *priv; /**< The private data of this object. */ }; struct _JingleGoogleP2PCandidate @@ -94,7 +93,7 @@ /** * Registers the JingleGoogleP2P type in the type system. */ -void jingle_google_p2p_register_type(PurplePlugin *plugin); +void jingle_google_p2p_register(PurplePlugin *plugin); JingleGoogleP2PCandidate *jingle_google_p2p_candidate_new(const gchar *id, guint generation, const gchar *address, guint port, guint preference,
--- a/libpurple/protocols/jabber/jabber.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jabber.c Fri Mar 22 02:42:46 2019 +0000 @@ -4259,16 +4259,16 @@ static gboolean plugin_load(PurplePlugin *plugin, GError **error) { - jingle_session_register_type(plugin); - - jingle_transport_register_type(plugin); - jingle_iceudp_register_type(plugin); - jingle_rawudp_register_type(plugin); - jingle_google_p2p_register_type(plugin); - - jingle_content_register_type(plugin); + jingle_session_register(plugin); + + jingle_transport_register(plugin); + jingle_iceudp_register(plugin); + jingle_rawudp_register(plugin); + jingle_google_p2p_register(plugin); + + jingle_content_register(plugin); #ifdef USE_VV - jingle_rtp_register_type(plugin); + jingle_rtp_register(plugin); #endif jabber_protocol_register_type(plugin);
--- a/libpurple/protocols/jabber/jingle/content.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/content.c Fri Mar 22 02:42:46 2019 +0000 @@ -31,7 +31,7 @@ #include <string.h> -struct _JingleContentPrivate +typedef struct { JingleSession *session; gchar *description_type; @@ -41,17 +41,7 @@ gchar *senders; JingleTransport *transport; JingleTransport *pending_transport; -}; - -#define JINGLE_CONTENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_CONTENT, JingleContentPrivate)) - -static void jingle_content_class_init (JingleContentClass *klass); -static void jingle_content_init (JingleContent *content); -static void jingle_content_finalize (GObject *object); -static void jingle_content_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void jingle_content_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static PurpleXmlNode *jingle_content_to_xml_internal(JingleContent *content, PurpleXmlNode *jingle, JingleActionType action); -static JingleContent *jingle_content_parse_internal(PurpleXmlNode *content); +} JingleContentPrivate; enum { PROP_0, @@ -65,25 +55,205 @@ PROP_LAST }; -static GObjectClass *parent_class = NULL; static GParamSpec *properties[PROP_LAST]; -PURPLE_DEFINE_TYPE(JingleContent, jingle_content, G_TYPE_OBJECT); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + JingleContent, + jingle_content, + G_TYPE_OBJECT, + 0, + G_ADD_PRIVATE_DYNAMIC(JingleContent) +); + +/****************************************************************************** + * JingleContent Implementation + *****************************************************************************/ +static JingleContent * +jingle_content_parse_internal(PurpleXmlNode *content) +{ + PurpleXmlNode *description = purple_xmlnode_get_child(content, "description"); + const gchar *type = purple_xmlnode_get_namespace(description); + const gchar *creator = purple_xmlnode_get_attrib(content, "creator"); + const gchar *disposition = purple_xmlnode_get_attrib(content, "disposition"); + const gchar *senders = purple_xmlnode_get_attrib(content, "senders"); + const gchar *name = purple_xmlnode_get_attrib(content, "name"); + JingleTransport *transport = + jingle_transport_parse(purple_xmlnode_get_child(content, "transport")); + if (transport == NULL) + return NULL; + + if (senders == NULL) + senders = "both"; + + return jingle_content_create(type, creator, disposition, name, senders, transport); +} + +static PurpleXmlNode * +jingle_content_to_xml_internal(JingleContent *content, PurpleXmlNode *jingle, JingleActionType action) +{ + PurpleXmlNode *node = purple_xmlnode_new_child(jingle, "content"); + gchar *creator = jingle_content_get_creator(content); + gchar *name = jingle_content_get_name(content); + gchar *senders = jingle_content_get_senders(content); + gchar *disposition = jingle_content_get_disposition(content); + + purple_xmlnode_set_attrib(node, "creator", creator); + purple_xmlnode_set_attrib(node, "name", name); + purple_xmlnode_set_attrib(node, "senders", senders); + if (!purple_strequal("session", disposition)) + purple_xmlnode_set_attrib(node, "disposition", disposition); + + g_free(disposition); + g_free(senders); + g_free(name); + g_free(creator); + + if (action != JINGLE_CONTENT_REMOVE) { + JingleTransport *transport; + + if (action != JINGLE_TRANSPORT_ACCEPT && + action != JINGLE_TRANSPORT_INFO && + action != JINGLE_TRANSPORT_REJECT && + action != JINGLE_TRANSPORT_REPLACE) { + PurpleXmlNode *description = purple_xmlnode_new_child(node, "description"); + + purple_xmlnode_set_namespace(description, + jingle_content_get_description_type(content)); + } + + if (action != JINGLE_TRANSPORT_REJECT && action == JINGLE_TRANSPORT_REPLACE) + transport = jingle_content_get_pending_transport(content); + else + transport = jingle_content_get_transport(content); + + jingle_transport_to_xml(transport, node, action); + g_object_unref(transport); + } + + return node; +} + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ +static void +jingle_content_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + JingleContent *content = JINGLE_CONTENT(object); + JingleContentPrivate *priv = jingle_content_get_instance_private(content); + + switch (prop_id) { + case PROP_SESSION: + priv->session = g_value_get_object(value); + break; + case PROP_CREATOR: + g_free(priv->creator); + priv->creator = g_value_dup_string(value); + break; + case PROP_DISPOSITION: + g_free(priv->disposition); + priv->disposition = g_value_dup_string(value); + break; + case PROP_NAME: + g_free(priv->name); + priv->name = g_value_dup_string(value); + break; + case PROP_SENDERS: + g_free(priv->senders); + priv->senders = g_value_dup_string(value); + break; + case PROP_TRANSPORT: + if (priv->transport) + g_object_unref(priv->transport); + priv->transport = g_value_get_object(value); + break; + case PROP_PENDING_TRANSPORT: + if (priv->pending_transport) + g_object_unref(priv->pending_transport); + priv->pending_transport = g_value_get_object(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_content_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + JingleContent *content = JINGLE_CONTENT(object); + JingleContentPrivate *priv = jingle_content_get_instance_private(content); + + switch (prop_id) { + case PROP_SESSION: + g_value_set_object(value, priv->session); + break; + case PROP_CREATOR: + g_value_set_string(value, priv->creator); + break; + case PROP_DISPOSITION: + g_value_set_string(value, priv->disposition); + break; + case PROP_NAME: + g_value_set_string(value, priv->name); + break; + case PROP_SENDERS: + g_value_set_string(value, priv->senders); + break; + case PROP_TRANSPORT: + g_value_set_object(value, priv->transport); + break; + case PROP_PENDING_TRANSPORT: + g_value_set_object(value, priv->pending_transport); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_content_init (JingleContent *content) +{ +} + +static void +jingle_content_finalize (GObject *content) +{ + JingleContentPrivate *priv = jingle_content_get_instance_private(JINGLE_CONTENT(content)); + + purple_debug_info("jingle","jingle_content_finalize\n"); + + g_free(priv->description_type); + g_free(priv->creator); + g_free(priv->disposition); + g_free(priv->name); + g_free(priv->senders); + g_object_unref(priv->transport); + if (priv->pending_transport) + g_object_unref(priv->pending_transport); + + G_OBJECT_CLASS(jingle_content_parent_class)->finalize(content); +} + + +static void +jingle_content_class_finalize (JingleContentClass *klass) +{ +} static void jingle_content_class_init (JingleContentClass *klass) { - GObjectClass *gobject_class = (GObjectClass*)klass; - parent_class = g_type_class_peek_parent(klass); + GObjectClass *obj_class = G_OBJECT_CLASS(klass); - gobject_class->finalize = jingle_content_finalize; - gobject_class->set_property = jingle_content_set_property; - gobject_class->get_property = jingle_content_get_property; + obj_class->finalize = jingle_content_finalize; + obj_class->set_property = jingle_content_set_property; + obj_class->get_property = jingle_content_get_property; + klass->to_xml = jingle_content_to_xml_internal; klass->parse = jingle_content_parse_internal; - g_type_class_add_private(klass, sizeof(JingleContentPrivate)); - properties[PROP_SESSION] = g_param_spec_object("session", "Jingle Session", "The jingle session parent of this content.", @@ -126,116 +296,16 @@ JINGLE_TYPE_TRANSPORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties(gobject_class, PROP_LAST, properties); -} - -static void -jingle_content_init (JingleContent *content) -{ - content->priv = JINGLE_CONTENT_GET_PRIVATE(content); - memset(content->priv, 0, sizeof(*content->priv)); -} - -static void -jingle_content_finalize (GObject *content) -{ - JingleContentPrivate *priv = JINGLE_CONTENT_GET_PRIVATE(content); - purple_debug_info("jingle","jingle_content_finalize\n"); - - g_free(priv->description_type); - g_free(priv->creator); - g_free(priv->disposition); - g_free(priv->name); - g_free(priv->senders); - g_object_unref(priv->transport); - if (priv->pending_transport) - g_object_unref(priv->pending_transport); - - parent_class->finalize(content); + g_object_class_install_properties(obj_class, PROP_LAST, properties); } -static void -jingle_content_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +/****************************************************************************** + * Public API + *****************************************************************************/ +void +jingle_content_register(PurplePlugin *plugin) { - JingleContent *content; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_CONTENT(object)); - - content = JINGLE_CONTENT(object); - - switch (prop_id) { - case PROP_SESSION: - content->priv->session = g_value_get_object(value); - break; - case PROP_CREATOR: - g_free(content->priv->creator); - content->priv->creator = g_value_dup_string(value); - break; - case PROP_DISPOSITION: - g_free(content->priv->disposition); - content->priv->disposition = g_value_dup_string(value); - break; - case PROP_NAME: - g_free(content->priv->name); - content->priv->name = g_value_dup_string(value); - break; - case PROP_SENDERS: - g_free(content->priv->senders); - content->priv->senders = g_value_dup_string(value); - break; - case PROP_TRANSPORT: - if (content->priv->transport) - g_object_unref(content->priv->transport); - content->priv->transport = g_value_get_object(value); - break; - case PROP_PENDING_TRANSPORT: - if (content->priv->pending_transport) - g_object_unref(content->priv->pending_transport); - content->priv->pending_transport = g_value_get_object(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -jingle_content_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - JingleContent *content; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_CONTENT(object)); - - content = JINGLE_CONTENT(object); - - switch (prop_id) { - case PROP_SESSION: - g_value_set_object(value, content->priv->session); - break; - case PROP_CREATOR: - g_value_set_string(value, content->priv->creator); - break; - case PROP_DISPOSITION: - g_value_set_string(value, content->priv->disposition); - break; - case PROP_NAME: - g_value_set_string(value, content->priv->name); - break; - case PROP_SENDERS: - g_value_set_string(value, content->priv->senders); - break; - case PROP_TRANSPORT: - g_value_set_object(value, content->priv->transport); - break; - case PROP_PENDING_TRANSPORT: - g_value_set_object(value, content->priv->pending_transport); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + jingle_content_register_type(G_TYPE_MODULE(plugin)); } JingleContent * @@ -308,6 +378,14 @@ return transport; } +JingleTransport * +jingle_content_get_pending_transport(JingleContent *content) +{ + JingleTransport *pending_transport; + g_object_get(content, "pending-transport", &pending_transport, NULL); + return pending_transport; +} + void jingle_content_set_session(JingleContent *content, JingleSession *session) { @@ -316,14 +394,6 @@ g_object_set(content, "session", session, NULL); } -JingleTransport * -jingle_content_get_pending_transport(JingleContent *content) -{ - JingleTransport *pending_transport; - g_object_get(content, "pending-transport", &pending_transport, NULL); - return pending_transport; -} - void jingle_content_set_pending_transport(JingleContent *content, JingleTransport *transport) { @@ -333,13 +403,18 @@ void jingle_content_accept_transport(JingleContent *content) { + JingleContentPrivate *priv = NULL; GObject *obj; - if (content->priv->transport) - g_object_unref(content->priv->transport); + g_return_if_fail(JINGLE_IS_CONTENT(content)); + + priv = jingle_content_get_instance_private(content); - content->priv->transport = content->priv->pending_transport; - content->priv->pending_transport = NULL; + if (priv->transport) + g_object_unref(priv->transport); + + priv->transport = priv->pending_transport; + priv->pending_transport = NULL; obj = G_OBJECT(content); g_object_freeze_notify(obj); @@ -351,9 +426,15 @@ void jingle_content_remove_pending_transport(JingleContent *content) { - if (content->priv->pending_transport) { - g_object_unref(content->priv->pending_transport); - content->priv->pending_transport = NULL; + JingleContentPrivate *priv = NULL; + + g_return_if_fail(JINGLE_IS_CONTENT(content)); + + priv = jingle_content_get_instance_private(content); + + if (priv->pending_transport) { + g_object_unref(priv->pending_transport); + priv->pending_transport = NULL; } g_object_notify_by_pspec(G_OBJECT(content), properties[PROP_PENDING_TRANSPORT]); @@ -365,26 +446,6 @@ g_object_set(content, "senders", senders, NULL); } -static JingleContent * -jingle_content_parse_internal(PurpleXmlNode *content) -{ - PurpleXmlNode *description = purple_xmlnode_get_child(content, "description"); - const gchar *type = purple_xmlnode_get_namespace(description); - const gchar *creator = purple_xmlnode_get_attrib(content, "creator"); - const gchar *disposition = purple_xmlnode_get_attrib(content, "disposition"); - const gchar *senders = purple_xmlnode_get_attrib(content, "senders"); - const gchar *name = purple_xmlnode_get_attrib(content, "name"); - JingleTransport *transport = - jingle_transport_parse(purple_xmlnode_get_child(content, "transport")); - if (transport == NULL) - return NULL; - - if (senders == NULL) - senders = "both"; - - return jingle_content_create(type, creator, disposition, name, senders, transport); -} - JingleContent * jingle_content_parse(PurpleXmlNode *content) { @@ -398,51 +459,6 @@ } } -static PurpleXmlNode * -jingle_content_to_xml_internal(JingleContent *content, PurpleXmlNode *jingle, JingleActionType action) -{ - PurpleXmlNode *node = purple_xmlnode_new_child(jingle, "content"); - gchar *creator = jingle_content_get_creator(content); - gchar *name = jingle_content_get_name(content); - gchar *senders = jingle_content_get_senders(content); - gchar *disposition = jingle_content_get_disposition(content); - - purple_xmlnode_set_attrib(node, "creator", creator); - purple_xmlnode_set_attrib(node, "name", name); - purple_xmlnode_set_attrib(node, "senders", senders); - if (!purple_strequal("session", disposition)) - purple_xmlnode_set_attrib(node, "disposition", disposition); - - g_free(disposition); - g_free(senders); - g_free(name); - g_free(creator); - - if (action != JINGLE_CONTENT_REMOVE) { - JingleTransport *transport; - - if (action != JINGLE_TRANSPORT_ACCEPT && - action != JINGLE_TRANSPORT_INFO && - action != JINGLE_TRANSPORT_REJECT && - action != JINGLE_TRANSPORT_REPLACE) { - PurpleXmlNode *description = purple_xmlnode_new_child(node, "description"); - - purple_xmlnode_set_namespace(description, - jingle_content_get_description_type(content)); - } - - if (action != JINGLE_TRANSPORT_REJECT && action == JINGLE_TRANSPORT_REPLACE) - transport = jingle_content_get_pending_transport(content); - else - transport = jingle_content_get_transport(content); - - jingle_transport_to_xml(transport, node, action); - g_object_unref(transport); - } - - return node; -} - PurpleXmlNode * jingle_content_to_xml(JingleContent *content, PurpleXmlNode *jingle, JingleActionType action) {
--- a/libpurple/protocols/jabber/jingle/content.h Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/content.h Fri Mar 22 02:42:46 2019 +0000 @@ -47,8 +47,6 @@ typedef struct _JingleContent JingleContent; /** @copydoc _JingleContentClass */ typedef struct _JingleContentClass JingleContentClass; -/** @copydoc _JingleContentPrivate */ -typedef struct _JingleContentPrivate JingleContentPrivate; /** The content class */ struct _JingleContentClass @@ -65,7 +63,6 @@ struct _JingleContent { GObject parent; /**< The parent of this object. */ - JingleContentPrivate *priv; /**< The private data of this object. */ }; /** @@ -78,7 +75,7 @@ /** * Registers the JingleContent type in the type system. */ -void jingle_content_register_type(PurplePlugin *plugin); +void jingle_content_register(PurplePlugin *plugin); JingleContent *jingle_content_create(const gchar *type, const gchar *creator, const gchar *disposition, const gchar *name,
--- a/libpurple/protocols/jabber/jingle/iceudp.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/iceudp.c Fri Mar 22 02:42:46 2019 +0000 @@ -31,23 +31,11 @@ #include <string.h> -struct _JingleIceUdpPrivate +typedef struct { GList *local_candidates; GList *remote_candidates; -}; - -#define JINGLE_ICEUDP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_ICEUDP, JingleIceUdpPrivate)) - -static void jingle_iceudp_class_init (JingleIceUdpClass *klass); -static void jingle_iceudp_init (JingleIceUdp *iceudp); -static void jingle_iceudp_finalize (GObject *object); -static void jingle_iceudp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void jingle_iceudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static JingleTransport *jingle_iceudp_parse_internal(PurpleXmlNode *iceudp); -static PurpleXmlNode *jingle_iceudp_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action); -static void jingle_iceudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); -static GList *jingle_iceudp_get_remote_candidates(JingleTransport *transport); +} JingleIceUdpPrivate; enum { PROP_0, @@ -56,177 +44,24 @@ PROP_LAST }; -static JingleTransportClass *parent_class = NULL; static GParamSpec *properties[PROP_LAST]; -static JingleIceUdpCandidate * -jingle_iceudp_candidate_copy(JingleIceUdpCandidate *candidate) -{ - JingleIceUdpCandidate *new_candidate = g_new0(JingleIceUdpCandidate, 1); - new_candidate->id = g_strdup(candidate->id); - new_candidate->component = candidate->component; - new_candidate->foundation = g_strdup(candidate->foundation); - new_candidate->generation = candidate->generation; - new_candidate->ip = g_strdup(candidate->ip); - new_candidate->network = candidate->network; - new_candidate->port = candidate->port; - new_candidate->priority = candidate->priority; - new_candidate->protocol = g_strdup(candidate->protocol); - new_candidate->type = g_strdup(candidate->type); - - new_candidate->username = g_strdup(candidate->username); - new_candidate->password = g_strdup(candidate->password); - - new_candidate->rem_known = candidate->rem_known; - - return new_candidate; -} - -static void -jingle_iceudp_candidate_free(JingleIceUdpCandidate *candidate) -{ - g_free(candidate->foundation); - g_free(candidate->id); - g_free(candidate->ip); - g_free(candidate->protocol); - g_free(candidate->reladdr); - g_free(candidate->type); - - g_free(candidate->username); - g_free(candidate->password); -} - -G_DEFINE_BOXED_TYPE(JingleIceUdpCandidate, jingle_iceudp_candidate, - jingle_iceudp_candidate_copy, jingle_iceudp_candidate_free) - -JingleIceUdpCandidate * -jingle_iceudp_candidate_new(const gchar *id, - guint component, const gchar *foundation, - guint generation, const gchar *ip, - guint network, guint port, guint priority, - const gchar *protocol, const gchar *type, - const gchar *username, const gchar *password) -{ - JingleIceUdpCandidate *candidate = g_new0(JingleIceUdpCandidate, 1); - candidate->id = g_strdup(id); - candidate->component = component; - candidate->foundation = g_strdup(foundation); - candidate->generation = generation; - candidate->ip = g_strdup(ip); - candidate->network = network; - candidate->port = port; - candidate->priority = priority; - candidate->protocol = g_strdup(protocol); - candidate->type = g_strdup(type); - - candidate->username = g_strdup(username); - candidate->password = g_strdup(password); - - candidate->rem_known = FALSE; - return candidate; -} - -PURPLE_DEFINE_TYPE(JingleIceUdp, jingle_iceudp, JINGLE_TYPE_TRANSPORT); - -static void -jingle_iceudp_class_init (JingleIceUdpClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*)klass; - parent_class = g_type_class_peek_parent(klass); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + JingleIceUdp, + jingle_iceudp, + JINGLE_TYPE_TRANSPORT, + 0, + G_ADD_PRIVATE_DYNAMIC(JingleIceUdp) +); - gobject_class->finalize = jingle_iceudp_finalize; - gobject_class->set_property = jingle_iceudp_set_property; - gobject_class->get_property = jingle_iceudp_get_property; - klass->parent_class.to_xml = jingle_iceudp_to_xml_internal; - klass->parent_class.parse = jingle_iceudp_parse_internal; - klass->parent_class.transport_type = JINGLE_TRANSPORT_ICEUDP; - klass->parent_class.add_local_candidate = jingle_iceudp_add_local_candidate; - klass->parent_class.get_remote_candidates = jingle_iceudp_get_remote_candidates; - - g_type_class_add_private(klass, sizeof(JingleIceUdpPrivate)); - - properties[PROP_LOCAL_CANDIDATES] = g_param_spec_pointer("local-candidates", - "Local candidates", - "The local candidates for this transport.", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_REMOTE_CANDIDATES] = g_param_spec_pointer("remote-candidates", - "Remote candidates", - "The remote candidates for this transport.", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, PROP_LAST, properties); -} - -static void -jingle_iceudp_init (JingleIceUdp *iceudp) -{ - iceudp->priv = JINGLE_ICEUDP_GET_PRIVATE(iceudp); - iceudp->priv->local_candidates = NULL; - iceudp->priv->remote_candidates = NULL; -} - -static void -jingle_iceudp_finalize (GObject *iceudp) -{ -/* JingleIceUdpPrivate *priv = JINGLE_ICEUDP_GET_PRIVATE(iceudp); */ - purple_debug_info("jingle","jingle_iceudp_finalize\n"); - - G_OBJECT_CLASS(parent_class)->finalize(iceudp); -} - -static void -jingle_iceudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - JingleIceUdp *iceudp; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_ICEUDP(object)); - - iceudp = JINGLE_ICEUDP(object); - - switch (prop_id) { - case PROP_LOCAL_CANDIDATES: - iceudp->priv->local_candidates = - g_value_get_pointer(value); - break; - case PROP_REMOTE_CANDIDATES: - iceudp->priv->remote_candidates = - g_value_get_pointer(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -jingle_iceudp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - JingleIceUdp *iceudp; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_ICEUDP(object)); - - iceudp = JINGLE_ICEUDP(object); - - switch (prop_id) { - case PROP_LOCAL_CANDIDATES: - g_value_set_pointer(value, iceudp->priv->local_candidates); - break; - case PROP_REMOTE_CANDIDATES: - g_value_set_pointer(value, iceudp->priv->remote_candidates); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - +/****************************************************************************** + * JingleIceUdp Transport Implementation + *****************************************************************************/ static void jingle_iceudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) { JingleIceUdp *iceudp = JINGLE_ICEUDP(transport); + JingleIceUdpPrivate *priv = jingle_iceudp_get_instance_private(iceudp); PurpleMediaCandidateType type; gchar *ip; gchar *username; @@ -257,19 +92,19 @@ g_free(username); g_free(ip); - for (iter = iceudp->priv->local_candidates; iter; iter = g_list_next(iter)) { + for (iter = priv->local_candidates; iter; iter = g_list_next(iter)) { JingleIceUdpCandidate *c = iter->data; if (purple_strequal(c->id, id)) { generation = c->generation + 1; g_boxed_free(JINGLE_TYPE_ICEUDP_CANDIDATE, c); - iceudp->priv->local_candidates = g_list_delete_link( - iceudp->priv->local_candidates, iter); + priv->local_candidates = g_list_delete_link( + priv->local_candidates, iter); iceudp_candidate->generation = generation; - iceudp->priv->local_candidates = g_list_append( - iceudp->priv->local_candidates, iceudp_candidate); + priv->local_candidates = g_list_append( + priv->local_candidates, iceudp_candidate); g_object_notify_by_pspec(G_OBJECT(iceudp), properties[PROP_LOCAL_CANDIDATES]); @@ -277,8 +112,8 @@ } } - iceudp->priv->local_candidates = g_list_append( - iceudp->priv->local_candidates, iceudp_candidate); + priv->local_candidates = g_list_append( + priv->local_candidates, iceudp_candidate); g_object_notify_by_pspec(G_OBJECT(iceudp), properties[PROP_LOCAL_CANDIDATES]); } @@ -287,7 +122,8 @@ jingle_iceudp_get_remote_candidates(JingleTransport *transport) { JingleIceUdp *iceudp = JINGLE_ICEUDP(transport); - GList *candidates = iceudp->priv->remote_candidates; + JingleIceUdpPrivate *priv = jingle_iceudp_get_instance_private(iceudp); + GList *candidates = priv->remote_candidates; GList *ret = NULL; for (; candidates; candidates = g_list_next(candidates)) { @@ -321,7 +157,8 @@ jingle_iceudp_get_remote_candidate_by_id(JingleIceUdp *iceudp, const gchar *id) { - GList *iter = iceudp->priv->remote_candidates; + JingleIceUdpPrivate *priv = jingle_iceudp_get_instance_private(iceudp); + GList *iter = priv->remote_candidates; for (; iter; iter = g_list_next(iter)) { JingleIceUdpCandidate *candidate = iter->data; if (purple_strequal(candidate->id, id)) { @@ -334,7 +171,7 @@ static void jingle_iceudp_add_remote_candidate(JingleIceUdp *iceudp, JingleIceUdpCandidate *candidate) { - JingleIceUdpPrivate *priv = JINGLE_ICEUDP_GET_PRIVATE(iceudp); + JingleIceUdpPrivate *priv = jingle_iceudp_get_instance_private(iceudp); JingleIceUdpCandidate *iceudp_candidate = jingle_iceudp_get_remote_candidate_by_id(iceudp, candidate->id); @@ -351,7 +188,7 @@ static JingleTransport * jingle_iceudp_parse_internal(PurpleXmlNode *iceudp) { - JingleTransport *transport = parent_class->parse(iceudp); + JingleTransport *transport = JINGLE_TRANSPORT_CLASS(jingle_iceudp_parent_class)->parse(iceudp); PurpleXmlNode *candidate = purple_xmlnode_get_child(iceudp, "candidate"); JingleIceUdpCandidate *iceudp_candidate = NULL; @@ -401,14 +238,14 @@ static PurpleXmlNode * jingle_iceudp_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action) { - PurpleXmlNode *node = parent_class->to_xml(transport, content, action); + PurpleXmlNode *node = JINGLE_TRANSPORT_CLASS(jingle_iceudp_parent_class)->to_xml(transport, content, action); if (action == JINGLE_SESSION_INITIATE || action == JINGLE_SESSION_ACCEPT || action == JINGLE_TRANSPORT_INFO || action == JINGLE_CONTENT_ADD || action == JINGLE_TRANSPORT_REPLACE) { - JingleIceUdpPrivate *priv = JINGLE_ICEUDP_GET_PRIVATE(transport); + JingleIceUdpPrivate *priv = jingle_iceudp_get_instance_private(JINGLE_ICEUDP(transport)); GList *iter = priv->local_candidates; gboolean used_candidate = FALSE; @@ -474,3 +311,171 @@ return node; } +/****************************************************************************** + * JingleIceUdp GObject Implementation + *****************************************************************************/ +static void +jingle_iceudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + JingleIceUdp *iceudp = JINGLE_ICEUDP(object); + JingleIceUdpPrivate *priv = jingle_iceudp_get_instance_private(iceudp); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + priv->local_candidates = + g_value_get_pointer(value); + break; + case PROP_REMOTE_CANDIDATES: + priv->remote_candidates = + g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_iceudp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + JingleIceUdp *iceudp = JINGLE_ICEUDP(object); + JingleIceUdpPrivate *priv = jingle_iceudp_get_instance_private(iceudp); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + g_value_set_pointer(value, priv->local_candidates); + break; + case PROP_REMOTE_CANDIDATES: + g_value_set_pointer(value, priv->remote_candidates); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_iceudp_init (JingleIceUdp *iceudp) +{ +} + +static void +jingle_iceudp_finalize (GObject *iceudp) +{ +/* JingleIceUdpPrivate *priv = JINGLE_ICEUDP_GET_PRIVATE(iceudp); */ + purple_debug_info("jingle","jingle_iceudp_finalize\n"); + + G_OBJECT_CLASS(jingle_iceudp_parent_class)->finalize(iceudp); +} + +static void +jingle_iceudp_class_finalize (JingleIceUdpClass *klass) +{ +} + +static void +jingle_iceudp_class_init (JingleIceUdpClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + JingleTransportClass *transport_class = JINGLE_TRANSPORT_CLASS(klass); + + obj_class->finalize = jingle_iceudp_finalize; + obj_class->set_property = jingle_iceudp_set_property; + obj_class->get_property = jingle_iceudp_get_property; + + transport_class->to_xml = jingle_iceudp_to_xml_internal; + transport_class->parse = jingle_iceudp_parse_internal; + transport_class->transport_type = JINGLE_TRANSPORT_ICEUDP; + transport_class->add_local_candidate = jingle_iceudp_add_local_candidate; + transport_class->get_remote_candidates = jingle_iceudp_get_remote_candidates; + + properties[PROP_LOCAL_CANDIDATES] = g_param_spec_pointer("local-candidates", + "Local candidates", + "The local candidates for this transport.", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_REMOTE_CANDIDATES] = g_param_spec_pointer("remote-candidates", + "Remote candidates", + "The remote candidates for this transport.", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, PROP_LAST, properties); +} + +/****************************************************************************** + * JingleIceUdpCandidate Boxed Implementation + *****************************************************************************/ +static JingleIceUdpCandidate * +jingle_iceudp_candidate_copy(JingleIceUdpCandidate *candidate) +{ + JingleIceUdpCandidate *new_candidate = g_new0(JingleIceUdpCandidate, 1); + new_candidate->id = g_strdup(candidate->id); + new_candidate->component = candidate->component; + new_candidate->foundation = g_strdup(candidate->foundation); + new_candidate->generation = candidate->generation; + new_candidate->ip = g_strdup(candidate->ip); + new_candidate->network = candidate->network; + new_candidate->port = candidate->port; + new_candidate->priority = candidate->priority; + new_candidate->protocol = g_strdup(candidate->protocol); + new_candidate->type = g_strdup(candidate->type); + + new_candidate->username = g_strdup(candidate->username); + new_candidate->password = g_strdup(candidate->password); + + new_candidate->rem_known = candidate->rem_known; + + return new_candidate; +} + +static void +jingle_iceudp_candidate_free(JingleIceUdpCandidate *candidate) +{ + g_free(candidate->foundation); + g_free(candidate->id); + g_free(candidate->ip); + g_free(candidate->protocol); + g_free(candidate->reladdr); + g_free(candidate->type); + + g_free(candidate->username); + g_free(candidate->password); +} + +G_DEFINE_BOXED_TYPE(JingleIceUdpCandidate, jingle_iceudp_candidate, + jingle_iceudp_candidate_copy, jingle_iceudp_candidate_free) + +/****************************************************************************** + * Public API + *****************************************************************************/ +void +jingle_iceudp_register(PurplePlugin *plugin) { + jingle_iceudp_register_type(G_TYPE_MODULE(plugin)); +} + +JingleIceUdpCandidate * +jingle_iceudp_candidate_new(const gchar *id, + guint component, const gchar *foundation, + guint generation, const gchar *ip, + guint network, guint port, guint priority, + const gchar *protocol, const gchar *type, + const gchar *username, const gchar *password) +{ + JingleIceUdpCandidate *candidate = g_new0(JingleIceUdpCandidate, 1); + candidate->id = g_strdup(id); + candidate->component = component; + candidate->foundation = g_strdup(foundation); + candidate->generation = generation; + candidate->ip = g_strdup(ip); + candidate->network = network; + candidate->port = port; + candidate->priority = priority; + candidate->protocol = g_strdup(protocol); + candidate->type = g_strdup(type); + + candidate->username = g_strdup(username); + candidate->password = g_strdup(password); + + candidate->rem_known = FALSE; + return candidate; +}
--- a/libpurple/protocols/jabber/jingle/iceudp.h Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/iceudp.h Fri Mar 22 02:42:46 2019 +0000 @@ -33,7 +33,6 @@ G_BEGIN_DECLS #define JINGLE_TYPE_ICEUDP (jingle_iceudp_get_type()) -#define JINGLE_TYPE_ICEUDP_CANDIDATE (jingle_iceudp_candidate_get_type()) #define JINGLE_ICEUDP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), JINGLE_TYPE_ICEUDP, JingleIceUdp)) #define JINGLE_ICEUDP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), JINGLE_TYPE_ICEUDP, JingleIceUdpClass)) #define JINGLE_IS_ICEUDP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), JINGLE_TYPE_ICEUDP)) @@ -44,8 +43,9 @@ typedef struct _JingleIceUdp JingleIceUdp; /** @copydoc _JingleIceUdpClass */ typedef struct _JingleIceUdpClass JingleIceUdpClass; -/** @copydoc _JingleIceUdpPrivate */ -typedef struct _JingleIceUdpPrivate JingleIceUdpPrivate; + +#define JINGLE_TYPE_ICEUDP_CANDIDATE (jingle_iceudp_candidate_get_type()) + /** @copydoc _JingleIceUdpCandidate */ typedef struct _JingleIceUdpCandidate JingleIceUdpCandidate; @@ -62,7 +62,6 @@ struct _JingleIceUdp { JingleTransport parent; /**< The parent of this object. */ - JingleIceUdpPrivate *priv; /**< The private data of this object. */ }; struct _JingleIceUdpCandidate @@ -99,7 +98,7 @@ /** * Registers the JingleIceUdp type in the type system. */ -void jingle_iceudp_register_type(PurplePlugin *plugin); +void jingle_iceudp_register(PurplePlugin *plugin); JingleIceUdpCandidate *jingle_iceudp_candidate_new(const gchar *id, guint component, const gchar *foundation, guint generation,
--- a/libpurple/protocols/jabber/jingle/rawudp.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/rawudp.c Fri Mar 22 02:42:46 2019 +0000 @@ -31,23 +31,11 @@ #include <string.h> -struct _JingleRawUdpPrivate +typedef struct { GList *local_candidates; GList *remote_candidates; -}; - -#define JINGLE_RAWUDP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_RAWUDP, JingleRawUdpPrivate)) - -static void jingle_rawudp_class_init (JingleRawUdpClass *klass); -static void jingle_rawudp_init (JingleRawUdp *rawudp); -static void jingle_rawudp_finalize (GObject *object); -static void jingle_rawudp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void jingle_rawudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static JingleTransport *jingle_rawudp_parse_internal(PurpleXmlNode *rawudp); -static PurpleXmlNode *jingle_rawudp_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action); -static void jingle_rawudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); -static GList *jingle_rawudp_get_remote_candidates(JingleTransport *transport); +} JingleRawUdpPrivate; enum { PROP_0, @@ -55,190 +43,25 @@ PROP_REMOTE_CANDIDATES, PROP_LAST }; - -static JingleTransportClass *parent_class = NULL; static GParamSpec *properties[PROP_LAST]; -static JingleRawUdpCandidate * -jingle_rawudp_candidate_copy(JingleRawUdpCandidate *candidate) -{ - JingleRawUdpCandidate *new_candidate = g_new0(JingleRawUdpCandidate, 1); - new_candidate->generation = candidate->generation; - new_candidate->component = candidate->component; - new_candidate->id = g_strdup(candidate->id); - new_candidate->ip = g_strdup(candidate->ip); - new_candidate->port = candidate->port; - - new_candidate->rem_known = candidate->rem_known; - return new_candidate; -} - -static void -jingle_rawudp_candidate_free(JingleRawUdpCandidate *candidate) -{ - g_free(candidate->id); - g_free(candidate->ip); -} - -G_DEFINE_BOXED_TYPE(JingleRawUdpCandidate, jingle_rawudp_candidate, - jingle_rawudp_candidate_copy, jingle_rawudp_candidate_free) - -JingleRawUdpCandidate * -jingle_rawudp_candidate_new(const gchar *id, guint generation, guint component, const gchar *ip, guint port) -{ - JingleRawUdpCandidate *candidate = g_new0(JingleRawUdpCandidate, 1); - candidate->generation = generation; - candidate->component = component; - candidate->id = g_strdup(id); - candidate->ip = g_strdup(ip); - candidate->port = port; - - candidate->rem_known = FALSE; - return candidate; -} - -PURPLE_DEFINE_TYPE(JingleRawUdp, jingle_rawudp, JINGLE_TYPE_TRANSPORT); - -static void -jingle_rawudp_class_init (JingleRawUdpClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*)klass; - parent_class = g_type_class_peek_parent(klass); - - gobject_class->finalize = jingle_rawudp_finalize; - gobject_class->set_property = jingle_rawudp_set_property; - gobject_class->get_property = jingle_rawudp_get_property; - klass->parent_class.to_xml = jingle_rawudp_to_xml_internal; - klass->parent_class.parse = jingle_rawudp_parse_internal; - klass->parent_class.transport_type = JINGLE_TRANSPORT_RAWUDP; - klass->parent_class.add_local_candidate = jingle_rawudp_add_local_candidate; - klass->parent_class.get_remote_candidates = jingle_rawudp_get_remote_candidates; - - g_type_class_add_private(klass, sizeof(JingleRawUdpPrivate)); - - properties[PROP_LOCAL_CANDIDATES] = g_param_spec_pointer("local-candidates", - "Local candidates", - "The local candidates for this transport.", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_REMOTE_CANDIDATES] = g_param_spec_pointer("remote-candidates", - "Remote candidates", - "The remote candidates for this transport.", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, PROP_LAST, properties); -} - -static void -jingle_rawudp_init (JingleRawUdp *rawudp) -{ - rawudp->priv = JINGLE_RAWUDP_GET_PRIVATE(rawudp); - rawudp->priv->local_candidates = NULL; - rawudp->priv->remote_candidates = NULL; -} - -static void -jingle_rawudp_finalize (GObject *rawudp) -{ -/* JingleRawUdpPrivate *priv = JINGLE_RAWUDP_GET_PRIVATE(rawudp); */ - purple_debug_info("jingle","jingle_rawudp_finalize\n"); - - G_OBJECT_CLASS(parent_class)->finalize(rawudp); -} +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + JingleRawUdp, + jingle_rawudp, + JINGLE_TYPE_TRANSPORT, + 0, + G_ADD_PRIVATE_DYNAMIC(JingleRawUdp) +); -static void -jingle_rawudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - JingleRawUdp *rawudp; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_RAWUDP(object)); - - rawudp = JINGLE_RAWUDP(object); - - switch (prop_id) { - case PROP_LOCAL_CANDIDATES: - rawudp->priv->local_candidates = - g_value_get_pointer(value); - break; - case PROP_REMOTE_CANDIDATES: - rawudp->priv->remote_candidates = - g_value_get_pointer(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -jingle_rawudp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - JingleRawUdp *rawudp; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_RAWUDP(object)); - - rawudp = JINGLE_RAWUDP(object); - - switch (prop_id) { - case PROP_LOCAL_CANDIDATES: - g_value_set_pointer(value, rawudp->priv->local_candidates); - break; - case PROP_REMOTE_CANDIDATES: - g_value_set_pointer(value, rawudp->priv->remote_candidates); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -jingle_rawudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) -{ - JingleRawUdp *rawudp = JINGLE_RAWUDP(transport); - gchar *ip; - JingleRawUdpCandidate *rawudp_candidate; - GList *iter; - - ip = purple_media_candidate_get_ip(candidate); - rawudp_candidate = jingle_rawudp_candidate_new(id, generation, - purple_media_candidate_get_component_id(candidate), - ip, purple_media_candidate_get_port(candidate)); - g_free(ip); - - for (iter = rawudp->priv->local_candidates; iter; iter = g_list_next(iter)) { - JingleRawUdpCandidate *c = iter->data; - if (purple_strequal(c->id, id)) { - generation = c->generation + 1; - - g_boxed_free(JINGLE_TYPE_RAWUDP_CANDIDATE, c); - rawudp->priv->local_candidates = g_list_delete_link( - rawudp->priv->local_candidates, iter); - - rawudp_candidate->generation = generation; - - rawudp->priv->local_candidates = g_list_append( - rawudp->priv->local_candidates, rawudp_candidate); - - g_object_notify_by_pspec(G_OBJECT(rawudp), properties[PROP_LOCAL_CANDIDATES]); - - return; - } - } - - rawudp->priv->local_candidates = g_list_append( - rawudp->priv->local_candidates, rawudp_candidate); - - g_object_notify_by_pspec(G_OBJECT(rawudp), properties[PROP_LOCAL_CANDIDATES]); -} - +/****************************************************************************** + * JingleRawUdp Transport Implementation + *****************************************************************************/ static GList * jingle_rawudp_get_remote_candidates(JingleTransport *transport) { JingleRawUdp *rawudp = JINGLE_RAWUDP(transport); - GList *candidates = rawudp->priv->remote_candidates; + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(rawudp); + GList *candidates = priv->remote_candidates; GList *ret = NULL; for (; candidates; candidates = g_list_next(candidates)) { @@ -256,7 +79,9 @@ static JingleRawUdpCandidate * jingle_rawudp_get_remote_candidate_by_id(JingleRawUdp *rawudp, gchar *id) { - GList *iter = rawudp->priv->remote_candidates; + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(rawudp); + + GList *iter = priv->remote_candidates; for (; iter; iter = g_list_next(iter)) { JingleRawUdpCandidate *candidate = iter->data; if (purple_strequal(candidate->id, id)) { @@ -269,7 +94,7 @@ static void jingle_rawudp_add_remote_candidate(JingleRawUdp *rawudp, JingleRawUdpCandidate *candidate) { - JingleRawUdpPrivate *priv = JINGLE_RAWUDP_GET_PRIVATE(rawudp); + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(rawudp); JingleRawUdpCandidate *rawudp_candidate = jingle_rawudp_get_remote_candidate_by_id(rawudp, candidate->id); if (rawudp_candidate != NULL) { @@ -282,11 +107,50 @@ g_object_notify_by_pspec(G_OBJECT(rawudp), properties[PROP_REMOTE_CANDIDATES]); } +static PurpleXmlNode * +jingle_rawudp_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action) +{ + PurpleXmlNode *node = JINGLE_TRANSPORT_CLASS(jingle_rawudp_parent_class)->to_xml(transport, content, action); + + if (action == JINGLE_SESSION_INITIATE || + action == JINGLE_TRANSPORT_INFO || + action == JINGLE_SESSION_ACCEPT) { + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(JINGLE_RAWUDP(transport)); + GList *iter = priv->local_candidates; + + for (; iter; iter = g_list_next(iter)) { + JingleRawUdpCandidate *candidate = iter->data; + PurpleXmlNode *xmltransport; + gchar *generation, *component, *port; + + if (candidate->rem_known == TRUE) + continue; + candidate->rem_known = TRUE; + + xmltransport = purple_xmlnode_new_child(node, "candidate"); + generation = g_strdup_printf("%d", candidate->generation); + component = g_strdup_printf("%d", candidate->component); + port = g_strdup_printf("%d", candidate->port); + + purple_xmlnode_set_attrib(xmltransport, "generation", generation); + purple_xmlnode_set_attrib(xmltransport, "component", component); + purple_xmlnode_set_attrib(xmltransport, "id", candidate->id); + purple_xmlnode_set_attrib(xmltransport, "ip", candidate->ip); + purple_xmlnode_set_attrib(xmltransport, "port", port); + + g_free(port); + g_free(generation); + } + } + + return node; +} + static JingleTransport * jingle_rawudp_parse_internal(PurpleXmlNode *rawudp) { - JingleTransport *transport = parent_class->parse(rawudp); - JingleRawUdpPrivate *priv = JINGLE_RAWUDP_GET_PRIVATE(transport); + JingleTransport *transport = JINGLE_TRANSPORT_CLASS(jingle_rawudp_parent_class)->parse(rawudp); + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(JINGLE_RAWUDP(transport)); PurpleXmlNode *candidate = purple_xmlnode_get_child(rawudp, "candidate"); JingleRawUdpCandidate *rawudp_candidate = NULL; @@ -323,42 +187,180 @@ return transport; } -static PurpleXmlNode * -jingle_rawudp_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action) +static void +jingle_rawudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) { - PurpleXmlNode *node = parent_class->to_xml(transport, content, action); + JingleRawUdp *rawudp = JINGLE_RAWUDP(transport); + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(rawudp); + gchar *ip; + JingleRawUdpCandidate *rawudp_candidate; + GList *iter; - if (action == JINGLE_SESSION_INITIATE || - action == JINGLE_TRANSPORT_INFO || - action == JINGLE_SESSION_ACCEPT) { - JingleRawUdpPrivate *priv = JINGLE_RAWUDP_GET_PRIVATE(transport); - GList *iter = priv->local_candidates; - - for (; iter; iter = g_list_next(iter)) { - JingleRawUdpCandidate *candidate = iter->data; - PurpleXmlNode *xmltransport; - gchar *generation, *component, *port; + ip = purple_media_candidate_get_ip(candidate); + rawudp_candidate = jingle_rawudp_candidate_new(id, generation, + purple_media_candidate_get_component_id(candidate), + ip, purple_media_candidate_get_port(candidate)); + g_free(ip); - if (candidate->rem_known == TRUE) - continue; - candidate->rem_known = TRUE; + for (iter = priv->local_candidates; iter; iter = g_list_next(iter)) { + JingleRawUdpCandidate *c = iter->data; + if (purple_strequal(c->id, id)) { + generation = c->generation + 1; - xmltransport = purple_xmlnode_new_child(node, "candidate"); - generation = g_strdup_printf("%d", candidate->generation); - component = g_strdup_printf("%d", candidate->component); - port = g_strdup_printf("%d", candidate->port); + g_boxed_free(JINGLE_TYPE_RAWUDP_CANDIDATE, c); + priv->local_candidates = g_list_delete_link( + priv->local_candidates, iter); - purple_xmlnode_set_attrib(xmltransport, "generation", generation); - purple_xmlnode_set_attrib(xmltransport, "component", component); - purple_xmlnode_set_attrib(xmltransport, "id", candidate->id); - purple_xmlnode_set_attrib(xmltransport, "ip", candidate->ip); - purple_xmlnode_set_attrib(xmltransport, "port", port); + rawudp_candidate->generation = generation; - g_free(port); - g_free(generation); + priv->local_candidates = g_list_append( + priv->local_candidates, rawudp_candidate); + + g_object_notify_by_pspec(G_OBJECT(rawudp), properties[PROP_LOCAL_CANDIDATES]); + + return; } } - return node; + priv->local_candidates = g_list_append( + priv->local_candidates, rawudp_candidate); + + g_object_notify_by_pspec(G_OBJECT(rawudp), properties[PROP_LOCAL_CANDIDATES]); +} + +/****************************************************************************** + * JingleRawUdp GObject Stuff + *****************************************************************************/ +static void +jingle_rawudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + JingleRawUdp *rawudp = JINGLE_RAWUDP(object); + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(rawudp); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + priv->local_candidates = g_value_get_pointer(value); + break; + case PROP_REMOTE_CANDIDATES: + priv->remote_candidates = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_rawudp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + JingleRawUdp *rawudp = JINGLE_RAWUDP(object); + JingleRawUdpPrivate *priv = jingle_rawudp_get_instance_private(rawudp); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + g_value_set_pointer(value, priv->local_candidates); + break; + case PROP_REMOTE_CANDIDATES: + g_value_set_pointer(value, priv->remote_candidates); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_rawudp_init (JingleRawUdp *rawudp) +{ +} + +static void +jingle_rawudp_finalize (GObject *rawudp) +{ +/* JingleRawUdpPrivate *priv = JINGLE_RAWUDP_GET_PRIVATE(rawudp); */ + purple_debug_info("jingle","jingle_rawudp_finalize\n"); + + G_OBJECT_CLASS(jingle_rawudp_parent_class)->finalize(rawudp); +} + +static void +jingle_rawudp_class_finalize(JingleRawUdpClass *klass) { } +static void +jingle_rawudp_class_init (JingleRawUdpClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + JingleTransportClass *transport_class = JINGLE_TRANSPORT_CLASS(klass); + + obj_class->finalize = jingle_rawudp_finalize; + obj_class->set_property = jingle_rawudp_set_property; + obj_class->get_property = jingle_rawudp_get_property; + + transport_class->to_xml = jingle_rawudp_to_xml_internal; + transport_class->parse = jingle_rawudp_parse_internal; + transport_class->transport_type = JINGLE_TRANSPORT_RAWUDP; + transport_class->add_local_candidate = jingle_rawudp_add_local_candidate; + transport_class->get_remote_candidates = jingle_rawudp_get_remote_candidates; + + properties[PROP_LOCAL_CANDIDATES] = g_param_spec_pointer("local-candidates", + "Local candidates", + "The local candidates for this transport.", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_REMOTE_CANDIDATES] = g_param_spec_pointer("remote-candidates", + "Remote candidates", + "The remote candidates for this transport.", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, PROP_LAST, properties); +} + +/****************************************************************************** + * JingleRawUdpCandidate Boxed Type + *****************************************************************************/ +static JingleRawUdpCandidate * +jingle_rawudp_candidate_copy(JingleRawUdpCandidate *candidate) +{ + JingleRawUdpCandidate *new_candidate = g_new0(JingleRawUdpCandidate, 1); + new_candidate->generation = candidate->generation; + new_candidate->component = candidate->component; + new_candidate->id = g_strdup(candidate->id); + new_candidate->ip = g_strdup(candidate->ip); + new_candidate->port = candidate->port; + + new_candidate->rem_known = candidate->rem_known; + return new_candidate; +} + +static void +jingle_rawudp_candidate_free(JingleRawUdpCandidate *candidate) +{ + g_free(candidate->id); + g_free(candidate->ip); +} + +G_DEFINE_BOXED_TYPE(JingleRawUdpCandidate, jingle_rawudp_candidate, + jingle_rawudp_candidate_copy, jingle_rawudp_candidate_free) + +/****************************************************************************** + * Public API + *****************************************************************************/ +void +jingle_rawudp_register(PurplePlugin *plugin) { + jingle_rawudp_register_type(G_TYPE_MODULE(plugin)); +} + +JingleRawUdpCandidate * +jingle_rawudp_candidate_new(const gchar *id, guint generation, guint component, const gchar *ip, guint port) +{ + JingleRawUdpCandidate *candidate = g_new0(JingleRawUdpCandidate, 1); + candidate->generation = generation; + candidate->component = component; + candidate->id = g_strdup(id); + candidate->ip = g_strdup(ip); + candidate->port = port; + + candidate->rem_known = FALSE; + return candidate; +}
--- a/libpurple/protocols/jabber/jingle/rawudp.h Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/rawudp.h Fri Mar 22 02:42:46 2019 +0000 @@ -33,7 +33,6 @@ G_BEGIN_DECLS #define JINGLE_TYPE_RAWUDP (jingle_rawudp_get_type()) -#define JINGLE_TYPE_RAWUDP_CANDIDATE (jingle_rawudp_candidate_get_type()) #define JINGLE_RAWUDP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), JINGLE_TYPE_RAWUDP, JingleRawUdp)) #define JINGLE_RAWUDP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), JINGLE_TYPE_RAWUDP, JingleRawUdpClass)) #define JINGLE_IS_RAWUDP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), JINGLE_TYPE_RAWUDP)) @@ -44,8 +43,9 @@ typedef struct _JingleRawUdp JingleRawUdp; /** @copydoc _JingleRawUdpClass */ typedef struct _JingleRawUdpClass JingleRawUdpClass; -/** @copydoc _JingleRawUdpPrivate */ -typedef struct _JingleRawUdpPrivate JingleRawUdpPrivate; + +#define JINGLE_TYPE_RAWUDP_CANDIDATE (jingle_rawudp_candidate_get_type()) + /** @copydoc _JingleRawUdpCandidate */ typedef struct _JingleRawUdpCandidate JingleRawUdpCandidate; @@ -62,7 +62,6 @@ struct _JingleRawUdp { JingleTransport parent; /**< The parent of this object. */ - JingleRawUdpPrivate *priv; /**< The private data of this object. */ }; struct _JingleRawUdpCandidate @@ -89,7 +88,7 @@ /** * Registers the JingleRawUdp type in the type system. */ -void jingle_rawudp_register_type(PurplePlugin *plugin); +void jingle_rawudp_register(PurplePlugin *plugin); JingleRawUdpCandidate *jingle_rawudp_candidate_new(const gchar *id, guint generation, guint component, const gchar *ip, guint port);
--- a/libpurple/protocols/jabber/jingle/rtp.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.c Fri Mar 22 02:42:46 2019 +0000 @@ -40,19 +40,12 @@ #include <string.h> -struct _JingleRtpPrivate +typedef struct { gchar *media_type; gchar *ssrc; -}; - -#define JINGLE_RTP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_RTP, JingleRtpPrivate)) +} JingleRtpPrivate; -static void jingle_rtp_class_init (JingleRtpClass *klass); -static void jingle_rtp_init (JingleRtp *rtp); -static void jingle_rtp_finalize (GObject *object); -static void jingle_rtp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void jingle_rtp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static JingleContent *jingle_rtp_parse_internal(PurpleXmlNode *rtp); static PurpleXmlNode *jingle_rtp_to_xml_internal(JingleContent *rtp, PurpleXmlNode *content, JingleActionType action); static void jingle_rtp_handle_action_internal(JingleContent *content, PurpleXmlNode *jingle, JingleActionType action); @@ -66,144 +59,19 @@ PROP_LAST }; -static JingleContentClass *parent_class = NULL; static GParamSpec *properties[PROP_LAST]; -PURPLE_DEFINE_TYPE(JingleRtp, jingle_rtp, JINGLE_TYPE_CONTENT); - -static void -jingle_rtp_class_init (JingleRtpClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*)klass; - parent_class = g_type_class_peek_parent(klass); - - gobject_class->finalize = jingle_rtp_finalize; - gobject_class->set_property = jingle_rtp_set_property; - gobject_class->get_property = jingle_rtp_get_property; - klass->parent_class.to_xml = jingle_rtp_to_xml_internal; - klass->parent_class.parse = jingle_rtp_parse_internal; - klass->parent_class.description_type = JINGLE_APP_RTP; - klass->parent_class.handle_action = jingle_rtp_handle_action_internal; - - g_type_class_add_private(klass, sizeof(JingleRtpPrivate)); - - properties[PROP_MEDIA_TYPE] = g_param_spec_string("media-type", - "Media Type", - "The media type (\"audio\" or \"video\") for this rtp session.", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - properties[PROP_SSRC] = g_param_spec_string("ssrc", - "ssrc", - "The ssrc for this rtp session.", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, PROP_LAST, properties); -} - -static void -jingle_rtp_init (JingleRtp *rtp) -{ - rtp->priv = JINGLE_RTP_GET_PRIVATE(rtp); - memset(rtp->priv, 0, sizeof(*rtp->priv)); -} - -static void -jingle_rtp_finalize (GObject *rtp) -{ - JingleRtpPrivate *priv = JINGLE_RTP_GET_PRIVATE(rtp); - purple_debug_info("jingle-rtp","jingle_rtp_finalize\n"); - - g_free(priv->media_type); - g_free(priv->ssrc); - - G_OBJECT_CLASS(parent_class)->finalize(rtp); -} - -static void -jingle_rtp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - JingleRtp *rtp; - g_return_if_fail(JINGLE_IS_RTP(object)); - - rtp = JINGLE_RTP(object); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + JingleRtp, + jingle_rtp, + JINGLE_TYPE_CONTENT, + 0, + G_ADD_PRIVATE_DYNAMIC(JingleRtp) +); - switch (prop_id) { - case PROP_MEDIA_TYPE: - g_free(rtp->priv->media_type); - rtp->priv->media_type = g_value_dup_string(value); - break; - case PROP_SSRC: - g_free(rtp->priv->ssrc); - rtp->priv->ssrc = g_value_dup_string(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -jingle_rtp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - JingleRtp *rtp; - g_return_if_fail(JINGLE_IS_RTP(object)); - - rtp = JINGLE_RTP(object); - - switch (prop_id) { - case PROP_MEDIA_TYPE: - g_value_set_string(value, rtp->priv->media_type); - break; - case PROP_SSRC: - g_value_set_string(value, rtp->priv->ssrc); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -gchar * -jingle_rtp_get_media_type(JingleContent *content) -{ - gchar *media_type; - g_object_get(content, "media-type", &media_type, NULL); - return media_type; -} - -gchar * -jingle_rtp_get_ssrc(JingleContent *content) -{ - gchar *ssrc; - g_object_get(content, "ssrc", &ssrc, NULL); - return ssrc; -} - -static PurpleMedia * -jingle_rtp_get_media(JingleSession *session) -{ - JabberStream *js = jingle_session_get_js(session); - PurpleMedia *media = NULL; - GList *iter = purple_media_manager_get_media_by_account( - purple_media_manager_get(), - purple_connection_get_account(js->gc)); - - for (; iter; iter = g_list_delete_link(iter, iter)) { - JingleSession *media_session = - purple_media_get_protocol_data(iter->data); - if (media_session == session) { - media = iter->data; - break; - } - } - if (iter != NULL) - g_list_free(iter); - - return media; -} - +/****************************************************************************** + * Helpers + *****************************************************************************/ static JingleTransport * jingle_rtp_candidates_to_transport(JingleSession *session, const gchar *type, guint generation, GList *candidates) { @@ -577,20 +445,6 @@ return codecs; } -static JingleContent * -jingle_rtp_parse_internal(PurpleXmlNode *rtp) -{ - JingleContent *content = parent_class->parse(rtp); - PurpleXmlNode *description = purple_xmlnode_get_child(rtp, "description"); - const gchar *media_type = purple_xmlnode_get_attrib(description, "media"); - const gchar *ssrc = purple_xmlnode_get_attrib(description, "ssrc"); - purple_debug_info("jingle-rtp", "rtp parse\n"); - g_object_set(content, "media-type", media_type, NULL); - if (ssrc != NULL) - g_object_set(content, "ssrc", ssrc, NULL); - return content; -} - static void jingle_rtp_add_payloads(PurpleXmlNode *description, GList *codecs) { @@ -632,10 +486,13 @@ } } +/****************************************************************************** + * JingleContent Implementation + *****************************************************************************/ static PurpleXmlNode * jingle_rtp_to_xml_internal(JingleContent *rtp, PurpleXmlNode *content, JingleActionType action) { - PurpleXmlNode *node = parent_class->to_xml(rtp, content, action); + PurpleXmlNode *node = JINGLE_CONTENT_CLASS(jingle_rtp_parent_class)->to_xml(rtp, content, action); PurpleXmlNode *description = purple_xmlnode_get_child(node, "description"); if (description != NULL) { JingleSession *session = jingle_content_get_session(rtp); @@ -660,6 +517,20 @@ return node; } +static JingleContent * +jingle_rtp_parse_internal(PurpleXmlNode *rtp) +{ + JingleContent *content = JINGLE_CONTENT_CLASS(jingle_rtp_parent_class)->parse(rtp); + PurpleXmlNode *description = purple_xmlnode_get_child(rtp, "description"); + const gchar *media_type = purple_xmlnode_get_attrib(description, "media"); + const gchar *ssrc = purple_xmlnode_get_attrib(description, "ssrc"); + purple_debug_info("jingle-rtp", "rtp parse\n"); + g_object_set(content, "media-type", media_type, NULL); + if (ssrc != NULL) + g_object_set(content, "ssrc", ssrc, NULL); + return content; +} + static void jingle_rtp_handle_action_internal(JingleContent *content, PurpleXmlNode *xmlcontent, JingleActionType action) { @@ -802,6 +673,149 @@ } } + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ +static void +jingle_rtp_init (JingleRtp *rtp) +{ +} + +static void +jingle_rtp_finalize (GObject *rtp) +{ + JingleRtpPrivate *priv = jingle_rtp_get_instance_private(JINGLE_RTP(rtp)); + purple_debug_info("jingle-rtp","jingle_rtp_finalize\n"); + + g_free(priv->media_type); + g_free(priv->ssrc); + + G_OBJECT_CLASS(jingle_rtp_parent_class)->finalize(rtp); +} + +static void +jingle_rtp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + JingleRtp *rtp = JINGLE_RTP(object); + JingleRtpPrivate *priv = jingle_rtp_get_instance_private(rtp); + + switch (prop_id) { + case PROP_MEDIA_TYPE: + g_free(priv->media_type); + priv->media_type = g_value_dup_string(value); + break; + case PROP_SSRC: + g_free(priv->ssrc); + priv->ssrc = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_rtp_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + JingleRtp *rtp = JINGLE_RTP(object); + JingleRtpPrivate *priv = jingle_rtp_get_instance_private(rtp); + + switch (prop_id) { + case PROP_MEDIA_TYPE: + g_value_set_string(value, priv->media_type); + break; + case PROP_SSRC: + g_value_set_string(value, priv->ssrc); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +jingle_rtp_class_finalize(JingleRtpClass *klass) { +} + +static void +jingle_rtp_class_init (JingleRtpClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + JingleContentClass *content_class = JINGLE_CONTENT_CLASS(klass); + + obj_class->finalize = jingle_rtp_finalize; + obj_class->set_property = jingle_rtp_set_property; + obj_class->get_property = jingle_rtp_get_property; + + content_class->to_xml = jingle_rtp_to_xml_internal; + content_class->parse = jingle_rtp_parse_internal; + content_class->description_type = JINGLE_APP_RTP; + content_class->handle_action = jingle_rtp_handle_action_internal; + + properties[PROP_MEDIA_TYPE] = g_param_spec_string("media-type", + "Media Type", + "The media type (\"audio\" or \"video\") for this rtp session.", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_SSRC] = g_param_spec_string("ssrc", + "ssrc", + "The ssrc for this rtp session.", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, PROP_LAST, properties); +} + +/****************************************************************************** + * Public API + *****************************************************************************/ +void +jingle_rtp_register(PurplePlugin *plugin) { + jingle_rtp_register_type(G_TYPE_MODULE(plugin)); +} + +gchar * +jingle_rtp_get_media_type(JingleContent *content) +{ + gchar *media_type; + g_object_get(content, "media-type", &media_type, NULL); + return media_type; +} + +gchar * +jingle_rtp_get_ssrc(JingleContent *content) +{ + gchar *ssrc; + g_object_get(content, "ssrc", &ssrc, NULL); + return ssrc; +} + +static PurpleMedia * +jingle_rtp_get_media(JingleSession *session) +{ + JabberStream *js = jingle_session_get_js(session); + PurpleMedia *media = NULL; + GList *iter = purple_media_manager_get_media_by_account( + purple_media_manager_get(), + purple_connection_get_account(js->gc)); + + for (; iter; iter = g_list_delete_link(iter, iter)) { + JingleSession *media_session = + purple_media_get_protocol_data(iter->data); + if (media_session == session) { + media = iter->data; + break; + } + } + if (iter != NULL) + g_list_free(iter); + + return media; +} + gboolean jingle_rtp_initiate_media(JabberStream *js, const gchar *who, PurpleMediaSessionType type) @@ -852,20 +866,30 @@ if (type & PURPLE_MEDIA_AUDIO) { + JingleRtpPrivate *priv = NULL; + transport = jingle_transport_create(transport_type); content = jingle_content_create(JINGLE_APP_RTP, "initiator", "session", "audio-session", "both", transport); + + priv = jingle_rtp_get_instance_private(JINGLE_RTP(content)); + jingle_session_add_content(session, content); - JINGLE_RTP(content)->priv->media_type = g_strdup("audio"); + priv->media_type = g_strdup("audio"); jingle_rtp_init_media(content); g_object_notify_by_pspec(G_OBJECT(content), properties[PROP_MEDIA_TYPE]); } if (type & PURPLE_MEDIA_VIDEO) { + JingleRtpPrivate *priv = NULL; + transport = jingle_transport_create(transport_type); content = jingle_content_create(JINGLE_APP_RTP, "initiator", "session", "video-session", "both", transport); + + priv = jingle_rtp_get_instance_private(JINGLE_RTP(content)); + jingle_session_add_content(session, content); - JINGLE_RTP(content)->priv->media_type = g_strdup("video"); + priv->media_type = g_strdup("video"); jingle_rtp_init_media(content); g_object_notify_by_pspec(G_OBJECT(content), properties[PROP_MEDIA_TYPE]); } @@ -902,4 +926,3 @@ } #endif /* USE_VV */ -
--- a/libpurple/protocols/jabber/jingle/rtp.h Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.h Fri Mar 22 02:42:46 2019 +0000 @@ -49,8 +49,6 @@ typedef struct _JingleRtp JingleRtp; /** @copydoc _JingleRtpClass */ typedef struct _JingleRtpClass JingleRtpClass; -/** @copydoc _JingleRtpPrivate */ -typedef struct _JingleRtpPrivate JingleRtpPrivate; /** The rtp class */ struct _JingleRtpClass @@ -62,7 +60,6 @@ struct _JingleRtp { JingleContent parent; /**< The parent of this object. */ - JingleRtpPrivate *priv; /**< The private data of this object. */ }; /** @@ -75,7 +72,7 @@ /** * Registers the JingleRtp type in the type system. */ -void jingle_rtp_register_type(PurplePlugin *plugin); +void jingle_rtp_register(PurplePlugin *plugin); gchar *jingle_rtp_get_media_type(JingleContent *content); gchar *jingle_rtp_get_ssrc(JingleContent *content);
--- a/libpurple/protocols/jabber/jingle/session.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/session.c Fri Mar 22 02:42:46 2019 +0000 @@ -32,7 +32,7 @@ #include <string.h> -struct _JingleSessionPrivate +typedef struct { gchar *sid; JabberStream *js; @@ -42,15 +42,7 @@ gboolean state; GList *contents; GList *pending_contents; -}; - -#define JINGLE_SESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_SESSION, JingleSessionPrivate)) - -static void jingle_session_class_init (JingleSessionClass *klass); -static void jingle_session_init (JingleSession *session); -static void jingle_session_finalize (GObject *object); -static void jingle_session_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void jingle_session_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +} JingleSessionPrivate; enum { PROP_0, @@ -65,22 +57,207 @@ PROP_LAST }; -static GObjectClass *parent_class = NULL; static GParamSpec *properties[PROP_LAST]; -PURPLE_DEFINE_TYPE(JingleSession, jingle_session, G_TYPE_OBJECT); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + JingleSession, + jingle_session, + G_TYPE_OBJECT, + 0, + G_ADD_PRIVATE_DYNAMIC(JingleSession) +); + +/****************************************************************************** + * Helpers + *****************************************************************************/ +static gboolean find_by_jid_ghr(gpointer key, + gpointer value, gpointer user_data) +{ + JingleSession *session = (JingleSession *)value; + const gchar *jid = user_data; + gboolean use_bare = strchr(jid, '/') == NULL; + gchar *remote_jid = jingle_session_get_remote_jid(session); + gchar *cmp_jid = use_bare ? jabber_get_bare_jid(remote_jid) + : g_strdup(remote_jid); + g_free(remote_jid); + if (purple_strequal(jid, cmp_jid)) { + g_free(cmp_jid); + return TRUE; + } + g_free(cmp_jid); + + return FALSE; +} + +static PurpleXmlNode * +jingle_add_jingle_packet(JingleSession *session, + JabberIq *iq, JingleActionType action) +{ + PurpleXmlNode *jingle = iq ? + purple_xmlnode_new_child(iq->node, "jingle") : + purple_xmlnode_new("jingle"); + gchar *local_jid = jingle_session_get_local_jid(session); + gchar *remote_jid = jingle_session_get_remote_jid(session); + gchar *sid = jingle_session_get_sid(session); + + purple_xmlnode_set_namespace(jingle, JINGLE); + purple_xmlnode_set_attrib(jingle, "action", jingle_get_action_name(action)); + + if (jingle_session_is_initiator(session)) { + purple_xmlnode_set_attrib(jingle, "initiator", local_jid); + purple_xmlnode_set_attrib(jingle, "responder", remote_jid); + } else { + purple_xmlnode_set_attrib(jingle, "initiator", remote_jid); + purple_xmlnode_set_attrib(jingle, "responder", local_jid); + } + + purple_xmlnode_set_attrib(jingle, "sid", sid); + + g_free(local_jid); + g_free(remote_jid); + g_free(sid); + + return jingle; +} + +static JabberIq * +jingle_create_iq(JingleSession *session) +{ + JabberStream *js = jingle_session_get_js(session); + JabberIq *result = jabber_iq_new(js, JABBER_IQ_SET); + gchar *from = jingle_session_get_local_jid(session); + gchar *to = jingle_session_get_remote_jid(session); + + purple_xmlnode_set_attrib(result->node, "from", from); + purple_xmlnode_set_attrib(result->node, "to", to); + + g_free(from); + g_free(to); + return result; +} + +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +static void +jingle_session_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + JingleSession *session = JINGLE_SESSION(object); + JingleSessionPrivate *priv = jingle_session_get_instance_private(session); + + switch (prop_id) { + case PROP_SID: + g_free(priv->sid); + priv->sid = g_value_dup_string(value); + break; + case PROP_JS: + priv->js = g_value_get_pointer(value); + break; + case PROP_REMOTE_JID: + g_free(priv->remote_jid); + priv->remote_jid = g_value_dup_string(value); + break; + case PROP_LOCAL_JID: + g_free(priv->local_jid); + priv->local_jid = g_value_dup_string(value); + break; + case PROP_IS_INITIATOR: + priv->is_initiator = g_value_get_boolean(value); + break; + case PROP_STATE: + priv->state = g_value_get_boolean(value); + break; + case PROP_CONTENTS: + priv->contents = g_value_get_pointer(value); + break; + case PROP_PENDING_CONTENTS: + priv->pending_contents = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_session_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + JingleSession *session = JINGLE_SESSION(object); + JingleSessionPrivate *priv = jingle_session_get_instance_private(session); + + switch (prop_id) { + case PROP_SID: + g_value_set_string(value, priv->sid); + break; + case PROP_JS: + g_value_set_pointer(value, priv->js); + break; + case PROP_REMOTE_JID: + g_value_set_string(value, priv->remote_jid); + break; + case PROP_LOCAL_JID: + g_value_set_string(value, priv->local_jid); + break; + case PROP_IS_INITIATOR: + g_value_set_boolean(value, priv->is_initiator); + break; + case PROP_STATE: + g_value_set_boolean(value, priv->state); + break; + case PROP_CONTENTS: + g_value_set_pointer(value, priv->contents); + break; + case PROP_PENDING_CONTENTS: + g_value_set_pointer(value, priv->pending_contents); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_session_init (JingleSession *session) +{ +} + +static void +jingle_session_finalize (GObject *session) +{ + JingleSessionPrivate *priv = jingle_session_get_instance_private(JINGLE_SESSION(session)); + purple_debug_info("jingle","jingle_session_finalize\n"); + + g_hash_table_remove(priv->js->sessions, priv->sid); + + g_free(priv->sid); + g_free(priv->remote_jid); + g_free(priv->local_jid); + + for (; priv->contents; priv->contents = + g_list_delete_link(priv->contents, priv->contents)) { + g_object_unref(priv->contents->data); + } + for (; priv->pending_contents; priv->pending_contents = + g_list_delete_link(priv->pending_contents, priv->pending_contents)) { + g_object_unref(priv->pending_contents->data); + } + + G_OBJECT_CLASS(jingle_session_parent_class)->finalize(session); +} + +static void +jingle_session_class_finalize (JingleSessionClass *klass) +{ +} static void jingle_session_class_init (JingleSessionClass *klass) { - GObjectClass *gobject_class = (GObjectClass*)klass; - parent_class = g_type_class_peek_parent(klass); + GObjectClass *obj_class = G_OBJECT_CLASS(klass); - gobject_class->finalize = jingle_session_finalize; - gobject_class->set_property = jingle_session_set_property; - gobject_class->get_property = jingle_session_get_property; - - g_type_class_add_private(klass, sizeof(JingleSessionPrivate)); + obj_class->finalize = jingle_session_finalize; + obj_class->set_property = jingle_session_set_property; + obj_class->get_property = jingle_session_get_property; properties[PROP_SID] = g_param_spec_string("sid", "Session ID", @@ -127,126 +304,17 @@ "The pending contents contained within this session", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties(gobject_class, PROP_LAST, properties); -} - -static void -jingle_session_init (JingleSession *session) -{ - session->priv = JINGLE_SESSION_GET_PRIVATE(session); - memset(session->priv, 0, sizeof(*session->priv)); -} - -static void -jingle_session_finalize (GObject *session) -{ - JingleSessionPrivate *priv = JINGLE_SESSION_GET_PRIVATE(session); - purple_debug_info("jingle","jingle_session_finalize\n"); - - g_hash_table_remove(priv->js->sessions, priv->sid); - - g_free(priv->sid); - g_free(priv->remote_jid); - g_free(priv->local_jid); - - for (; priv->contents; priv->contents = - g_list_delete_link(priv->contents, priv->contents)) { - g_object_unref(priv->contents->data); - } - for (; priv->pending_contents; priv->pending_contents = - g_list_delete_link(priv->pending_contents, priv->pending_contents)) { - g_object_unref(priv->pending_contents->data); - } - - parent_class->finalize(session); + g_object_class_install_properties(obj_class, PROP_LAST, properties); } -static void -jingle_session_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - JingleSession *session; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_SESSION(object)); - - session = JINGLE_SESSION(object); - - switch (prop_id) { - case PROP_SID: - g_free(session->priv->sid); - session->priv->sid = g_value_dup_string(value); - break; - case PROP_JS: - session->priv->js = g_value_get_pointer(value); - break; - case PROP_REMOTE_JID: - g_free(session->priv->remote_jid); - session->priv->remote_jid = g_value_dup_string(value); - break; - case PROP_LOCAL_JID: - g_free(session->priv->local_jid); - session->priv->local_jid = g_value_dup_string(value); - break; - case PROP_IS_INITIATOR: - session->priv->is_initiator = g_value_get_boolean(value); - break; - case PROP_STATE: - session->priv->state = g_value_get_boolean(value); - break; - case PROP_CONTENTS: - session->priv->contents = g_value_get_pointer(value); - break; - case PROP_PENDING_CONTENTS: - session->priv->pending_contents = g_value_get_pointer(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +/****************************************************************************** + * Public API + *****************************************************************************/ +void +jingle_session_register(PurplePlugin *plugin) { + jingle_session_register_type(G_TYPE_MODULE(plugin)); } -static void -jingle_session_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - JingleSession *session; - - g_return_if_fail(object != NULL); - g_return_if_fail(JINGLE_IS_SESSION(object)); - - session = JINGLE_SESSION(object); - - switch (prop_id) { - case PROP_SID: - g_value_set_string(value, session->priv->sid); - break; - case PROP_JS: - g_value_set_pointer(value, session->priv->js); - break; - case PROP_REMOTE_JID: - g_value_set_string(value, session->priv->remote_jid); - break; - case PROP_LOCAL_JID: - g_value_set_string(value, session->priv->local_jid); - break; - case PROP_IS_INITIATOR: - g_value_set_boolean(value, session->priv->is_initiator); - break; - case PROP_STATE: - g_value_set_boolean(value, session->priv->state); - break; - case PROP_CONTENTS: - g_value_set_pointer(value, session->priv->contents); - break; - case PROP_PENDING_CONTENTS: - g_value_set_pointer(value, session->priv->pending_contents); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - JingleSession * jingle_session_create(JabberStream *js, const gchar *sid, const gchar *local_jid, const gchar *remote_jid, @@ -351,25 +419,6 @@ return session; } -static gboolean find_by_jid_ghr(gpointer key, - gpointer value, gpointer user_data) -{ - JingleSession *session = (JingleSession *)value; - const gchar *jid = user_data; - gboolean use_bare = strchr(jid, '/') == NULL; - gchar *remote_jid = jingle_session_get_remote_jid(session); - gchar *cmp_jid = use_bare ? jabber_get_bare_jid(remote_jid) - : g_strdup(remote_jid); - g_free(remote_jid); - if (purple_strequal(jid, cmp_jid)) { - g_free(cmp_jid); - return TRUE; - } - g_free(cmp_jid); - - return FALSE; -} - JingleSession * jingle_session_find_by_jid(JabberStream *js, const gchar *jid) { @@ -378,37 +427,6 @@ find_by_jid_ghr, (gpointer)jid) : NULL; } -static PurpleXmlNode * -jingle_add_jingle_packet(JingleSession *session, - JabberIq *iq, JingleActionType action) -{ - PurpleXmlNode *jingle = iq ? - purple_xmlnode_new_child(iq->node, "jingle") : - purple_xmlnode_new("jingle"); - gchar *local_jid = jingle_session_get_local_jid(session); - gchar *remote_jid = jingle_session_get_remote_jid(session); - gchar *sid = jingle_session_get_sid(session); - - purple_xmlnode_set_namespace(jingle, JINGLE); - purple_xmlnode_set_attrib(jingle, "action", jingle_get_action_name(action)); - - if (jingle_session_is_initiator(session)) { - purple_xmlnode_set_attrib(jingle, "initiator", local_jid); - purple_xmlnode_set_attrib(jingle, "responder", remote_jid); - } else { - purple_xmlnode_set_attrib(jingle, "initiator", remote_jid); - purple_xmlnode_set_attrib(jingle, "responder", local_jid); - } - - purple_xmlnode_set_attrib(jingle, "sid", sid); - - g_free(local_jid); - g_free(remote_jid); - g_free(sid); - - return jingle; -} - JabberIq * jingle_session_create_ack(JingleSession *session, const PurpleXmlNode *jingle) { @@ -422,22 +440,6 @@ return result; } -static JabberIq * -jingle_create_iq(JingleSession *session) -{ - JabberStream *js = jingle_session_get_js(session); - JabberIq *result = jabber_iq_new(js, JABBER_IQ_SET); - gchar *from = jingle_session_get_local_jid(session); - gchar *to = jingle_session_get_remote_jid(session); - - purple_xmlnode_set_attrib(result->node, "from", from); - purple_xmlnode_set_attrib(result->node, "to", to); - - g_free(from); - g_free(to); - return result; -} - PurpleXmlNode * jingle_session_to_xml(JingleSession *session, PurpleXmlNode *jingle, JingleActionType action) { @@ -482,12 +484,17 @@ JingleContent * jingle_session_find_content(JingleSession *session, const gchar *name, const gchar *creator) { + JingleSessionPrivate *priv = NULL; GList *iter; + g_return_val_if_fail(JINGLE_IS_SESSION(session), NULL); + if (name == NULL) return NULL; - iter = session->priv->contents; + priv = jingle_session_get_instance_private(session); + + iter = priv->contents; for (; iter; iter = g_list_next(iter)) { JingleContent *content = iter->data; gchar *cname = jingle_content_get_name(content); @@ -509,12 +516,17 @@ JingleContent * jingle_session_find_pending_content(JingleSession *session, const gchar *name, const gchar *creator) { + JingleSessionPrivate *priv = NULL; GList *iter; + g_return_val_if_fail(JINGLE_IS_SESSION(session), NULL); + if (name == NULL) return NULL; - iter = session->priv->pending_contents; + priv = jingle_session_get_instance_private(session); + + iter = priv->pending_contents; for (; iter; iter = g_list_next(iter)) { JingleContent *content = iter->data; gchar *cname = jingle_content_get_name(content); @@ -536,8 +548,13 @@ void jingle_session_add_content(JingleSession *session, JingleContent* content) { - session->priv->contents = - g_list_append(session->priv->contents, content); + JingleSessionPrivate *priv = NULL; + + g_return_if_fail(JINGLE_IS_SESSION(session)); + + priv = jingle_session_get_instance_private(session); + + priv->contents = g_list_append(priv->contents, content); jingle_content_set_session(content, session); g_object_notify_by_pspec(G_OBJECT(session), properties[PROP_CONTENTS]); @@ -546,12 +563,16 @@ void jingle_session_remove_content(JingleSession *session, const gchar *name, const gchar *creator) { - JingleContent *content = - jingle_session_find_content(session, name, creator); + JingleSessionPrivate *priv = NULL; + JingleContent *content = NULL; + + g_return_if_fail(JINGLE_IS_SESSION(session)); + + priv = jingle_session_get_instance_private(session); + content = jingle_session_find_content(session, name, creator); if (content) { - session->priv->contents = - g_list_remove(session->priv->contents, content); + priv->contents = g_list_remove(priv->contents, content); g_object_unref(content); g_object_notify_by_pspec(G_OBJECT(session), properties[PROP_CONTENTS]); @@ -561,8 +582,13 @@ void jingle_session_add_pending_content(JingleSession *session, JingleContent* content) { - session->priv->pending_contents = - g_list_append(session->priv->pending_contents, content); + JingleSessionPrivate *priv = NULL; + + g_return_if_fail(JINGLE_IS_SESSION(session)); + + priv = jingle_session_get_instance_private(session); + + priv->pending_contents = g_list_append(priv->pending_contents, content); jingle_content_set_session(content, session); g_object_notify_by_pspec(G_OBJECT(session), properties[PROP_PENDING_CONTENTS]); @@ -571,11 +597,16 @@ void jingle_session_remove_pending_content(JingleSession *session, const gchar *name, const gchar *creator) { - JingleContent *content = jingle_session_find_pending_content(session, name, creator); + JingleSessionPrivate *priv = NULL; + JingleContent *content = NULL; + + g_return_if_fail(JINGLE_IS_SESSION(session)); + + priv = jingle_session_get_instance_private(session); + content = jingle_session_find_pending_content(session, name, creator); if (content) { - session->priv->pending_contents = - g_list_remove(session->priv->pending_contents, content); + priv->pending_contents = g_list_remove(priv->pending_contents, content); g_object_unref(content); g_object_notify_by_pspec(G_OBJECT(session), properties[PROP_PENDING_CONTENTS]); @@ -585,8 +616,11 @@ void jingle_session_accept_content(JingleSession *session, const gchar *name, const gchar *creator) { - JingleContent *content = jingle_session_find_pending_content(session, name, creator); + JingleContent *content = NULL; + g_return_if_fail(JINGLE_IS_SESSION(session)); + + content = jingle_session_find_pending_content(session, name, creator); if (content) { g_object_ref(content); jingle_session_remove_pending_content(session, name, creator); @@ -597,7 +631,13 @@ void jingle_session_accept_session(JingleSession *session) { - session->priv->state = TRUE; + JingleSessionPrivate *priv = NULL; + + g_return_if_fail(JINGLE_IS_SESSION(session)); + + priv = jingle_session_get_instance_private(session); + + priv->state = TRUE; g_object_notify_by_pspec(G_OBJECT(session), properties[PROP_STATE]); } @@ -605,25 +645,32 @@ JabberIq * jingle_session_terminate_packet(JingleSession *session, const gchar *reason) { - JabberIq *iq = jingle_session_to_packet(session, - JINGLE_SESSION_TERMINATE); - PurpleXmlNode *jingle = purple_xmlnode_get_child(iq->node, "jingle"); + JabberIq *iq = NULL; + + g_return_val_if_fail(JINGLE_IS_SESSION(session), NULL); + + iq = jingle_session_to_packet(session, JINGLE_SESSION_TERMINATE); if (reason != NULL) { PurpleXmlNode *reason_node; + PurpleXmlNode *jingle = purple_xmlnode_get_child(iq->node, "jingle"); reason_node = purple_xmlnode_new_child(jingle, "reason"); purple_xmlnode_new_child(reason_node, reason); } + return iq; } JabberIq * jingle_session_redirect_packet(JingleSession *session, const gchar *sid) { - JabberIq *iq = jingle_session_terminate_packet(session, - "alternative-session"); + JabberIq *iq = NULL; PurpleXmlNode *alt_session; + g_return_val_if_fail(JINGLE_IS_SESSION(session), NULL); + + iq = jingle_session_terminate_packet(session, "alternative-session"); + if (sid == NULL) return iq; @@ -634,6 +681,6 @@ PurpleXmlNode *sid_node = purple_xmlnode_new_child(alt_session, "sid"); purple_xmlnode_insert_data(sid_node, sid, -1); } + return iq; } -
--- a/libpurple/protocols/jabber/jingle/session.h Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/session.h Fri Mar 22 02:42:46 2019 +0000 @@ -44,8 +44,6 @@ typedef struct _JingleSession JingleSession; /** @copydoc _JingleSessionClass */ typedef struct _JingleSessionClass JingleSessionClass; -/** @copydoc _JingleSessionPrivate */ -typedef struct _JingleSessionPrivate JingleSessionPrivate; /** The session class */ struct _JingleSessionClass @@ -57,7 +55,6 @@ struct _JingleSession { GObject parent; /**< The parent of this object. */ - JingleSessionPrivate *priv; /**< The private data of this object. */ }; struct _JingleContent; @@ -72,7 +69,7 @@ /** * Registers the JingleSession type in the type system. */ -void jingle_session_register_type(PurplePlugin *plugin); +void jingle_session_register(PurplePlugin *plugin); JingleSession *jingle_session_create(JabberStream *js, const gchar *sid, const gchar *local_jid, const gchar *remote_jid,
--- a/libpurple/protocols/jabber/jingle/transport.c Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/transport.c Fri Mar 22 02:42:46 2019 +0000 @@ -30,88 +30,66 @@ #include <string.h> -struct _JingleTransportPrivate +G_DEFINE_DYNAMIC_TYPE(JingleTransport, jingle_transport, G_TYPE_OBJECT); + +/****************************************************************************** + * Transport Implementation + *****************************************************************************/ +static JingleTransport * +jingle_transport_parse_internal(PurpleXmlNode *transport) { - void *dummy; -}; + const gchar *type = purple_xmlnode_get_namespace(transport); + return jingle_transport_create(type); +} -#define JINGLE_TRANSPORT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_TRANSPORT, JingleTransportPrivate)) +static void +jingle_transport_add_local_candidate_internal(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) +{ + /* Nothing to do */ +} -static void jingle_transport_class_init (JingleTransportClass *klass); -static void jingle_transport_init (JingleTransport *transport); -static void jingle_transport_finalize (GObject *object); -static void jingle_transport_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void jingle_transport_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -JingleTransport *jingle_transport_parse_internal(PurpleXmlNode *transport); -PurpleXmlNode *jingle_transport_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action); -static void jingle_transport_add_local_candidate_internal(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); -static GList *jingle_transport_get_remote_candidates_internal(JingleTransport *transport); +static PurpleXmlNode * +jingle_transport_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action) +{ + PurpleXmlNode *node = purple_xmlnode_new_child(content, "transport"); + purple_xmlnode_set_namespace(node, jingle_transport_get_transport_type(transport)); + return node; +} -static GObjectClass *parent_class = NULL; +static GList * +jingle_transport_get_remote_candidates_internal(JingleTransport *transport) +{ + return NULL; +} -enum { - PROP_0, -}; +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ +static void +jingle_transport_init (JingleTransport *transport) +{ +} -PURPLE_DEFINE_TYPE(JingleTransport, jingle_transport, G_TYPE_OBJECT); +static void +jingle_transport_class_finalize (JingleTransportClass *klass) +{ +} static void jingle_transport_class_init (JingleTransportClass *klass) { - GObjectClass *gobject_class = (GObjectClass*)klass; - parent_class = g_type_class_peek_parent(klass); - - gobject_class->finalize = jingle_transport_finalize; - gobject_class->set_property = jingle_transport_set_property; - gobject_class->get_property = jingle_transport_get_property; klass->to_xml = jingle_transport_to_xml_internal; klass->parse = jingle_transport_parse_internal; klass->add_local_candidate = jingle_transport_add_local_candidate_internal; klass->get_remote_candidates = jingle_transport_get_remote_candidates_internal; - - g_type_class_add_private(klass, sizeof(JingleTransportPrivate)); -} - -static void -jingle_transport_init (JingleTransport *transport) -{ - transport->priv = JINGLE_TRANSPORT_GET_PRIVATE(transport); - transport->priv->dummy = NULL; -} - -static void -jingle_transport_finalize (GObject *transport) -{ - /* JingleTransportPrivate *priv = JINGLE_TRANSPORT_GET_PRIVATE(transport); */ - purple_debug_info("jingle","jingle_transport_finalize\n"); - - parent_class->finalize(transport); } -static void -jingle_transport_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - g_return_if_fail(G_IS_OBJECT(object)); - g_return_if_fail(JINGLE_IS_TRANSPORT(object)); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -jingle_transport_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - g_return_if_fail(G_IS_OBJECT(object)); - g_return_if_fail(JINGLE_IS_TRANSPORT(object)); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +/****************************************************************************** + * Public API + *****************************************************************************/ +void +jingle_transport_register(PurplePlugin *plugin) { + jingle_transport_register_type(G_TYPE_MODULE(plugin)); } JingleTransport * @@ -134,39 +112,12 @@ generation, candidate); } -void -jingle_transport_add_local_candidate_internal(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) -{ - /* Nothing to do */ -} - GList * jingle_transport_get_remote_candidates(JingleTransport *transport) { return JINGLE_TRANSPORT_GET_CLASS(transport)->get_remote_candidates(transport); } -static GList * -jingle_transport_get_remote_candidates_internal(JingleTransport *transport) -{ - return NULL; -} - -JingleTransport * -jingle_transport_parse_internal(PurpleXmlNode *transport) -{ - const gchar *type = purple_xmlnode_get_namespace(transport); - return jingle_transport_create(type); -} - -PurpleXmlNode * -jingle_transport_to_xml_internal(JingleTransport *transport, PurpleXmlNode *content, JingleActionType action) -{ - PurpleXmlNode *node = purple_xmlnode_new_child(content, "transport"); - purple_xmlnode_set_namespace(node, jingle_transport_get_transport_type(transport)); - return node; -} - JingleTransport * jingle_transport_parse(PurpleXmlNode *transport) { @@ -174,7 +125,7 @@ GType type = jingle_get_type(type_name); if (type == G_TYPE_NONE) return NULL; - + return JINGLE_TRANSPORT_CLASS(g_type_class_ref(type))->parse(transport); } @@ -185,4 +136,3 @@ g_return_val_if_fail(JINGLE_IS_TRANSPORT(transport), NULL); return JINGLE_TRANSPORT_GET_CLASS(transport)->to_xml(transport, content, action); } -
--- a/libpurple/protocols/jabber/jingle/transport.h Fri Mar 22 01:54:47 2019 +0000 +++ b/libpurple/protocols/jabber/jingle/transport.h Fri Mar 22 02:42:46 2019 +0000 @@ -44,8 +44,6 @@ typedef struct _JingleTransport JingleTransport; /** @copydoc _JingleTransportClass */ typedef struct _JingleTransportClass JingleTransportClass; -/** @copydoc _JingleTransportPrivate */ -typedef struct _JingleTransportPrivate JingleTransportPrivate; /** The transport class */ struct _JingleTransportClass @@ -63,7 +61,6 @@ struct _JingleTransport { GObject parent; /**< The parent of this object. */ - JingleTransportPrivate *priv; /**< The private data of this object. */ }; /** @@ -76,7 +73,7 @@ /** * Registers the JingleTransport type in the type system. */ -void jingle_transport_register_type(PurplePlugin *plugin); +void jingle_transport_register(PurplePlugin *plugin); JingleTransport *jingle_transport_create(const gchar *type); const gchar *jingle_transport_get_transport_type(JingleTransport *transport);