/*
 * 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;
        case GST_RTCP_TYPE_RTPFB:
        case GST_RTCP_TYPE_PSFB:
          *ssrc = gst_rtcp_packet_fb_get_sender_ssrc (&packet);
          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/")
