/* GStreamer
 * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
 * Copyright (C) 2010 Tim-Philipp Müller <tim centricular net>
 * Copyright (C) 2012 Collabora Ltd. <tim.muller@collabora.co.uk>
 *
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/**
 * SECTION:gstnettimepacket
 * @short_description: Helper structure to construct clock packets used
 *                     by network clocks.
 * @see_also: #GstClock, #GstNetClientClock, #GstNetTimeProvider
 *
 * Various functions for receiving, sending an serializing #GstNetTimePacket
 * structures.
 *
 * Last reviewed on 2005-11-23 (0.9.5)
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <glib.h>

#ifdef __CYGWIN__
# include <unistd.h>
# include <fcntl.h>
#endif

#include "gstnettimepacket.h"

G_DEFINE_BOXED_TYPE (GstNetTimePacket, gst_net_time_packet,
    gst_net_time_packet_copy, gst_net_time_packet_free);

/**
 * gst_net_time_packet_new:
 * @buffer: (array): 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 (gst_net_time_packet_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_free:
 * @packet: the #GstNetTimePacket
 *
 * Free @packet.
 */
void
gst_net_time_packet_free (GstNetTimePacket * packet)
{
  g_free (packet);
}

/**
 * gst_net_time_packet_copy:
 * @packet: the #GstNetTimePacket
 *
 * Make a copy of @packet.
 *
 * Returns: a copy of @packet, free with gst_net_time_packet_free().
 */
GstNetTimePacket *
gst_net_time_packet_copy (const GstNetTimePacket * packet)
{
  GstNetTimePacket *ret;

  ret = g_new0 (GstNetTimePacket, 1);
  ret->local_time = packet->local_time;
  ret->remote_time = packet->remote_time;

  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:
 * @socket: socket to receive the time packet on
 * @src_address: (out): address of variable to return sender address
 * @error: return address for a #GError, or NULL
 *
 * Receives a #GstNetTimePacket over a socket. Handles interrupted system
 * calls, but otherwise returns NULL on error.
 *
 * Returns: (transfer full): a new #GstNetTimePacket, or NULL on error. Free
 *    with gst_net_time_packet_free() when done.
 */
GstNetTimePacket *
gst_net_time_packet_receive (GSocket * socket,
    GSocketAddress ** src_address, GError ** error)
{
  gchar buffer[GST_NET_TIME_PACKET_SIZE];
  GError *err = NULL;
  gssize ret;

  g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  while (TRUE) {
    ret = g_socket_receive_from (socket, src_address, buffer,
        GST_NET_TIME_PACKET_SIZE, NULL, &err);

    if (ret < 0) {
      if (err->code == G_IO_ERROR_WOULD_BLOCK) {
        g_error_free (err);
        err = NULL;
        continue;
      } else {
        goto receive_error;
      }
    } else if (ret < GST_NET_TIME_PACKET_SIZE) {
      goto short_packet;
    } else {
      return gst_net_time_packet_new ((const guint8 *) buffer);
    }
  }

receive_error:
  {
    GST_DEBUG ("receive error: %s", err->message);
    g_propagate_error (error, err);
    return NULL;
  }
short_packet:
  {
    GST_DEBUG ("someone sent us a short packet (%" G_GSSIZE_FORMAT " < %d)",
        ret, GST_NET_TIME_PACKET_SIZE);
    g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
        "short time packet (%d < %d)", (int) ret, GST_NET_TIME_PACKET_SIZE);
    return NULL;
  }
}

/**
 * gst_net_time_packet_send:
 * @packet: the #GstNetTimePacket to send
 * @socket: socket to send the time packet on
 * @dest_address: address to send the time packet to
 * @error: return address for a #GError, or NULL
 *
 * Sends a #GstNetTimePacket over a socket.
 *
 * MT safe.
 *
 * Returns: TRUE if successful, FALSE in case an error occured.
 */
gboolean
gst_net_time_packet_send (const GstNetTimePacket * packet,
    GSocket * socket, GSocketAddress * dest_address, GError ** error)
{
  gboolean was_blocking;
  guint8 *buffer;
  gssize res;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
  g_return_val_if_fail (G_IS_SOCKET_ADDRESS (dest_address), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  was_blocking = g_socket_get_blocking (socket);

  if (was_blocking)
    g_socket_set_blocking (socket, FALSE);

  /* FIXME: avoid pointless alloc/free, serialise into stack-allocated buffer */
  buffer = gst_net_time_packet_serialize (packet);

  res = g_socket_send_to (socket, dest_address, (const gchar *) buffer,
      GST_NET_TIME_PACKET_SIZE, NULL, error);

  /* datagram packets should be sent as a whole or not at all */
  g_assert (res < 0 || res == GST_NET_TIME_PACKET_SIZE);

  g_free (buffer);

  if (was_blocking)
    g_socket_set_blocking (socket, TRUE);

  return (res == GST_NET_TIME_PACKET_SIZE);
}
