+2005-11-16 Andy Wingo <wingo@pobox.com>
+
+ * gst/net/Makefile.am:
+ * gst/net/gstnet.h:
+ * gst/net/gstnettimeprovider.c:
+ * gst/net/gstnettimeprovider.h: Use the timepacket stuff in the
+ provider, include it from gstnet.h, and add it to the build.
+
+ * gst/net/gstnettimepacket.h:
+ * gst/net/gstnettimepacket.c: New files, abstracts out the packet
+ sending and receiving.
+
2005-11-16 Wim Taymans <wim@fluendo.com>
* check/Makefile.am:
GST_END_TEST;
+#if 0
+GST_START_TEST (test_functioning)
+{
+ GstNetTimeProvider *ntp;
+ GstClock *clock;
+
+ clock = gst_system_clock_obtain ();
+ fail_unless (clock != NULL, "failed to get system clock");
+ ntp = gst_net_time_provider_new (clock, NULL, -1);
+ fail_unless (ntp != NULL, "failed to create net time provider");
+
+
+
+ gst_object_unref (ntp);
+ gst_object_unref (clock);
+}
+
+GST_END_TEST;
+#endif
+
Suite *
gst_net_time_provider_suite (void)
{
libgstnet_tempname_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/net
libgstnet_tempname_@GST_MAJORMINOR@_include_HEADERS = \
gstnet.h \
+ gstnettimepacker.h \
gstnettimeprovider.h
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
+ gstnettimepacket.c \
gstnettimeprovider.c
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
#define __GST_NET_H__
+#include <gst/net/gstnettimepacket.h>
#include <gst/net/gstnettimeprovider.h>
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstnettimepacket.h"
+
+
+/**
+ * gst_net_time_packet_new:
+ * @buffer: a buffer from which to construct the packet, or NULL
+ *
+ * Creates a new #GstNetTimePacket from a buffer received over the network. The
+ * caller is responsible for ensuring that @buffer is at least
+ * #GST_NET_TIME_PACKET_SIZE bytes long.
+ *
+ * If @buffer is #NULL, the local and remote times will be set to
+ * #GST_CLOCK_TIME_NONE.
+ *
+ * MT safe. Caller owns return value (g_free to free).
+ *
+ * Returns: The new #GstNetTimePacket.
+ */
+GstNetTimePacket *
+gst_net_time_packet_new (const guint8 * buffer)
+{
+ GstNetTimePacket *ret;
+
+ g_assert (sizeof (GstClockTime) == 8);
+
+ ret = g_new0 (GstNetTimePacket, 1);
+
+ if (buffer) {
+ ret->local_time = GST_READ_UINT64_BE (buffer);
+ ret->remote_time = GST_READ_UINT64_BE (buffer + sizeof (GstClockTime));
+ } else {
+ ret->local_time = GST_CLOCK_TIME_NONE;
+ ret->remote_time = GST_CLOCK_TIME_NONE;
+ }
+
+ return ret;
+}
+
+/**
+ * gst_net_time_packet_serialize:
+ * @packet: the #GstNetTimePacket
+ *
+ * Serialized a #GstNetTimePacket into a newly-allocated sequence of
+ * #GST_NET_TIME_PACKET_SIZE bytes, in network byte order. The value returned is
+ * suitable for passing to write(2) or sendto(2) for communication over the
+ * network.
+ *
+ * MT safe. Caller owns return value (g_free to free).
+ *
+ * Returns: A newly allocated sequence of #GST_NET_TIME_PACKET_SIZE bytes.
+ */
+guint8 *
+gst_net_time_packet_serialize (const GstNetTimePacket * packet)
+{
+ guint8 *ret;
+
+ g_assert (sizeof (GstClockTime) == 8);
+
+ ret = g_new0 (guint8, GST_NET_TIME_PACKET_SIZE);
+
+ GST_WRITE_UINT64_BE (ret, packet->local_time);
+ GST_WRITE_UINT64_BE (ret + sizeof (GstClockTime), packet->remote_time);
+
+ return ret;
+}
+
+/**
+ * gst_net_time_packet_receive:
+ * @sockfd: a file descriptor created by socket(2)
+ * @addr: a pointer to a sockaddr to hold the address of the sender
+ * @len: a pointer to the size of the data pointed to by @addr
+ *
+ * Receives a #GstNetTimePacket over a socket. Handles interrupted system calls,
+ * but otherwise returns NULL on error. See recvfrom(2) for more information on
+ * how to interpret @sockaddr.
+ *
+ * MT safe. Caller owns return value (g_free to free).
+ *
+ * Returns: The new #GstNetTimePacket.
+ */
+GstNetTimePacket *
+gst_net_time_packet_receive (gint fd, struct sockaddr * addr, socklen_t * len)
+{
+ guint8 buffer[GST_NET_TIME_PACKET_SIZE];
+ gint ret;
+
+ while (TRUE) {
+ ret = recvfrom (fd, buffer, GST_NET_TIME_PACKET_SIZE,
+ 0, (struct sockaddr *) addr, len);
+ if (ret < 0) {
+ if (errno != EAGAIN && errno != EINTR)
+ goto receive_error;
+ else
+ continue;
+ } else if (ret < GST_NET_TIME_PACKET_SIZE) {
+ goto short_packet;
+ } else {
+ return gst_net_time_packet_new (buffer);
+ }
+ }
+
+receive_error:
+ {
+ GST_DEBUG ("receive error %d: %s (%d)", ret, g_strerror (errno), errno);
+ return NULL;
+ }
+short_packet:
+ {
+ GST_DEBUG ("someone sent us a short packet (%d < %d)",
+ ret, GST_NET_TIME_PACKET_SIZE);
+ return NULL;
+ }
+}
+
+/**
+ * gst_net_time_packet_send:
+ * @packet: the #GstNetTimePacket
+ * @sockfd: a file descriptor created by socket(2)
+ * @addr: a pointer to a sockaddr to hold the address of the sender
+ * @len: the size of the data pointed to by @addr
+ *
+ * Sends a #GstNetTimePacket over a socket. Essentially a thin wrapper around
+ * sendto(2) and gst_net_time_packet_serialize().
+ *
+ * MT safe.
+ *
+ * Returns: The return value of sendto(2).
+ */
+gint
+gst_net_time_packet_send (const GstNetTimePacket * packet, gint fd,
+ struct sockaddr * addr, socklen_t len)
+{
+ guint8 *buffer;
+ gint ret;
+
+ g_return_val_if_fail (packet != NULL, -EINVAL);
+
+ buffer = gst_net_time_packet_serialize (packet);
+
+ ret = sendto (fd, buffer, GST_NET_TIME_PACKET_SIZE, MSG_DONTWAIT, addr, len);
+
+ return ret;
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_NET_TIME_PACKET_H__
+#define __GST_NET_TIME_PACKET_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define GST_NET_TIME_PACKET_SIZE 16
+
+typedef struct _GstNetTimePacket GstNetTimePacket;
+
+struct _GstNetTimePacket {
+ GstClockTime local_time;
+ GstClockTime remote_time;
+};
+
+GstNetTimePacket* gst_net_time_packet_new (const guint8 *buffer);
+guint8* gst_net_time_packet_serialize (const GstNetTimePacket *packet);
+
+GstNetTimePacket* gst_net_time_packet_receive (gint fd, struct sockaddr *addr,
+ socklen_t *len);
+gint gst_net_time_packet_send (const GstNetTimePacket *packet,
+ gint fd, struct sockaddr *addr,
+ socklen_t len);
+
+G_END_DECLS
+
+
+#endif /* __GST_NET_TIME_PACKET_H__ */
#endif
#include "gstnettimeprovider.h"
+#include "gstnettimepacket.h"
+
#include <unistd.h>
#include <sys/ioctl.h>
#define DEFAULT_ADDRESS "0.0.0.0"
#define DEFAULT_PORT 5637
-typedef struct
-{
- GstClockTime slave_time_sent;
- GstClockTime master_time_received;
-} NetworkTimePacket;
-
- /* 2 * sizeof(GstClockTime), verified in base_init */
-#define NETWORK_TIME_PACKET_SIZE 16
-#define NETWORK_TIME_PACKET_SET_MASTER_TIME(p, t) \
- GST_WRITE_UINT64_BE(p+8, t)
-
enum
{
PROP_0,
socklen_t len;
fd_set read_fds;
guint max_sock;
- gchar *pktdata;
+ GstNetTimePacket *packet;
gint ret;
while (TRUE) {
continue;
} else {
/* got data in */
- pktdata = g_malloc (NETWORK_TIME_PACKET_SIZE);
-
len = sizeof (struct sockaddr);
- while (TRUE) {
- ret = recvfrom (self->sock, pktdata, NETWORK_TIME_PACKET_SIZE,
- 0, (struct sockaddr *) &tmpaddr, &len);
- if (ret < 0) {
- if (errno != EAGAIN && errno != EINTR)
- goto receive_error;
- else
- continue;
- } else if (ret < NETWORK_TIME_PACKET_SIZE) {
- goto short_packet;
- } else {
- GstClockTime now;
- now = gst_clock_get_time (self->clock);
+ packet = gst_net_time_packet_receive (self->sock,
+ (struct sockaddr *) &tmpaddr, &len);
- NETWORK_TIME_PACKET_SET_MASTER_TIME (pktdata, time);
+ if (!packet)
+ goto receive_error;
- /* ignore errors */
- sendto (self->sock, pktdata, ret, MSG_DONTWAIT,
- (struct sockaddr *) &tmpaddr, len);
+ /* do what we were asked to and send the packet back */
+ packet->remote_time = gst_clock_get_time (self->clock);
- break;
- }
+ /* ignore errors */
+ gst_net_time_packet_send (packet, self->sock,
+ (struct sockaddr *) &tmpaddr, len);
- g_assert_not_reached ();
- }
+ g_free (packet);
continue;
}
g_strerror (errno), errno);
continue;
}
- short_packet:
- {
- GST_DEBUG_OBJECT (self, "someone sent us a short packet (%d < %d)",
- ret, NETWORK_TIME_PACKET_SIZE);
- continue;
- }
stopped:
{
GST_DEBUG_OBJECT (self, "shutting down");
}
receive_error:
{
- g_free (pktdata);
- GST_DEBUG_OBJECT (self, "receive error %d: %s (%d)", ret,
- g_strerror (errno), errno);
+ GST_DEBUG_OBJECT (self, "receive error");
continue;
}
libgstnet_tempname_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/net
libgstnet_tempname_@GST_MAJORMINOR@_include_HEADERS = \
gstnet.h \
+ gstnettimepacker.h \
gstnettimeprovider.h
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
+ gstnettimepacket.c \
gstnettimeprovider.c
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
#define __GST_NET_H__
+#include <gst/net/gstnettimepacket.h>
#include <gst/net/gstnettimeprovider.h>
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstnettimepacket.h"
+
+
+/**
+ * gst_net_time_packet_new:
+ * @buffer: a buffer from which to construct the packet, or NULL
+ *
+ * Creates a new #GstNetTimePacket from a buffer received over the network. The
+ * caller is responsible for ensuring that @buffer is at least
+ * #GST_NET_TIME_PACKET_SIZE bytes long.
+ *
+ * If @buffer is #NULL, the local and remote times will be set to
+ * #GST_CLOCK_TIME_NONE.
+ *
+ * MT safe. Caller owns return value (g_free to free).
+ *
+ * Returns: The new #GstNetTimePacket.
+ */
+GstNetTimePacket *
+gst_net_time_packet_new (const guint8 * buffer)
+{
+ GstNetTimePacket *ret;
+
+ g_assert (sizeof (GstClockTime) == 8);
+
+ ret = g_new0 (GstNetTimePacket, 1);
+
+ if (buffer) {
+ ret->local_time = GST_READ_UINT64_BE (buffer);
+ ret->remote_time = GST_READ_UINT64_BE (buffer + sizeof (GstClockTime));
+ } else {
+ ret->local_time = GST_CLOCK_TIME_NONE;
+ ret->remote_time = GST_CLOCK_TIME_NONE;
+ }
+
+ return ret;
+}
+
+/**
+ * gst_net_time_packet_serialize:
+ * @packet: the #GstNetTimePacket
+ *
+ * Serialized a #GstNetTimePacket into a newly-allocated sequence of
+ * #GST_NET_TIME_PACKET_SIZE bytes, in network byte order. The value returned is
+ * suitable for passing to write(2) or sendto(2) for communication over the
+ * network.
+ *
+ * MT safe. Caller owns return value (g_free to free).
+ *
+ * Returns: A newly allocated sequence of #GST_NET_TIME_PACKET_SIZE bytes.
+ */
+guint8 *
+gst_net_time_packet_serialize (const GstNetTimePacket * packet)
+{
+ guint8 *ret;
+
+ g_assert (sizeof (GstClockTime) == 8);
+
+ ret = g_new0 (guint8, GST_NET_TIME_PACKET_SIZE);
+
+ GST_WRITE_UINT64_BE (ret, packet->local_time);
+ GST_WRITE_UINT64_BE (ret + sizeof (GstClockTime), packet->remote_time);
+
+ return ret;
+}
+
+/**
+ * gst_net_time_packet_receive:
+ * @sockfd: a file descriptor created by socket(2)
+ * @addr: a pointer to a sockaddr to hold the address of the sender
+ * @len: a pointer to the size of the data pointed to by @addr
+ *
+ * Receives a #GstNetTimePacket over a socket. Handles interrupted system calls,
+ * but otherwise returns NULL on error. See recvfrom(2) for more information on
+ * how to interpret @sockaddr.
+ *
+ * MT safe. Caller owns return value (g_free to free).
+ *
+ * Returns: The new #GstNetTimePacket.
+ */
+GstNetTimePacket *
+gst_net_time_packet_receive (gint fd, struct sockaddr * addr, socklen_t * len)
+{
+ guint8 buffer[GST_NET_TIME_PACKET_SIZE];
+ gint ret;
+
+ while (TRUE) {
+ ret = recvfrom (fd, buffer, GST_NET_TIME_PACKET_SIZE,
+ 0, (struct sockaddr *) addr, len);
+ if (ret < 0) {
+ if (errno != EAGAIN && errno != EINTR)
+ goto receive_error;
+ else
+ continue;
+ } else if (ret < GST_NET_TIME_PACKET_SIZE) {
+ goto short_packet;
+ } else {
+ return gst_net_time_packet_new (buffer);
+ }
+ }
+
+receive_error:
+ {
+ GST_DEBUG ("receive error %d: %s (%d)", ret, g_strerror (errno), errno);
+ return NULL;
+ }
+short_packet:
+ {
+ GST_DEBUG ("someone sent us a short packet (%d < %d)",
+ ret, GST_NET_TIME_PACKET_SIZE);
+ return NULL;
+ }
+}
+
+/**
+ * gst_net_time_packet_send:
+ * @packet: the #GstNetTimePacket
+ * @sockfd: a file descriptor created by socket(2)
+ * @addr: a pointer to a sockaddr to hold the address of the sender
+ * @len: the size of the data pointed to by @addr
+ *
+ * Sends a #GstNetTimePacket over a socket. Essentially a thin wrapper around
+ * sendto(2) and gst_net_time_packet_serialize().
+ *
+ * MT safe.
+ *
+ * Returns: The return value of sendto(2).
+ */
+gint
+gst_net_time_packet_send (const GstNetTimePacket * packet, gint fd,
+ struct sockaddr * addr, socklen_t len)
+{
+ guint8 *buffer;
+ gint ret;
+
+ g_return_val_if_fail (packet != NULL, -EINVAL);
+
+ buffer = gst_net_time_packet_serialize (packet);
+
+ ret = sendto (fd, buffer, GST_NET_TIME_PACKET_SIZE, MSG_DONTWAIT, addr, len);
+
+ return ret;
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_NET_TIME_PACKET_H__
+#define __GST_NET_TIME_PACKET_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define GST_NET_TIME_PACKET_SIZE 16
+
+typedef struct _GstNetTimePacket GstNetTimePacket;
+
+struct _GstNetTimePacket {
+ GstClockTime local_time;
+ GstClockTime remote_time;
+};
+
+GstNetTimePacket* gst_net_time_packet_new (const guint8 *buffer);
+guint8* gst_net_time_packet_serialize (const GstNetTimePacket *packet);
+
+GstNetTimePacket* gst_net_time_packet_receive (gint fd, struct sockaddr *addr,
+ socklen_t *len);
+gint gst_net_time_packet_send (const GstNetTimePacket *packet,
+ gint fd, struct sockaddr *addr,
+ socklen_t len);
+
+G_END_DECLS
+
+
+#endif /* __GST_NET_TIME_PACKET_H__ */
#endif
#include "gstnettimeprovider.h"
+#include "gstnettimepacket.h"
+
#include <unistd.h>
#include <sys/ioctl.h>
#define DEFAULT_ADDRESS "0.0.0.0"
#define DEFAULT_PORT 5637
-typedef struct
-{
- GstClockTime slave_time_sent;
- GstClockTime master_time_received;
-} NetworkTimePacket;
-
- /* 2 * sizeof(GstClockTime), verified in base_init */
-#define NETWORK_TIME_PACKET_SIZE 16
-#define NETWORK_TIME_PACKET_SET_MASTER_TIME(p, t) \
- GST_WRITE_UINT64_BE(p+8, t)
-
enum
{
PROP_0,
socklen_t len;
fd_set read_fds;
guint max_sock;
- gchar *pktdata;
+ GstNetTimePacket *packet;
gint ret;
while (TRUE) {
continue;
} else {
/* got data in */
- pktdata = g_malloc (NETWORK_TIME_PACKET_SIZE);
-
len = sizeof (struct sockaddr);
- while (TRUE) {
- ret = recvfrom (self->sock, pktdata, NETWORK_TIME_PACKET_SIZE,
- 0, (struct sockaddr *) &tmpaddr, &len);
- if (ret < 0) {
- if (errno != EAGAIN && errno != EINTR)
- goto receive_error;
- else
- continue;
- } else if (ret < NETWORK_TIME_PACKET_SIZE) {
- goto short_packet;
- } else {
- GstClockTime now;
- now = gst_clock_get_time (self->clock);
+ packet = gst_net_time_packet_receive (self->sock,
+ (struct sockaddr *) &tmpaddr, &len);
- NETWORK_TIME_PACKET_SET_MASTER_TIME (pktdata, time);
+ if (!packet)
+ goto receive_error;
- /* ignore errors */
- sendto (self->sock, pktdata, ret, MSG_DONTWAIT,
- (struct sockaddr *) &tmpaddr, len);
+ /* do what we were asked to and send the packet back */
+ packet->remote_time = gst_clock_get_time (self->clock);
- break;
- }
+ /* ignore errors */
+ gst_net_time_packet_send (packet, self->sock,
+ (struct sockaddr *) &tmpaddr, len);
- g_assert_not_reached ();
- }
+ g_free (packet);
continue;
}
g_strerror (errno), errno);
continue;
}
- short_packet:
- {
- GST_DEBUG_OBJECT (self, "someone sent us a short packet (%d < %d)",
- ret, NETWORK_TIME_PACKET_SIZE);
- continue;
- }
stopped:
{
GST_DEBUG_OBJECT (self, "shutting down");
}
receive_error:
{
- g_free (pktdata);
- GST_DEBUG_OBJECT (self, "receive error %d: %s (%d)", ret,
- g_strerror (errno), errno);
+ GST_DEBUG_OBJECT (self, "receive error");
continue;
}
GST_END_TEST;
+#if 0
+GST_START_TEST (test_functioning)
+{
+ GstNetTimeProvider *ntp;
+ GstClock *clock;
+
+ clock = gst_system_clock_obtain ();
+ fail_unless (clock != NULL, "failed to get system clock");
+ ntp = gst_net_time_provider_new (clock, NULL, -1);
+ fail_unless (ntp != NULL, "failed to create net time provider");
+
+
+
+ gst_object_unref (ntp);
+ gst_object_unref (clock);
+}
+
+GST_END_TEST;
+#endif
+
Suite *
gst_net_time_provider_suite (void)
{