[farsight2/master] Add empty implementation of the rawudp transmitter plugin

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:19:22 PST 2008


---
 Makefile.am                                        |    2 +
 configure.ac                                       |   26 ++
 transmitters/Makefile.am                           |    3 +
 transmitters/rawudp/Makefile.am                    |   23 ++
 transmitters/rawudp/fs-rawudp-stream-transmitter.c |  199 ++++++++++++
 transmitters/rawudp/fs-rawudp-stream-transmitter.h |   91 ++++++
 transmitters/rawudp/fs-rawudp-transmitter.c        |  195 +++++++++++
 transmitters/rawudp/fs-rawudp-transmitter.h        |   87 +++++
 transmitters/rawudp/stun.c                         |  343 ++++++++++++++++++++
 transmitters/rawudp/stun.h                         |  129 ++++++++
 10 files changed, 1098 insertions(+), 0 deletions(-)
 create mode 100644 transmitters/Makefile.am
 create mode 100644 transmitters/rawudp/Makefile.am
 create mode 100644 transmitters/rawudp/fs-rawudp-stream-transmitter.c
 create mode 100644 transmitters/rawudp/fs-rawudp-stream-transmitter.h
 create mode 100644 transmitters/rawudp/fs-rawudp-transmitter.c
 create mode 100644 transmitters/rawudp/fs-rawudp-transmitter.h
 create mode 100644 transmitters/rawudp/stun.c
 create mode 100644 transmitters/rawudp/stun.h

diff --git a/Makefile.am b/Makefile.am
index 6a1e1f4..ba5bf09 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,7 @@ SUBDIRS_EXT =
 SUBDIRS = 			\
 	gst-libs 		\
 	gst $(SUBDIRS_EXT)	\
+	transmitters		\
 	tests 			\
 	docs
 #
@@ -15,6 +16,7 @@ SUBDIRS = 			\
 DIST_SUBDIRS = 			\
 	gst-libs		\
 	gst $(SUBDIRS_EXT)	\
+	transmitters		\
 	tests 			\
 	docs
 #
diff --git a/configure.ac b/configure.ac
index 59dbd2c..6f3ec55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -133,6 +133,30 @@ AM_CONDITIONAL(BUILD_EXTERNAL, test "x$BUILD_EXTERNAL" = "xyes")
 
 dnl *** path for our local plugins ***
 
+
+dnl these are all the transmitter plug-ins
+FS2_TRANSMITTER_PLUGINS_ALL=" \
+	rawudp
+	"
+AC_SUBST(FS2_TRANSMITTER_PLUGINS_ALL)
+
+FS2_TRANSMITTER_PLUGINS_SELECTED=""
+
+AC_ARG_WITH(transmitter-plugins,
+    AC_HELP_STRING([--with-transmitter-plugins],
+      [comma-separated list of plug-ins to compile]),
+    [for i in `echo $withval | tr , ' '`; do
+        if echo $FS2_TRANSMITTER_PLUGINS_ALL | grep $i > /dev/null
+        then
+            FS2_TRANSMITTER_PLUGINS_SELECTED="$FS2_TRANSMITTER_PLUGINS_SELECTED $i"
+        else
+            echo "plug-in $i not recognized, ignoring..."
+        fi
+    done],
+    [FS2_TRANSMITTER_PLUGINS_SELECTED=$FS2_TRANSMITTER_PLUGINS_ALL])
+
+AC_SUBST(FS2_TRANSMITTER_PLUGINS_SELECTED)
+
 dnl set the plugindir where plugins should be installed
 AS_AC_EXPAND(FS2_PLUGIN_PATH, ${libdir}/farsight-$FS2_MAJORMINOR)
 AC_SUBST(FS2_PLUGIN_PATH)
@@ -308,6 +332,8 @@ gst/funnel/Makefile
 gst-libs/Makefile
 gst-libs/gst/Makefile
 gst-libs/gst/farsight/Makefile
+transmitters/Makefile
+transmitters/rawudp/Makefile
 dnl pkgconfig/Makefile
 dnl pkgconfig/farsight2.pc
 dnl pkgconfig/farsight2-uninstalled.pc
diff --git a/transmitters/Makefile.am b/transmitters/Makefile.am
new file mode 100644
index 0000000..353b1f0
--- /dev/null
+++ b/transmitters/Makefile.am
@@ -0,0 +1,3 @@
+
+SUBDIRS = $(FS2_TRANSMITTER_PLUGINS_SELECTED)
+DIST_SUBDIRS = $(FS2_TRANMITTER_PLUGINS_ALL)
diff --git a/transmitters/rawudp/Makefile.am b/transmitters/rawudp/Makefile.am
new file mode 100644
index 0000000..b067ca2
--- /dev/null
+++ b/transmitters/rawudp/Makefile.am
@@ -0,0 +1,23 @@
+
+plugindir = $(FS2_PLUGIN_PATH)
+
+plugin_LTLIBRARIES = librawudp-transmitter.la
+
+# sources used to compile this lib
+librawudp_transmitter_la_SOURCES = \
+	fs-rawudp-transmitter.c \
+	fs-rawudp-stream-transmitter.c \
+	stun.c
+
+# flags used to compile this plugin
+librawudp_transmitter_la_CFLAGS = $(FS2_INTERNAL_CFLAGS) $(FS2_CFLAGS) \
+	$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+librawudp_transmitter_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+librawudp_transmitter_la_LIBADD = \
+	$(top_builddir)/gst-libs/gst/farsight/libgstfarsight-0.10.la \
+	$(FS2_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)
+
+noinst_HEADERS = \
+	fs-rawudp-transmitter.h \
+	fs-rawudp-stream-transmitter.h \
+	stun.h
diff --git a/transmitters/rawudp/fs-rawudp-stream-transmitter.c b/transmitters/rawudp/fs-rawudp-stream-transmitter.c
new file mode 100644
index 0000000..79fb7f7
--- /dev/null
+++ b/transmitters/rawudp/fs-rawudp-stream-transmitter.c
@@ -0,0 +1,199 @@
+/*
+ * Farsight2 - Farsight RAW UDP with STUN Transmitter
+ *
+ * Copyright 2007 Collabora Ltd.
+ *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ * Copyright 2007 Nokia Corp.
+ *
+ * fs-rawudp-transmitter.c - A Farsight UDP transmitter with STUN
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+/**
+ * SECTION:fs-stream-transmitter
+ * @short_description: A stream transmitter object for UDP with STUN
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "fs-rawudp-stream-transmitter.h"
+
+#include <gst/gst.h>
+
+/* Signals */
+enum
+{
+  LAST_SIGNAL
+};
+
+/* props */
+enum
+{
+  PROP_0,
+  PROP_SENDING,
+};
+
+struct _FsRawUdpStreamTransmitterPrivate
+{
+  gboolean disposed;
+};
+
+#define FS_RAWUDP_STREAM_TRANSMITTER_GET_PRIVATE(o)  \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_RAWUDP_STREAM_TRANSMITTER, \
+                                FsRawUdpStreamTransmitterPrivate))
+
+static void fs_rawudp_stream_transmitter_class_init (FsRawUdpStreamTransmitterClass *klass);
+static void fs_rawudp_stream_transmitter_init (FsRawUdpStreamTransmitter *self);
+static void fs_rawudp_stream_transmitter_dispose (GObject *object);
+static void fs_rawudp_stream_transmitter_finalize (GObject *object);
+
+static void fs_rawudp_stream_transmitter_get_property (GObject *object,
+                                                guint prop_id,
+                                                GValue *value,
+                                                GParamSpec *pspec);
+static void fs_rawudp_stream_transmitter_set_property (GObject *object,
+                                                guint prop_id,
+                                                const GValue *value,
+                                                GParamSpec *pspec);
+
+static gboolean fs_rawudp_stream_transmitter_add_remote_candidate (
+    FsStreamTransmitter *streamtransmitter, FsCandidate *candidate,
+    GError **error);
+
+
+static GObjectClass *parent_class = NULL;
+// static guint signals[LAST_SIGNAL] = { 0 };
+
+GType
+fs_rawudp_stream_transmitter_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (FsRawUdpStreamTransmitterClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) fs_rawudp_stream_transmitter_class_init,
+      NULL,
+      NULL,
+      sizeof (FsRawUdpStreamTransmitter),
+      0,
+      (GInstanceInitFunc) fs_rawudp_stream_transmitter_init
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT,
+        "FsRawUdpStreamTransmitter", &info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+static void
+fs_rawudp_stream_transmitter_class_init (FsRawUdpStreamTransmitterClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+  FsStreamTransmitterClass *streamtransmitterclass =
+    FS_STREAM_TRANSMITTER_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class->set_property = fs_rawudp_stream_transmitter_set_property;
+  gobject_class->get_property = fs_rawudp_stream_transmitter_get_property;
+
+  streamtransmitterclass->add_remote_candidate =
+    fs_rawudp_stream_transmitter_add_remote_candidate;
+
+  g_object_class_override_property (gobject_class, PROP_SENDING, "sending");
+
+  gobject_class->dispose = fs_rawudp_stream_transmitter_dispose;
+  gobject_class->finalize = fs_rawudp_stream_transmitter_finalize;
+
+  g_type_class_add_private (klass, sizeof (FsRawUdpStreamTransmitterPrivate));
+}
+
+static void
+fs_rawudp_stream_transmitter_init (FsRawUdpStreamTransmitter *self)
+{
+  /* member init */
+  self->priv = FS_RAWUDP_STREAM_TRANSMITTER_GET_PRIVATE (self);
+  self->priv->disposed = FALSE;
+}
+
+static void
+fs_rawudp_stream_transmitter_dispose (GObject *object)
+{
+  FsRawUdpStreamTransmitter *self = FS_RAWUDP_STREAM_TRANSMITTER (object);
+
+  if (self->priv->disposed) {
+    /* If dispose did already run, return. */
+    return;
+  }
+
+  /* Make sure dispose does not run twice. */
+  self->priv->disposed = TRUE;
+
+  parent_class->dispose (object);
+}
+
+static void
+fs_rawudp_stream_transmitter_finalize (GObject *object)
+{
+  parent_class->finalize (object);
+}
+
+static void
+fs_rawudp_stream_transmitter_get_property (GObject *object,
+                                           guint prop_id,
+                                           GValue *value,
+                                           GParamSpec *pspec)
+{
+}
+
+static void
+fs_rawudp_stream_transmitter_set_property (GObject *object,
+                                           guint prop_id,
+                                           const GValue *value,
+                                           GParamSpec *pspec)
+{
+}
+
+
+/**
+ * fs_rawudp_stream_transmitter_add_remote_candidate
+ * @streamtransmitter: a #FsStreamTransmitter
+ * @candidate: a remote #FsCandidate to add
+ * @error: location of a #GError, or NULL if no error occured
+ *
+ * This function is used to add remote candidates to the transmitter
+ *
+ * Returns: TRUE of the candidate could be added, FALSE if it couldnt
+ *   (and the #GError will be set)
+ */
+
+static gboolean
+fs_rawudp_stream_transmitter_add_remote_candidate (
+    FsStreamTransmitter *streamtransmitter, FsCandidate *candidate,
+    GError **error)
+{
+  return FALSE;
+}
+
diff --git a/transmitters/rawudp/fs-rawudp-stream-transmitter.h b/transmitters/rawudp/fs-rawudp-stream-transmitter.h
new file mode 100644
index 0000000..9e3637f
--- /dev/null
+++ b/transmitters/rawudp/fs-rawudp-stream-transmitter.h
@@ -0,0 +1,91 @@
+/*
+ * Farsight2 - Farsight RAW UDP with STUN Stream Transmitter
+ *
+ * Copyright 2007 Collabora Ltd.
+ *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ * Copyright 2007 Nokia Corp.
+ *
+ * fs-stream-transmitter.h - A Farsight UDP stream transmitter with STUN
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __FS_RAWUDP_STREAM_TRANSMITTER_H__
+#define __FS_RAWUDP_STREAM_TRANSMITTER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gst/farsight/fs-stream-transmitter.h>
+
+G_BEGIN_DECLS
+
+/* TYPE MACROS */
+#define FS_TYPE_RAWUDP_STREAM_TRANSMITTER \
+  (fs_rawudp_stream_transmitter_get_type())
+#define FS_RAWUDP_STREAM_TRANSMITTER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_RAWUDP_STREAM_TRANSMITTER, \
+                              FsRawUdpStreamTransmitter))
+#define FS_RAWUDP_STREAM_TRANSMITTER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_RAWUDP_STREAM_TRANSMITTER, \
+                           FsRawUdpStreamTransmitterClass))
+#define FS_IS_RAWUDP_STREAM_TRANSMITTER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_RAWUDP_STREAM_TRANSMITTER))
+#define FS_IS_RAWUDP_STREAM_TRANSMITTER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_RAWUDP_STREAM_TRANSMITTER))
+#define FS_RAWUDP_STREAM_TRANSMITTER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_RAWUDP_STREAM_TRANSMITTER, \
+                              FsRawUdpStreamTransmitterClass))
+#define FS_RAWUDP_STREAM_TRANSMITTER_CAST(obj) ((FsRawUdpStreamTransmitter *) (obj))
+
+typedef struct _FsRawUdpStreamTransmitter FsRawUdpStreamTransmitter;
+typedef struct _FsRawUdpStreamTransmitterClass FsRawUdpStreamTransmitterClass;
+typedef struct _FsRawUdpStreamTransmitterPrivate FsRawUdpStreamTransmitterPrivate;
+
+/**
+ * FsRawUdpStreamTransmitterClass:
+ * @parent_class: Our parent
+ *
+ * The Raw UDP stream transmitter class
+ */
+
+struct _FsRawUdpStreamTransmitterClass
+{
+  FsStreamTransmitter parent_class;
+
+  /*virtual functions */
+  /*< private >*/
+  gpointer _padding[8];
+};
+
+/**
+ * FsRawUdpStreamTransmitter:
+ *
+ * All members are private, access them using methods and properties
+ */
+struct _FsRawUdpStreamTransmitter
+{
+  FsStreamTransmitterClass parent;
+
+  /*< private >*/
+  FsRawUdpStreamTransmitterPrivate *priv;
+  gpointer _padding[8];
+};
+
+GType fs_rawudp_stream_transmitter_get_type (void);
+
+G_END_DECLS
+
+#endif /* __FS_RAWUDP_STREAM_TRANSMITTER_H__ */
diff --git a/transmitters/rawudp/fs-rawudp-transmitter.c b/transmitters/rawudp/fs-rawudp-transmitter.c
new file mode 100644
index 0000000..e93981a
--- /dev/null
+++ b/transmitters/rawudp/fs-rawudp-transmitter.c
@@ -0,0 +1,195 @@
+/*
+ * Farsight2 - Farsight RAW UDP with STUN Transmitter
+ *
+ * Copyright 2007 Collabora Ltd.
+ *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ * Copyright 2007 Nokia Corp.
+ *
+ * fs-rawudp-transmitter.h - A Farsight UDP transmitter with STUN
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/**
+ * SECTION:fs-rawudp-transmitter
+ * @short_description: A transmitter for raw udp (with STUN)
+ *
+ * This transmitter provides RAW udp (with stun)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "fs-rawudp-transmitter.h"
+
+/* Signals */
+enum
+{
+  LAST_SIGNAL
+};
+
+/* props */
+enum
+{
+  PROP_0,
+  PROP_GST_SINK,
+  PROP_GST_SRC,
+};
+
+struct _FsRawUdpTransmitterPrivate
+{
+  gboolean disposed;
+};
+
+#define FS_RAWUDP_TRANSMITTER_GET_PRIVATE(o)  \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_RAWUDP_TRANSMITTER, FsRawUdpTransmitterPrivate))
+
+static void fs_rawudp_transmitter_class_init (FsRawUdpTransmitterClass *klass);
+static void fs_rawudp_transmitter_init (FsRawUdpTransmitter *self);
+static void fs_rawudp_transmitter_dispose (GObject *object);
+static void fs_rawudp_transmitter_finalize (GObject *object);
+
+static void fs_rawudp_transmitter_get_property (GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+static void fs_rawudp_transmitter_set_property (GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+
+static FsStreamTransmitter *fs_rawudp_transmitter_new_stream_transmitter (
+    FsTransmitter *transmitter, FsParticipant *participant);
+
+
+static GObjectClass *parent_class = NULL;
+//static guint signals[LAST_SIGNAL] = { 0 };
+
+GType
+fs_rawudp_transmitter_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (FsRawUdpTransmitterClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) fs_rawudp_transmitter_class_init,
+      NULL,
+      NULL,
+      sizeof (FsRawUdpTransmitter),
+      0,
+      (GInstanceInitFunc) fs_rawudp_transmitter_init
+    };
+
+    type = g_type_register_static (FS_TYPE_TRANSMITTER,
+        "FsRawUdpTransmitter", &info, 0);
+  }
+
+  return type;
+}
+
+static void
+fs_rawudp_transmitter_class_init (FsRawUdpTransmitterClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+  FsTransmitterClass *transmitter_class = FS_TRANSMITTER_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class->set_property = fs_rawudp_transmitter_set_property;
+  gobject_class->get_property = fs_rawudp_transmitter_get_property;
+
+  g_object_class_override_property (gobject_class, PROP_GST_SRC, "gst-src");
+  g_object_class_override_property (gobject_class, PROP_GST_SINK, "gst-sink");
+
+  transmitter_class->new_stream_transmitter =
+    fs_rawudp_transmitter_new_stream_transmitter;
+
+  gobject_class->dispose = fs_rawudp_transmitter_dispose;
+  gobject_class->finalize = fs_rawudp_transmitter_finalize;
+
+  g_type_class_add_private (klass, sizeof (FsRawUdpTransmitterPrivate));
+}
+
+static void
+fs_rawudp_transmitter_init (FsRawUdpTransmitter *self)
+{
+  /* member init */
+  self->priv = FS_RAWUDP_TRANSMITTER_GET_PRIVATE (self);
+  self->priv->disposed = FALSE;
+}
+
+static void
+fs_rawudp_transmitter_dispose (GObject *object)
+{
+  FsRawUdpTransmitter *self = FS_RAWUDP_TRANSMITTER (object);
+
+  if (self->priv->disposed) {
+    /* If dispose did already run, return. */
+    return;
+  }
+
+  /* Make sure dispose does not run twice. */
+  self->priv->disposed = TRUE;
+
+  parent_class->dispose (object);
+}
+
+static void
+fs_rawudp_transmitter_finalize (GObject *object)
+{
+  parent_class->finalize (object);
+}
+
+static void
+fs_rawudp_transmitter_get_property (GObject *object,
+                             guint prop_id,
+                             GValue *value,
+                             GParamSpec *pspec)
+{
+}
+
+static void
+fs_rawudp_transmitter_set_property (GObject *object,
+                             guint prop_id,
+                             const GValue *value,
+                             GParamSpec *pspec)
+{
+}
+
+
+/**
+ * fs_rawudp_transmitter_new_stream_rawudp_transmitter:
+ * @transmitter: a #FsTranmitter
+ * @participant: the #FsParticipant for which the #FsStream using this
+ * new #FsStreamTransmitter is created
+ *
+ * This function will create a new #FsStreamTransmitter element for a
+ * specific participant for this #FsRawUdpTransmitter
+ *
+ * Returns: a new #FsStreamTransmitter
+ */
+
+static FsStreamTransmitter *
+fs_rawudp_transmitter_new_stream_transmitter (FsTransmitter *transmitter,
+  FsParticipant *participant)
+{
+
+  return NULL;
+}
diff --git a/transmitters/rawudp/fs-rawudp-transmitter.h b/transmitters/rawudp/fs-rawudp-transmitter.h
new file mode 100644
index 0000000..7269b16
--- /dev/null
+++ b/transmitters/rawudp/fs-rawudp-transmitter.h
@@ -0,0 +1,87 @@
+/*
+ * Farsight2 - Farsight RAW UDP with STUN Transmitter
+ *
+ * Copyright 2007 Collabora Ltd.
+ *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ * Copyright 2007 Nokia Corp.
+ *
+ * fs-rawudp-transmitter.h - A Farsight UDP transmitter with STUN
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __FS_RAWUDP_TRANSMITTER_H__
+#define __FS_RAWUDP_TRANSMITTER_H__
+
+#include <gst/farsight/fs-transmitter.h>
+
+G_BEGIN_DECLS
+
+/* TYPE MACROS */
+#define FS_TYPE_RAWUDP_TRANSMITTER \
+  (fs_rawudp_transmitter_get_type())
+#define FS_RAWUDP_TRANSMITTER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_RAWUDP_TRANSMITTER, \
+    FsRawUdpTransmitter))
+#define FS_RAWUDP_TRANSMITTER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_RAWUDP_TRANSMITTER, \
+    FsRawUdpTransmitterClass))
+#define FS_IS_RAWUDP_TRANSMITTER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_RAWUDP_TRANSMITTER))
+#define FS_IS_RAWUDP_TRANSMITTER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_RAWUDP_TRANSMITTER))
+#define FS_RAWUDP_TRANSMITTER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_RAWUDP_TRANSMITTER, \
+    FsRawUdpTransmitterClass))
+#define FS_RAWUDP_TRANSMITTER_CAST(obj) ((FsRawUdpTransmitter *) (obj))
+
+typedef struct _FsRawUdpTransmitter FsRawUdpTransmitter;
+typedef struct _FsRawUdpTransmitterClass FsRawUdpTransmitterClass;
+typedef struct _FsRawUdpTransmitterPrivate FsRawUdpTransmitterPrivate;
+
+/**
+ * FsRawUdpTransmitterClass:
+ * @parent_class: Our parent
+ *
+ * The Raw UDP transmitter class
+ */
+
+struct _FsRawUdpTransmitterClass
+{
+  FsTransmitterClass parent_class;
+
+  /*< private >*/
+  gpointer _padding[8];
+};
+
+/**
+ * FsRawUdpTransmitter:
+ *
+ * All members are private, access them using methods and properties
+ */
+struct _FsRawUdpTransmitter
+{
+  FsTransmitter parent;
+
+  /*< private >*/
+  FsRawUdpTransmitterPrivate *priv;
+  gpointer _padding[8];
+};
+
+GType fs_rawudp_transmitter_get_type (void);
+
+G_END_DECLS
+
+#endif /* __FS_RAWUDP_TRANSMITTER_H__ */
diff --git a/transmitters/rawudp/stun.c b/transmitters/rawudp/stun.c
new file mode 100644
index 0000000..1157fd7
--- /dev/null
+++ b/transmitters/rawudp/stun.c
@@ -0,0 +1,343 @@
+#include "stun.h"
+
+#include <string.h>
+
+#ifndef G_OS_WIN32
+#include <arpa/inet.h>
+#else
+#include <winsock2.h>
+#endif
+
+/* round up to multiple of 4 */
+G_GNUC_CONST
+static guint
+ceil4 (guint n)
+{
+  if (n % 4 == 0)
+    return n;
+  else
+    return n + 4 - (n % 4);
+}
+
+G_GNUC_WARN_UNUSED_RESULT
+static StunAttribute *
+stun_attribute_new (guint type)
+{
+  StunAttribute *attr = g_slice_new0 (StunAttribute);
+
+  attr->type = type;
+  return attr;
+}
+
+StunAttribute *
+stun_attribute_mapped_address_new (guint32 ip, guint16 port)
+{
+  StunAttribute *attr = stun_attribute_new (STUN_ATTRIBUTE_MAPPED_ADDRESS);
+
+  attr->length = 8;
+  attr->address.padding = 0;
+  attr->address.af = 1;
+  attr->address.ip = ip;
+  attr->address.port = port;
+  return attr;
+}
+
+StunAttribute *
+stun_attribute_username_new (const gchar *username)
+{
+  StunAttribute *attr;
+
+  attr = stun_attribute_new (STUN_ATTRIBUTE_USERNAME);
+  g_assert (strlen (username) < sizeof (attr->username));
+  attr->length = strlen (username);
+  strcpy (attr->username, username);
+  return attr;
+}
+
+void
+stun_attribute_free (StunAttribute *attr)
+{
+  g_slice_free (StunAttribute, attr);
+}
+
+G_GNUC_WARN_UNUSED_RESULT
+static gboolean
+_stun_attribute_unpack (StunAttribute *attr, guint length, const gchar *s)
+{
+  guint type;
+
+  if (length < 4)
+    /* must start with 16 bit type, 16 bit length */
+    return FALSE;
+
+  type = ntohs (*(guint16 *) s);
+
+  switch (type)
+    {
+      case STUN_ATTRIBUTE_MAPPED_ADDRESS:
+        if (length != 12)
+          return FALSE;
+
+        attr->address.af = (guint8) s[5];
+        g_assert (attr->address.af == 1);
+        attr->address.port = ntohs (*(guint16 *)(s + 6));
+        attr->address.ip = ntohl (*(guint32 *)(s + 8));
+        break;
+
+      case STUN_ATTRIBUTE_USERNAME:
+      case STUN_ATTRIBUTE_PASSWORD:
+        if (length - 4 > sizeof (attr->username) / sizeof (gchar))
+          return FALSE;
+
+        attr->length = length - 4;
+
+        if (type == STUN_ATTRIBUTE_USERNAME)
+          memcpy (attr->username, s + 4, attr->length);
+        else
+          memcpy (attr->password, s + 4, attr->length);
+        break;
+
+      default:
+        /* unknown attribute; we can only unpack the type */
+        break;
+    }
+
+  attr->type = type;
+  return TRUE;
+}
+
+StunAttribute *
+stun_attribute_unpack (guint length, const gchar *s)
+{
+  StunAttribute *attr;
+
+  attr = stun_attribute_new (0);
+
+  if (_stun_attribute_unpack (attr, length, s))
+    return attr;
+
+  stun_attribute_free (attr);
+  return NULL;
+}
+
+guint
+stun_attribute_pack (StunAttribute *attr, gchar **packed)
+{
+  switch (attr->type)
+    {
+      case STUN_ATTRIBUTE_MAPPED_ADDRESS:
+        {
+          if (packed != NULL)
+            {
+              StunAttribute *ret = g_malloc0 (sizeof (StunAttribute));
+
+              ret->type = htons (attr->type);
+              ret->length = htons (8);
+              ret->address.af = attr->address.af;
+              ret->address.port = htons (attr->address.port);
+              ret->address.ip = htonl (attr->address.ip);
+              *packed = (gchar *) ret;
+            }
+
+          return 12;
+        }
+
+      case STUN_ATTRIBUTE_USERNAME:
+        {
+          if (packed != NULL)
+            {
+              StunAttribute *ret = g_malloc0 (sizeof (StunAttribute));
+
+              ret->type = htons (attr->type);
+              ret->length = htons (attr->length);
+              memcpy (ret->username, attr->username, attr->length);
+              *packed = (gchar *) ret;
+            }
+
+          return ceil4 (4 + attr->length);
+        }
+
+      default:
+        return 0;
+  }
+}
+
+gchar *
+stun_attribute_dump (StunAttribute *attr)
+{
+  switch (attr->type)
+    {
+      case STUN_ATTRIBUTE_MAPPED_ADDRESS:
+        return g_strdup_printf (
+          "MAPPED-ADDRESS %d.%d.%d.%d:%d",
+            (attr->address.ip & 0xff000000) >> 24,
+            (attr->address.ip & 0x00ff0000) >> 16,
+            (attr->address.ip & 0x0000ff00) >>  8,
+            (attr->address.ip & 0x000000ff) >>  0,
+            attr->address.port);
+      case STUN_ATTRIBUTE_USERNAME:
+        return g_strdup_printf (
+          "USERNAME \"%*s\"", attr->length, attr->username);
+      default:
+        return g_strdup_printf ("UNKNOWN (%d)", attr->type);
+    }
+}
+
+void
+stun_message_init (StunMessage *msg, guint type, const gchar *id)
+{
+  msg->type = type;
+
+  if (id != NULL)
+    memcpy (msg->transaction_id, id, 16);
+}
+
+StunMessage *
+stun_message_new (guint type, const gchar *id, guint n_attributes)
+{
+  StunMessage *msg = g_slice_new0 (StunMessage);
+
+  stun_message_init (msg, type, id);
+
+  if (n_attributes != 0)
+    msg->attributes = g_malloc0 (
+        (n_attributes + 1) * sizeof (StunAttribute *));
+
+  return msg;
+}
+
+void
+stun_message_free (StunMessage *msg)
+{
+  StunAttribute **attr;
+
+  if (msg->attributes)
+    {
+      for (attr = msg->attributes; *attr; attr++)
+        stun_attribute_free (*attr);
+
+      g_free (msg->attributes);
+    }
+
+  g_slice_free (StunMessage, msg);
+}
+
+StunMessage *
+stun_message_unpack (guint length, const gchar *s)
+{
+  guint attr_length;
+  guint n_attributes = 0;
+  guint i;
+  guint offset;
+  StunAttribute *attr;
+  StunMessage *msg;
+
+  /* message header is 20 bytes */
+
+  if (length < 20)
+    return NULL;
+
+  /* count the number of attributes */
+
+  for (offset = 20; offset < length; offset += attr_length)
+    {
+      attr_length = ceil4 (4 + ntohs (*(guint16 *)(s + offset + 2)));
+      n_attributes++;
+    }
+
+  /* create message structure */
+
+  msg = stun_message_new (ntohs (*(guint16 *) s), s + 4, n_attributes);
+
+  /* unpack attributes */
+
+  for (i = 0, offset = 20; i < n_attributes; i++, offset += attr_length)
+    {
+      attr_length = 4 + ntohs (*(guint16 *)(s + offset + 2));
+      attr = msg->attributes[i] = stun_attribute_unpack (attr_length,
+          s + offset);
+      attr_length = ceil4 (attr_length);
+    }
+
+  return msg;
+}
+
+guint
+stun_message_pack (StunMessage *msg, gchar **packed)
+{
+  gchar *tmp;
+  guint length = 0;
+
+  if (msg->attributes)
+    {
+      StunAttribute **attr;
+
+      for (attr = msg->attributes; *attr; attr++)
+        length += stun_attribute_pack (*attr, NULL);
+    }
+
+  g_assert (length % 4 == 0);
+  tmp = g_malloc0 (length + 20);
+  *(guint16 *) (tmp + 0) = htons (msg->type);
+  *(guint16 *) (tmp + 2) = htons (length);
+  memcpy (tmp + 4, msg->transaction_id, 16);
+
+  if (msg->attributes)
+    {
+      StunAttribute **attr;
+      gchar *pos = tmp + 20;
+
+      for (attr = msg->attributes; *attr; attr++)
+        {
+          gchar *attr_packed;
+          guint attr_length = stun_attribute_pack (*attr, &attr_packed);
+          memcpy (pos, attr_packed, attr_length);
+          g_free (attr_packed);
+          pos += attr_length;
+        }
+    }
+
+  *packed = tmp;
+  return length + 20;
+}
+
+gchar *
+stun_message_dump (StunMessage *msg)
+{
+  StunAttribute **attr;
+  GString *tmp = g_string_new ("");
+  const gchar *name;
+
+  switch (msg->type) {
+    case STUN_MESSAGE_BINDING_REQUEST:
+      name = "BINDING-REQUEST";
+      break;
+    case STUN_MESSAGE_BINDING_RESPONSE:
+      name = "BINDING-RESPONSE";
+      break;
+    case STUN_MESSAGE_BINDING_ERROR_RESPONSE:
+      name = "BINDING-ERROR-RESPONSE";
+      break;
+    default:
+      name = "(UNKNOWN)";
+  }
+
+  g_string_printf (tmp,
+    "%s %08x:%08x:%08x:%08x\n",
+      name,
+      ntohl (*(guint32 *)(msg->transaction_id)),
+      ntohl (*(guint32 *)(msg->transaction_id + 4)),
+      ntohl (*(guint32 *)(msg->transaction_id + 8)),
+      ntohl (*(guint32 *)(msg->transaction_id + 12)));
+
+  if (msg->attributes)
+    for (attr = msg->attributes; *attr; attr++)
+      {
+          gchar *dump = stun_attribute_dump (*attr);
+          g_string_append_printf (tmp, "  %s\n", dump);
+          g_free (dump);
+      }
+
+  return g_string_free (tmp, FALSE);
+}
+
diff --git a/transmitters/rawudp/stun.h b/transmitters/rawudp/stun.h
new file mode 100644
index 0000000..87f00f8
--- /dev/null
+++ b/transmitters/rawudp/stun.h
@@ -0,0 +1,129 @@
+
+#ifndef __STUN_H__
+#define __STUN_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+  STUN_MESSAGE_BINDING_REQUEST              = 0x001,
+  STUN_MESSAGE_BINDING_RESPONSE             = 0x101,
+  STUN_MESSAGE_BINDING_ERROR_RESPONSE       = 0x111,
+  STUN_MESSAGE_SHARED_SECRET_REQUEST        = 0x002,
+  STUN_MESSAGE_SHARED_SECRET_RESPONSE       = 0x102,
+  STUN_MESSAGE_SHARED_SECRET_ERROR_RESPONSE = 0x112
+} StunMessageType;
+
+/* a = defined by RFC 3489
+ * b = defined by RFC 3489bis
+ * c = defined by draft-ietf-behave-turn-02
+ */
+
+typedef enum
+{
+  // mandatory parameters (<= 0x7fff)
+  STUN_ATTRIBUTE_MAPPED_ADDRESS       = 0x0001, // ab
+  STUN_ATTRIBUTE_RESPONSE_ADDRESS     = 0x0002, // a
+  STUN_ATTRIBUTE_CHANGE_REQUEST       = 0x0003, // a
+  STUN_ATTRIBUTE_CHANGED_ADDRESS      = 0x0004, // a
+  STUN_ATTRIBUTE_SOURCE_ADDRESS       = 0x0005, // a
+  STUN_ATTRIBUTE_USERNAME             = 0x0006, // ab
+  STUN_ATTRIBUTE_PASSWORD             = 0x0007, // ab
+  STUN_ATTRIBUTE_MESSAGE_INTEGRITY    = 0x0008, // ab
+  STUN_ATTRIBUTE_ERROR_CODE           = 0x0009, // ab
+  STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES   = 0x000a, // ab
+  STUN_ATTRIBUTE_REFLECTED_FROM       = 0x000b, // a
+  STUN_ATTRIBUTE_REALM                = 0x0014, //  b
+  STUN_ATTRIBUTE_NONCE                = 0x0015, //  b
+  STUN_ATTRIBUTE_LIFETIME             = 0x000D, //   c
+  STUN_ATTRIBUTE_BANDWIDTH            = 0x0010, //   c
+  STUN_ATTRIBUTE_REMOTE_ADDRESS       = 0x0012, //   c
+  STUN_ATTRIBUTE_DATA                 = 0x0013, //   c
+  STUN_ATTRIBUTE_RELAY_ADDRESS        = 0x0016, //   c
+  STUN_ATTRIBUTE_REQUESTED_PORT_PROPS = 0x0018, //   c
+  STUN_ATTRIBUTE_REQUESTED_TRANSPORT  = 0x0019, //   c
+  STUN_ATTRIBUTE_REQUESTED_IP         = 0x0022, //   c
+  STUN_ATTRIBUTE_TIMER_VAL            = 0x0021, //   c
+  // optional parameters (> 0x7fff)
+  STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS   = 0x8020, //  b
+  STUN_ATTRIBUTE_FINGERPRINT          = 0x8023, //  b
+  STUN_ATTRIBUTE_SERVER               = 0x8022, //  b
+  SUTN_ATTRIBUTE_ALTERNATE_SERVER     = 0x8023, //  b
+  STUN_ATTRIBUTE_REFRESH_INTERVAL     = 0x8024, //  b
+} StunAttributeType;
+
+typedef struct _StunAttribute StunAttribute;
+
+struct _StunAttribute {
+  guint16 type;
+  guint16 length;
+  union {
+    struct {
+      guint8 padding;
+      guint8 af;
+      guint16 port;
+      guint32 ip;
+    } address;
+    gchar username[128];
+    gchar password[128];
+  };
+};
+
+typedef struct _StunMessage StunMessage;
+
+struct _StunMessage {
+  guint16 type;
+  gchar transaction_id[16];
+  StunAttribute **attributes;
+};
+
+G_GNUC_WARN_UNUSED_RESULT
+StunAttribute *
+stun_attribute_mapped_address_new (guint32 ip_address, guint16 port);
+
+StunAttribute *
+stun_attribute_username_new (const gchar *username);
+
+void
+stun_attribute_free (StunAttribute *attr);
+
+G_GNUC_WARN_UNUSED_RESULT
+guint
+stun_attribute_pack (StunAttribute *attr, gchar **ret);
+
+G_GNUC_WARN_UNUSED_RESULT
+gchar *
+stun_attribute_dump (StunAttribute *attr);
+
+G_GNUC_WARN_UNUSED_RESULT
+StunAttribute *
+stun_attribute_unpack (guint length, const gchar *s);
+
+void
+stun_message_init (StunMessage *msg, guint type, const gchar *id);
+
+G_GNUC_WARN_UNUSED_RESULT
+StunMessage *
+stun_message_new (guint type, const gchar *id, guint n_attributes);
+
+void
+stun_message_free (StunMessage *msg);
+G_GNUC_WARN_UNUSED_RESULT
+
+guint
+stun_message_pack (StunMessage *msg, gchar **packed);
+G_GNUC_WARN_UNUSED_RESULT
+
+gchar *
+stun_message_dump (StunMessage *msg);
+G_GNUC_WARN_UNUSED_RESULT
+
+StunMessage *
+stun_message_unpack (guint length, const gchar *s);
+
+G_END_DECLS
+
+#endif /* __STUN_H__ */
+
-- 
1.5.6.5




More information about the farsight-commits mailing list