/*
 * camapplication.c - GStreamer CAM (EN50221) Application Layer
 * Copyright (C) 2007 Alessandro Decina
 * 
 * Authors:
 *   Alessandro Decina <alessandro@nnva.org>
 *
 * 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.
 */

#include "camapplication.h"

#define GST_CAT_DEFAULT cam_debug_cat

/* Resource Manager */
#define TAG_PROFILE_ENQUIRY 0x9F8010
#define TAG_PROFILE_REPLY 0x9F8011
#define TAG_PROFILE_CHANGE 0x9F8012

/* Application Info */
#define TAG_APPLICATION_INFO_ENQUIRY 0x9F8020
#define TAG_APPLICATION_INFO_REPLY 0x9F8021
#define TAG_APPLICATION_INFO_ENTER_MENU 0x9F8022

/* Conditional Access */
#define TAG_CONDITIONAL_ACCESS_INFO_ENQUIRY 0x9F8030
#define TAG_CONDITIONAL_ACCESS_INFO_REPLY 0x9F8031
#define TAG_CONDITIONAL_ACCESS_PMT 0x9F8032
#define TAG_CONDITIONAL_ACCESS_PMT_REPLY 0x9F8033

typedef struct
{
  guint tagid;
  const gchar *description;
} CamTagMessage;

static const CamTagMessage debugmessage[] = {
  {TAG_PROFILE_ENQUIRY, "PROFILE_ENQUIRY"},
  {TAG_PROFILE_REPLY, "PROFILE_REPLY"},
  {TAG_PROFILE_CHANGE, "PROFILE_CHANGE"},
  {TAG_APPLICATION_INFO_ENQUIRY, "APPLICATION_INFO_ENQUIRY"},
  {TAG_APPLICATION_INFO_REPLY, "APPLICATION_INFO_REPLY"},
  {TAG_APPLICATION_INFO_ENTER_MENU, "APPLICATION_INFO_ENTER_MENU"},
  {TAG_CONDITIONAL_ACCESS_INFO_ENQUIRY, "CONDITIONAL_ACCESS_INFO_ENQUIRY"},
  {TAG_CONDITIONAL_ACCESS_INFO_REPLY, "CONDITIONAL_ACCESS_INFO_REPLY"},
  {TAG_CONDITIONAL_ACCESS_PMT, "CONDITIONAL_ACCESS_PMT"},
  {TAG_CONDITIONAL_ACCESS_PMT_REPLY, "CONDITIONAL_ACCESS_PMT_REPLY"}
};

static inline const gchar *
tag_get_name (guint tagid)
{
  guint i;

  for (i = 0; i < G_N_ELEMENTS (debugmessage); i++)
    if (debugmessage[i].tagid == tagid)
      return debugmessage[i].description;
  return "UNKNOWN";
}

static CamReturn open_session_request_cb (CamSL * sl,
    CamSLSession * session, CamSLResourceStatus * status);
static CamReturn session_opened_cb (CamSL * sl, CamSLSession * session);
static CamReturn session_closed_cb (CamSL * sl, CamSLSession * session);
static CamReturn session_data_cb (CamSL * sl,
    CamSLSession * session, guint8 * data, guint length);

static guint
resource_id_hash (gconstpointer key)
{
  guint resource_id = GPOINTER_TO_UINT (key);

  if (!CAM_AL_RESOURCE_ID_IS_PUBLIC (resource_id)) {
    /* private identifier, leave it as is */
    return resource_id;
  }

  /* public identifier, mask out the version number */
  return resource_id >> 6;
}

CamAL *
cam_al_new (CamSL * sl)
{
  CamAL *al = g_new0 (CamAL, 1);

  al->sl = sl;
  al->applications = g_hash_table_new (resource_id_hash, g_direct_equal);

  sl->user_data = al;
  sl->open_session_request = open_session_request_cb;
  sl->session_opened = session_opened_cb;
  sl->session_closed = session_closed_cb;
  sl->session_data = session_data_cb;

  return al;
}

void
cam_al_destroy (CamAL * al)
{
  g_hash_table_destroy (al->applications);
  g_free (al);
}

gboolean
cam_al_install (CamAL * al, CamALApplication * application)
{
  if (g_hash_table_lookup (al->applications,
          GINT_TO_POINTER (application->resource_id)) != NULL)
    return FALSE;

  application->al = al;

  g_hash_table_insert (al->applications,
      GINT_TO_POINTER (application->resource_id), application);

  return TRUE;
}

gboolean
cam_al_uninstall (CamAL * al, CamALApplication * application)
{
  gboolean ret;

  ret = g_hash_table_remove (al->applications,
      GINT_TO_POINTER (application->resource_id));

  return ret;
}

CamALApplication *
cam_al_get (CamAL * al, guint resource_id)
{
  return CAM_AL_APPLICATION (g_hash_table_lookup (al->applications,
          GINT_TO_POINTER (resource_id)));
}

void
_cam_al_application_init (CamALApplication * application)
{
  application->sessions = NULL;
}

void
_cam_al_application_destroy (CamALApplication * application)
{
  g_list_free (application->sessions);
}

static void
foreach_get_key (gpointer key, gpointer value, gpointer user_data)
{
  GList **lst = (GList **) user_data;

  *lst = g_list_append (*lst, key);
}

GList *
cam_al_get_resource_ids (CamAL * al)
{
  GList *resource_ids = NULL;

  g_hash_table_foreach (al->applications, foreach_get_key, &resource_ids);

  return resource_ids;
}

void
cam_al_calc_buffer_size (CamAL * al, guint body_length,
    guint * buffer_size, guint * offset)
{
  guint apdu_header_length;
  guint8 length_field_len;

  /* get the length of the lenght_field() */
  length_field_len = cam_calc_length_field_size (body_length);

  /* sum the APDU header */
  apdu_header_length = 3 + length_field_len;

  /* chain up to the session layer to get the size of the buffer that can
   * contain the whole APDU */
  cam_sl_calc_buffer_size (al->sl, apdu_header_length + body_length,
      buffer_size, offset);

  /* add the APDU header to the SPDU offset */
  *offset += apdu_header_length;
}

CamReturn
cam_al_application_write (CamALApplication * application,
    CamSLSession * session, guint tag, guint8 * buffer, guint buffer_size,
    guint body_length)
{
  guint length_field_len;
  guint apdu_header_length;
  guint8 *apdu;

  GST_DEBUG ("tag:0x%x (%s), buffer_size:%d, body_length:%d", tag,
      tag_get_name (tag), buffer_size, body_length);

  length_field_len = cam_calc_length_field_size (body_length);
  apdu_header_length = 3 + length_field_len;
  apdu = (buffer + buffer_size) - body_length - apdu_header_length;
  apdu[0] = tag >> 16;
  apdu[1] = (tag >> 8) & 0xFF;
  apdu[2] = tag & 0xFF;

  cam_write_length_field (&apdu[3], body_length);

  return cam_sl_session_write (session, buffer, buffer_size,
      apdu_header_length + body_length);
}

static CamReturn
open_session_request_cb (CamSL * sl, CamSLSession * session,
    CamSLResourceStatus * status)
{
  CamAL *al = CAM_AL (sl->user_data);
  CamALApplication *application;
  guint resource_id = session->resource_id;
  CamReturn ret;

  application = g_hash_table_lookup (al->applications,
      GINT_TO_POINTER (resource_id));
  if (application == NULL) {
    *status = CAM_SL_RESOURCE_STATUS_NOT_FOUND;

    return CAM_RETURN_OK;
  }

  if (CAM_AL_RESOURCE_ID_VERSION (application->resource_id)
      < CAM_AL_RESOURCE_ID_VERSION (resource_id)) {
    *status = CAM_SL_RESOURCE_STATUS_INVALID_VERSION;

    return CAM_RETURN_OK;
  }

  ret = application->session_request (application, session, status);
  if (CAM_FAILED (ret)) {
    *status = CAM_SL_RESOURCE_STATUS_NOT_FOUND;

    return ret;
  }

  if (*status == CAM_SL_RESOURCE_STATUS_OPEN) {
    session->user_data = application;
    application->sessions = g_list_append (application->sessions, session);
  }

  return CAM_RETURN_OK;
}

static CamReturn
session_opened_cb (CamSL * sl, CamSLSession * session)
{
  CamALApplication *application;

  application = CAM_AL_APPLICATION (session->user_data);
  if (application == NULL) {
    GST_ERROR ("session is established but has no application");
    return CAM_RETURN_APPLICATION_ERROR;
  }

  return application->open (application, session);
}

static CamReturn
session_closed_cb (CamSL * sl, CamSLSession * session)
{
  CamALApplication *application;
  CamReturn ret;
  GList *walk;

  application = CAM_AL_APPLICATION (session->user_data);
  if (application == NULL) {
    GST_ERROR ("session is established but has no application");
    return CAM_RETURN_APPLICATION_ERROR;
  }

  ret = application->close (application, session);
  for (walk = application->sessions; walk; walk = g_list_next (walk)) {
    CamSLSession *s = CAM_SL_SESSION (walk->data);

    if (s->session_nb == session->session_nb) {
      application->sessions = g_list_delete_link (application->sessions, walk);
      break;
    }
  }

  return ret;
}

static CamReturn
session_data_cb (CamSL * sl, CamSLSession * session, guint8 * data, guint size)
{
  CamALApplication *application;
  guint tag = 0;
  guint8 length_field_len;
  guint length;
  guint i;

  application = CAM_AL_APPLICATION (session->user_data);
  if (application == NULL) {
    GST_ERROR ("session is established but has no application");
    return CAM_RETURN_APPLICATION_ERROR;
  }

  if (size < 4) {
    GST_ERROR ("invalid APDU length %d", size);
    return CAM_RETURN_APPLICATION_ERROR;
  }

  for (i = 0; i < 3; ++i)
    tag = (tag << 8) | data[i];

  length_field_len = cam_read_length_field (&data[3], &length);

  if (length != size - 4) {
    GST_ERROR ("unexpected APDU length %d expected %d", length, size);

    return CAM_RETURN_APPLICATION_ERROR;
  }

  GST_DEBUG ("Got tag 0x%x (%s) , length:%d", tag, tag_get_name (tag), length);

  return application->data (application, session,
      tag, data + 3 + length_field_len, length);
}
