/* * Farstream - Farstream Candidate * * Copyright 2007 Collabora Ltd. * @author: Philippe Kalaf * Copyright 2007 Nokia Corp. * * fs-candidate.c - A Farstream candidate * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "fs-candidate.h" /** * SECTION:fs-candidate * @short_description: Structure describing a transport candidate. * * An FsCandidate is a way to exchange candidate information between the client * and Farstream. This description is compatible with ICE-13. It can also be a * multicast address. Candidates are linked to streams. The information * specified in this structure is usually representative of the codec * information exchanged in the signaling. */ GType fs_candidate_get_type (void) { static GType candidate_type = 0; if (candidate_type == 0) { candidate_type = g_boxed_type_register_static ( "FsCandidate", (GBoxedCopyFunc)fs_candidate_copy, (GBoxedFreeFunc)fs_candidate_destroy); } return candidate_type; } GType fs_candidate_list_get_type (void) { static GType candidate_list_type = 0; if (candidate_list_type == 0) { candidate_list_type = g_boxed_type_register_static ( "FsCandidateList", (GBoxedCopyFunc)fs_candidate_list_copy, (GBoxedFreeFunc)fs_candidate_list_destroy); } return candidate_list_type; } /** * fs_candidate_destroy: (skip) * @cand: a #FsCandidate to delete * * Frees a #FsCandidate and all its contents */ void fs_candidate_destroy (FsCandidate * cand) { if (cand == NULL) return; g_free ((gchar *) cand->foundation); g_free ((gchar *) cand->ip); g_free ((gchar *) cand->base_ip); g_free ((gchar *) cand->username); g_free ((gchar *) cand->password); g_slice_free (FsCandidate, cand); } /** * fs_candidate_copy: * @cand: a #FsCandidate to copy * * Copies a #FsCandidate and its contents. * * Returns: a new #FsCandidate */ FsCandidate * fs_candidate_copy (const FsCandidate * cand) { FsCandidate *copy = g_slice_new0 (FsCandidate); if (cand == NULL) return NULL; copy->component_id = cand->component_id; copy->port = cand->port; copy->base_port = cand->base_port; copy->proto = cand->proto; copy->priority = cand->priority; copy->type = cand->type; copy->ttl = cand->ttl; copy->foundation = g_strdup (cand->foundation); copy->ip = g_strdup (cand->ip); copy->base_ip = g_strdup (cand->base_ip); copy->username = g_strdup (cand->username); copy->password = g_strdup (cand->password); return copy; } /** * fs_candidate_list_destroy: (skip) * @candidate_list: A GList of #FsCandidate * * Deletes a GList of #FsCandidate and its contents */ void fs_candidate_list_destroy (GList *candidate_list) { GList *lp; FsCandidate *cand; for (lp = candidate_list; lp; lp = g_list_next (lp)) { cand = (FsCandidate *) lp->data; fs_candidate_destroy (cand); lp->data = NULL; } g_list_free (candidate_list); } /** * fs_candidate_list_copy: * @candidate_list: (element-type FsCodec): A GList of #FsCandidate * * Copies a GList of #FsCandidate and its contents * * Returns: (element-type FsCodec) (transfer full): a new GList of #FsCandidate */ GList * fs_candidate_list_copy (const GList *candidate_list) { GQueue copy = G_QUEUE_INIT; const GList *lp; for (lp = candidate_list; lp; lp = g_list_next (lp)) { FsCandidate *cand = lp->data; g_queue_push_tail (©, fs_candidate_copy (cand)); } return copy.head; } /** * fs_candidate_new: * @foundation: The foundation of the candidate * @component_id: The component this candidate is for * @type: The type of candidate * @proto: The protocol this component is for * @ip: (allow-none): The IP address of this component (can be NULL for local candidate to * mean any address) * @port: the UDP/TCP port * * Allocates a new #FsCandidate, the rest of the fields can be optionally * filled manually. See also fs_candidate_new_full() * * Returns: a newly-allocated #FsCandidate */ FsCandidate * fs_candidate_new ( const gchar *foundation, guint component_id, FsCandidateType type, FsNetworkProtocol proto, const gchar *ip, guint port) { FsCandidate *candidate = g_slice_new0 (FsCandidate); candidate->foundation = g_strdup (foundation); candidate->component_id = component_id; candidate->type = type; candidate->proto = proto; candidate->ip = g_strdup (ip); candidate->port = port; return candidate; } /** * fs_candidate_new_full: * @foundation: The foundation of the candidate * @component_id: The component this candidate is for * @ip: (allow-none): The IP address of this component (can be NULL for local candidate to * mean any address) * @port: the UDP/TCP port * @base_ip: (allow-none): IP of base in dotted format as defined in ICE-19. * @base_port: Port of base as defined in ICE-19. * @proto: The protocol this component is for * @priority: Value between 0 and (2^31 - 1) representing the priority * @type: The type of candidate * @username: (allow-none): Username to use to connect to client if necessary, * NULL otherwise * @password: (allow-none): Username to use to connect to client if necessary, * NULL otherwise * @ttl: The TTL used when sending Multicast packet (0 = auto) * * Allocates a new #FsCandidate, filling all the fields. See also * fs_candidate_new() * * Returns: a newly-allocated #FsCandidate */ FsCandidate * fs_candidate_new_full ( const gchar *foundation, guint component_id, const gchar *ip, guint16 port, const gchar *base_ip, guint16 base_port, FsNetworkProtocol proto, guint32 priority, FsCandidateType type, const gchar *username, const gchar *password, guint ttl) { FsCandidate *candidate = g_slice_new (FsCandidate); candidate->foundation = g_strdup (foundation); candidate->component_id = component_id; candidate->ip = g_strdup (ip); candidate->port = port; candidate->base_ip = g_strdup (base_ip); candidate->base_port = base_port; candidate->proto = proto; candidate->priority = priority; candidate->type = type; candidate->username = g_strdup (username); candidate->password = g_strdup (password); candidate->ttl = ttl; return candidate; } /** * fs_value_set_candidate_list: * @value: a #GValue of type #FS_TYPE_CANDIDATE_LIST * @candidates: (element-type FsCandidate) (allow-none): A #GList of #FsCandidate * * This is for the bindings benefit. Works around the limitations of GObject * introspection. * */ void fs_value_set_candidate_list (GValue *value, GList *candidates) { g_value_init (value, FS_TYPE_CANDIDATE_LIST); g_value_set_boxed (value, candidates); }