/*
 * GStreamer - GStreamer SRTP encoder and decoder
 *
 * Copyright 2009-2013 Collabora Ltd.
 *  @author: Gabriel Millaire <gabriel.millaire@collabora.co.uk>
 *  @author: Olivier Crete <olivier.crete@collabora.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

#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include "gstsrtp.h"

#include <glib.h>

#include <gst/rtp/gstrtcpbuffer.h>

#include "gstsrtpenc.h"
#include "gstsrtpdec.h"

static void free_reporter_data (gpointer data);

GPrivate current_callback = G_PRIVATE_INIT (free_reporter_data);

struct GstSrtpEventReporterData
{
  gboolean soft_limit_reached;
};

static void
free_reporter_data (gpointer data)
{
  g_slice_free (struct GstSrtpEventReporterData, data);
}


static void
srtp_event_reporter (srtp_event_data_t * data)
{
  struct GstSrtpEventReporterData *dat = g_private_get (&current_callback);

  if (!dat)
    return;

  switch (data->event) {
    case event_key_soft_limit:
      dat->soft_limit_reached = TRUE;
      break;

    default:
      break;
  }
}

void
gst_srtp_init_event_reporter (void)
{
  struct GstSrtpEventReporterData *dat = g_private_get (&current_callback);

  if (!dat) {
    dat = g_slice_new (struct GstSrtpEventReporterData);
    g_private_set (&current_callback, dat);
  }

  dat->soft_limit_reached = FALSE;

  srtp_install_event_handler (srtp_event_reporter);
}

const gchar *
enum_nick_from_value (GType enum_gtype, gint value)
{
  GEnumClass *enum_class = g_type_class_ref (enum_gtype);
  GEnumValue *enum_value;
  const gchar *nick;

  if (!enum_gtype)
    return NULL;

  enum_value = g_enum_get_value (enum_class, value);
  if (!enum_value)
    return NULL;
  nick = enum_value->value_nick;
  g_type_class_unref (enum_class);

  return nick;
}


gint
enum_value_from_nick (GType enum_gtype, const gchar * nick)
{
  GEnumClass *enum_class = g_type_class_ref (enum_gtype);
  GEnumValue *enum_value;
  gint value;

  if (!enum_gtype)
    return -1;

  enum_value = g_enum_get_value_by_nick (enum_class, nick);
  if (!enum_value)
    return -1;
  value = enum_value->value;
  g_type_class_unref (enum_class);

  return value;
}

gboolean
gst_srtp_get_soft_limit_reached (void)
{
  struct GstSrtpEventReporterData *dat = g_private_get (&current_callback);

  if (dat)
    return dat->soft_limit_reached;
  return FALSE;
}

/* Get SSRC from RTCP buffer
 */
gboolean
rtcp_buffer_get_ssrc (GstBuffer * buf, guint32 * ssrc)
{
  gboolean ret = FALSE;
  GstRTCPBuffer rtcpbuf = GST_RTCP_BUFFER_INIT;
  GstRTCPPacket packet;

  /* Get SSRC from RR or SR packet (RTCP) */

  if (!gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcpbuf))
    return FALSE;

  if (gst_rtcp_buffer_get_first_packet (&rtcpbuf, &packet)) {
    GstRTCPType type;
    do {
      type = gst_rtcp_packet_get_type (&packet);
      switch (type) {
        case GST_RTCP_TYPE_RR:
          *ssrc = gst_rtcp_packet_rr_get_ssrc (&packet);
          ret = TRUE;
          break;
        case GST_RTCP_TYPE_SR:
          gst_rtcp_packet_sr_get_sender_info (&packet, ssrc, NULL, NULL, NULL,
              NULL);
          ret = TRUE;
          break;
        default:
          break;
      }
    } while ((ret == FALSE) && (type != GST_RTCP_TYPE_INVALID) &&
        gst_rtcp_packet_move_to_next (&packet));
  }

  gst_rtcp_buffer_unmap (&rtcpbuf);

  return ret;
}

void
set_crypto_policy_cipher_auth (GstSrtpCipherType cipher,
    GstSrtpAuthType auth, crypto_policy_t * policy)
{
  switch (cipher) {
    case GST_SRTP_CIPHER_AES_128_ICM:
      policy->cipher_type = AES_ICM;
      policy->cipher_key_len = 30;
      break;
    case GST_SRTP_CIPHER_AES_256_ICM:
      policy->cipher_type = AES_ICM;
      policy->cipher_key_len = 46;
      break;
    case GST_SRTP_CIPHER_NULL:
      policy->cipher_type = NULL_CIPHER;
      policy->cipher_key_len = 0;
      break;
    default:
      g_assert_not_reached ();
  }

  switch (auth) {
    case GST_SRTP_AUTH_HMAC_SHA1_80:
      policy->auth_type = HMAC_SHA1;
      policy->auth_key_len = 20;
      policy->auth_tag_len = 10;
      break;
    case GST_SRTP_AUTH_HMAC_SHA1_32:
      policy->auth_type = HMAC_SHA1;
      policy->auth_key_len = 20;
      policy->auth_tag_len = 4;
      break;
    case GST_SRTP_AUTH_NULL:
      policy->auth_type = NULL_AUTH;
      policy->auth_key_len = 0;
      policy->auth_tag_len = 0;
      break;
  }

  if (cipher == GST_SRTP_CIPHER_NULL && auth == GST_SRTP_AUTH_NULL)
    policy->sec_serv = sec_serv_none;
  else if (cipher == GST_SRTP_CIPHER_NULL)
    policy->sec_serv = sec_serv_auth;
  else if (auth == GST_SRTP_AUTH_NULL)
    policy->sec_serv = sec_serv_conf;
  else
    policy->sec_serv = sec_serv_conf_and_auth;
}

guint
cipher_key_size (GstSrtpCipherType cipher)
{
  guint size = 0;

  switch (cipher) {
    case GST_SRTP_CIPHER_AES_128_ICM:
      size = 30;
      break;
    case GST_SRTP_CIPHER_AES_256_ICM:
      size = 46;
      break;
    case GST_SRTP_CIPHER_NULL:
      size = 0;
      break;
    default:
      g_assert_not_reached ();
  }

  return size;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  srtp_init ();

  if (!gst_srtp_enc_plugin_init (plugin))
    return FALSE;

  if (!gst_srtp_dec_plugin_init (plugin))
    return FALSE;

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    srtp,
    "GStreamer SRTP",
    plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
