static GPtrArray * get_data_forms (WockyNode *node) { GPtrArray *out = g_ptr_array_new_with_free_func (g_object_unref); WockyNodeIter iter; WockyNode *x_node = NULL; wocky_node_iter_init (&iter, node, "x", WOCKY_XMPP_NS_DATA); while (wocky_node_iter_next (&iter, &x_node)) { WockyDataForm *form = wocky_data_form_new_from_node (x_node, NULL); /* we've already parsed the reply to check the hash matches, so * we can already guarantee these data forms will be parsed * fine */ if (G_LIKELY (form != NULL)) g_ptr_array_add (out, form); } return out; }
static void parse_candidates (GabbleJingleTransportIface *obj, WockyNode *transport_node, GError **error) { GabbleJingleTransportGoogle *t = GABBLE_JINGLE_TRANSPORT_GOOGLE (obj); GabbleJingleTransportGooglePrivate *priv = t->priv; GList *candidates = NULL; WockyNodeIter i; WockyNode *node; wocky_node_iter_init (&i, transport_node, "candidate", NULL); while (wocky_node_iter_next (&i, &node)) { const gchar *name, *address, *user, *pass, *str; guint port, net, gen, component; int pref; JingleTransportProtocol proto; JingleCandidateType ctype; JingleCandidate *c; name = wocky_node_get_attribute (node, "name"); if (name == NULL) break; if (!g_hash_table_lookup_extended (priv->component_names, name, NULL, NULL)) { DEBUG ("component name %s unknown to this transport", name); continue; } component = GPOINTER_TO_INT (g_hash_table_lookup (priv->component_names, name)); address = wocky_node_get_attribute (node, "address"); if (address == NULL) break; str = wocky_node_get_attribute (node, "port"); if (str == NULL) break; port = atoi (str); str = wocky_node_get_attribute (node, "protocol"); if (str == NULL) break; if (!wocky_strdiff (str, "udp")) { proto = JINGLE_TRANSPORT_PROTOCOL_UDP; } else if (!wocky_strdiff (str, "tcp")) { /* candiates on port 443 must be "ssltcp" */ if (port == 443) break; proto = JINGLE_TRANSPORT_PROTOCOL_TCP; } else if (!wocky_strdiff (str, "ssltcp")) { /* "ssltcp" must use port 443 */ if (port != 443) break; /* we really don't care about "ssltcp" otherwise */ proto = JINGLE_TRANSPORT_PROTOCOL_TCP; } else { /* unknown protocol */ DEBUG ("unknown protocol: %s", str); break; } str = wocky_node_get_attribute (node, "preference"); if (str == NULL) break; pref = g_ascii_strtod (str, NULL) * 65536; str = wocky_node_get_attribute (node, "type"); if (str == NULL) break; if (!wocky_strdiff (str, "local")) { ctype = JINGLE_CANDIDATE_TYPE_LOCAL; } else if (!wocky_strdiff (str, "stun")) { ctype = JINGLE_CANDIDATE_TYPE_STUN; } else if (!wocky_strdiff (str, "relay")) { ctype = JINGLE_CANDIDATE_TYPE_RELAY; } else { /* unknown candidate type */ DEBUG ("unknown candidate type: %s", str); break; } user = wocky_node_get_attribute (node, "username"); if (user == NULL) break; pass = wocky_node_get_attribute (node, "password"); if (pass == NULL) break; str = wocky_node_get_attribute (node, "network"); if (str == NULL) break; net = atoi (str); str = wocky_node_get_attribute (node, "generation"); if (str == NULL) break; gen = atoi (str); str = wocky_node_get_attribute (node, "component"); if (str != NULL) component = atoi (str); c = jingle_candidate_new (proto, ctype, NULL, component, address, port, gen, pref, user, pass, net); candidates = g_list_append (candidates, c); } if (wocky_node_iter_next (&i, NULL)) { DEBUG ("not all nodes were processed, reporting error"); /* rollback these */ jingle_transport_free_candidates (candidates); g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, "invalid candidate"); return; } DEBUG ("emitting %d new remote candidates", g_list_length (candidates)); g_signal_emit (obj, signals[NEW_CANDIDATES], 0, candidates); /* append them to the known remote candidates */ priv->remote_candidates = g_list_concat (priv->remote_candidates, candidates); }
static gboolean update_location_from_item ( GabbleConnection *conn, TpHandle contact, WockyNode *item_node) { WockyNode *node; GHashTable *location = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( (TpBaseConnection *) conn, TP_HANDLE_TYPE_CONTACT); const gchar *from = tp_handle_inspect (contact_repo, contact); WockyNodeIter i; WockyNode *subloc_node; const gchar *lang; if (item_node == NULL) return FALSE; node = wocky_node_get_child_ns (item_node, "geoloc", NS_GEOLOC); if (node == NULL) return FALSE; DEBUG ("LocationsUpdate for %s:", from); lang = wocky_node_get_language (node); if (lang != NULL) { g_hash_table_insert (location, g_strdup ("language"), tp_g_value_slice_new_string (lang)); } build_mapping_tables (); wocky_node_iter_init (&i, node, NULL, NULL); while (wocky_node_iter_next (&i, &subloc_node)) { GValue *value = NULL; gchar *xmpp_name; const gchar *str; LocationMapping *mapping; xmpp_name = subloc_node->name; str = subloc_node->content; if (str == NULL) continue; mapping = g_hash_table_lookup (xmpp_to_tp, xmpp_name); if (mapping == NULL) { DEBUG ("Unknown location attribute: %s\n", xmpp_name); continue; } if (mapping->type == G_TYPE_DOUBLE) { gdouble double_value; gchar *end; double_value = g_ascii_strtod (str, &end); if (end == str) continue; value = tp_g_value_slice_new_double (double_value); DEBUG ("\t - %s: %f", xmpp_name, double_value); } else if (strcmp (xmpp_name, "timestamp") == 0) { GTimeVal timeval; if (g_time_val_from_iso8601 (str, &timeval)) { value = tp_g_value_slice_new_int64 (timeval.tv_sec); DEBUG ("\t - %s: %s", xmpp_name, str); } else { DEBUG ("\t - %s: %s: unknown date format", xmpp_name, str); continue; } } else if (mapping->type == G_TYPE_STRING) { value = tp_g_value_slice_new_string (str); DEBUG ("\t - %s: %s", xmpp_name, str); } else { g_assert_not_reached (); } g_hash_table_insert (location, g_strdup (mapping->tp_name), value); } tp_svc_connection_interface_location_emit_location_updated (conn, contact, location); gabble_presence_cache_update_location (conn->presence_cache, contact, location); return TRUE; }
static void parse_description (WockyJingleContent *content, WockyNode *desc_node, GError **error) { GabbleJingleShare *self = GABBLE_JINGLE_SHARE (content); GabbleJingleSharePrivate *priv = self->priv; WockyNodeIter i; WockyNode *manifest_node = NULL; WockyNode *protocol_node = NULL; WockyNode *http_node = NULL; WockyNode *node; DEBUG ("parse description called"); if (priv->manifest != NULL) { DEBUG ("Not parsing description, we already have a manifest"); return; } manifest_node = wocky_node_get_child (desc_node, "manifest"); if (manifest_node == NULL) { g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, "description missing <manifest/> node"); return; } protocol_node = wocky_node_get_child (desc_node, "protocol"); if (protocol_node != NULL) http_node = wocky_node_get_child (protocol_node, "http"); free_manifest (self); priv->manifest = g_slice_new0 (GabbleJingleShareManifest); /* Build the manifest */ wocky_node_iter_init (&i, manifest_node, NULL, NULL); while (wocky_node_iter_next (&i, &node)) { WockyNode *name = NULL; WockyNode *image = NULL; gboolean folder; const gchar *size; GabbleJingleShareManifestEntry *m = NULL; if (!wocky_strdiff (node->name, "folder")) folder = TRUE; else if (!wocky_strdiff (node->name, "file")) folder = FALSE; else continue; name = wocky_node_get_child (node, "name"); if (name == NULL) continue; m = g_slice_new0 (GabbleJingleShareManifestEntry); m->folder = folder; m->name = g_strdup (name->content); size = wocky_node_get_attribute (node, "size"); if (size) m->size = g_ascii_strtoull (size, NULL, 10); image = wocky_node_get_child (node, "image"); if (image) { const gchar *width; const gchar *height; m->image = TRUE; width = wocky_node_get_attribute (image, "width"); if (width) m->image_width = g_ascii_strtoull (width, NULL, 10); height =wocky_node_get_attribute (image, "height"); if (height) m->image_height = g_ascii_strtoull (height, NULL, 10); } priv->manifest->entries = g_list_prepend (priv->manifest->entries, m); } /* Get the source and preview url paths from the protocol/http node */ if (http_node != NULL) { /* clear the previously set values */ wocky_node_iter_init (&i, http_node, "url", NULL); while (wocky_node_iter_next (&i, &node)) { const gchar *name = wocky_node_get_attribute (node, "name"); if (name == NULL) continue; if (!wocky_strdiff (name, "source-path")) { const gchar *url = node->content; priv->manifest->source_url = g_strdup (url); } if (!wocky_strdiff (name, "preview-path")) { const gchar *url = node->content; priv->manifest->preview_url = g_strdup (url); } } } /* Build the filename/filesize property values based on the new manifest */ g_free (priv->filename); priv->filename = NULL; priv->filesize = 0; if (g_list_length (priv->manifest->entries) > 0) { if (g_list_length (priv->manifest->entries) == 1) { GabbleJingleShareManifestEntry *m = priv->manifest->entries->data; if (m->folder) priv->filename = g_strdup_printf ("%s.tar", m->name); else priv->filename = g_strdup (m->name); priv->filesize = m->size; } else { GList *li; gchar *temp; priv->filename = g_strdup (""); for (li = priv->manifest->entries; li; li = li->next) { GabbleJingleShareManifestEntry *m = li->data; temp = priv->filename; priv->filename = g_strdup_printf ("%s%s%s%s", temp, m->name, m->folder? ".tar":"", li->next == NULL? "": "-"); g_free (temp); priv->filesize += m->size; } temp = priv->filename; priv->filename = g_strdup_printf ("%s.tar", temp); g_free (temp); } } _wocky_jingle_content_set_media_ready (content); }
static void parse_candidates (WockyJingleTransportIface *obj, WockyNode *transport_node, GError **error) { WockyJingleTransportIceUdp *t = WOCKY_JINGLE_TRANSPORT_ICEUDP (obj); WockyJingleTransportIceUdpPrivate *priv = t->priv; gboolean node_contains_a_candidate = FALSE; GList *candidates = NULL; WockyNodeIter i; WockyNode *node; DEBUG ("called"); wocky_node_iter_init (&i, transport_node, "candidate", NULL); while (wocky_node_iter_next (&i, &node)) { const gchar *id, *address, *user, *pass, *str; guint port, net, gen, component = 1; gdouble pref; WockyJingleTransportProtocol proto; WockyJingleCandidateType ctype; WockyJingleCandidate *c; node_contains_a_candidate = TRUE; id = wocky_node_get_attribute (node, "foundation"); if (id == NULL) { DEBUG ("candidate doesn't contain foundation"); continue; } address = wocky_node_get_attribute (node, "ip"); if (address == NULL) { DEBUG ("candidate doesn't contain ip"); continue; } str = wocky_node_get_attribute (node, "port"); if (str == NULL) { DEBUG ("candidate doesn't contain port"); continue; } port = atoi (str); str = wocky_node_get_attribute (node, "protocol"); if (str == NULL) { DEBUG ("candidate doesn't contain protocol"); continue; } if (!wocky_strdiff (str, "udp")) { proto = WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP; } else { /* unknown protocol */ DEBUG ("unknown protocol: %s", str); continue; } str = wocky_node_get_attribute (node, "priority"); if (str == NULL) { DEBUG ("candidate doesn't contain priority"); continue; } pref = g_ascii_strtod (str, NULL); str = wocky_node_get_attribute (node, "type"); if (str == NULL) { DEBUG ("candidate doesn't contain type"); continue; } if (!wocky_strdiff (str, "host")) { ctype = WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL; } else if (!wocky_strdiff (str, "srflx") || !wocky_strdiff (str, "prflx")) { /* FIXME Strictly speaking a prflx candidate should be a different * type, but the TP spec has now way to distinguish and it doesn't * matter much anyway.. */ ctype = WOCKY_JINGLE_CANDIDATE_TYPE_STUN; } else if (!wocky_strdiff (str, "relay")) { ctype = WOCKY_JINGLE_CANDIDATE_TYPE_RELAY; } else { /* unknown candidate type */ DEBUG ("unknown candidate type: %s", str); continue; } user = wocky_node_get_attribute (transport_node, "ufrag"); if (user == NULL) { DEBUG ("transport doesn't contain ufrag"); continue; } pass = wocky_node_get_attribute (transport_node, "pwd"); if (pass == NULL) { DEBUG ("transport doesn't contain pwd"); continue; } str = wocky_node_get_attribute (node, "network"); if (str == NULL) { DEBUG ("candidate doesn't contain network"); continue; } net = atoi (str); str = wocky_node_get_attribute (node, "generation"); if (str == NULL) { DEBUG ("candidate doesn't contain generation"); continue; } gen = atoi (str); str = wocky_node_get_attribute (node, "component"); if (str == NULL) { DEBUG ("candidate doesn't contain component"); continue; } component = atoi (str); if (priv->ufrag == NULL || strcmp (priv->ufrag, user)) { g_free (priv->ufrag); priv->ufrag = g_strdup (user); } if (priv->pwd == NULL || strcmp (priv->pwd, pass)) { g_free (priv->pwd); priv->pwd = g_strdup (pass); } c = wocky_jingle_candidate_new (proto, ctype, id, component, address, port, gen, pref, user, pass, net); candidates = g_list_append (candidates, c); } if (candidates == NULL) { if (node_contains_a_candidate) { DEBUG_NODE (transport_node, "couldn't parse any of the given candidates"); g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, "could not parse any of the given candidates"); } else { DEBUG ("no candidates in this stanza"); } } else { DEBUG ("emitting %d new remote candidates", g_list_length (candidates)); g_signal_emit (obj, signals[NEW_CANDIDATES], 0, candidates); priv->remote_candidates = g_list_concat (priv->remote_candidates, candidates); } }