/*
 * camsession.c - GStreamer CAM (EN50221) Session 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "camsession.h"

#define GST_CAT_DEFAULT cam_debug_cat
#define I_TAG 0
#define I_LENGTH_FB 1

#define TAG_SESSION_NUMBER 0x90
#define TAG_OPEN_SESSION_REQUEST 0x91
#define TAG_OPEN_SESSION_RESPONSE 0x92
#define TAG_CREATE_SESSION 0x93
#define TAG_CREATE_SESSION_RESPONSE 0x94
#define TAG_CLOSE_SESSION_REQUEST 0x95
#define TAG_CLOSE_SESSION_RESPONSE 0x96

static CamReturn connection_data_cb (CamTL * tl, CamTLConnection * connection,
    guint8 * spdu, guint spdu_length);

CamSLSession *
cam_sl_session_new (CamSL * sl, CamTLConnection * connection,
    guint16 session_nb, guint resource_id)
{
  CamSLSession *session = g_new0 (CamSLSession, 1);

  session->state = CAM_SL_SESSION_STATE_IDLE;
  session->sl = sl;
  session->connection = connection;
  session->session_nb = session_nb;
  session->resource_id = resource_id;

  return session;
}

void
cam_sl_session_destroy (CamSLSession * session)
{
  g_free (session);
}

CamSL *
cam_sl_new (CamTL * tl)
{
  CamSL *sl = g_new0 (CamSL, 1);

  sl->sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, (GDestroyNotify) cam_sl_session_destroy);

  tl->user_data = sl;
  tl->connection_data = connection_data_cb;

  return sl;
}

void
cam_sl_destroy (CamSL * sl)
{
  g_hash_table_destroy (sl->sessions);

  g_free (sl);
}

CamReturn
cam_sl_create_session (CamSL * sl,
    CamTLConnection * connection, guint resource_id,
    CamSLSession ** out_session)
{
  CamReturn ret;
  CamSLSession *session = NULL;
  guint size;
  guint offset;
  guint8 *tpdu = NULL;
  guint8 *spdu;
  guint16 session_nb;

  /* FIXME: implement session number allocations properly */
  if (sl->session_ids == G_MAXUINT16)
    return CAM_RETURN_SESSION_TOO_MANY_SESSIONS;

  session_nb = ++sl->session_ids;
  session = cam_sl_session_new (sl, connection, session_nb, resource_id);

  /* SPDU layout (8 bytes):
   * TAG_CREATE_SESSION 1 byte
   * length_field () 1 byte
   * resource_id 4 bytes
   * session_nb 2 bytes
   */

  /* get TPDU size */
  cam_tl_calc_buffer_size (sl->tl, 8, &size, &offset);

  tpdu = (guint8 *) g_malloc (size);
  spdu = tpdu + offset;

  /* SPDU header */
  /* tag */
  spdu[0] = TAG_CREATE_SESSION;
  /* fixed length_field */
  spdu[1] = 6;

  /* SPDU body */
  /* resource id */
  GST_WRITE_UINT32_BE (&spdu[2], resource_id);
  /* session_nb */
  GST_WRITE_UINT16_BE (&spdu[6], session_nb);

  /* write the TPDU */
  ret = cam_tl_connection_write (session->connection, tpdu, size, 8);
  if (CAM_FAILED (ret))
    goto error;

  *out_session = session;

  g_free (tpdu);
  return CAM_RETURN_OK;

error:
  if (session)
    cam_sl_session_destroy (session);

  g_free (tpdu);

  return ret;
}

/* send a TAG_CLOSE_SESSION SPDU */
CamReturn
cam_sl_session_close (CamSLSession * session)
{
  CamReturn ret;
  guint size;
  guint offset;
  guint8 *tpdu = NULL;
  guint8 *spdu;
  CamSL *sl = session->sl;

  /* SPDU layout (4 bytes):
   * TAG_CLOSE_SESSION 1 byte
   * length_field () 1 byte
   * session_nb 2 bytes
   */

  /* get the size of the TPDU */
  cam_tl_calc_buffer_size (sl->tl, 4, &size, &offset);

  tpdu = (guint8 *) g_malloc (size);
  /* the spdu header starts after the TPDU headers */
  spdu = tpdu + offset;

  /* SPDU header */
  /* tag */
  spdu[0] = TAG_CLOSE_SESSION_REQUEST;
  /* fixed length_field */
  spdu[1] = 2;
  /* SPDU body */
  /* session_nb */
  GST_WRITE_UINT16_BE (&spdu[2], session->session_nb);

  /* write the TPDU */
  ret = cam_tl_connection_write (session->connection, tpdu, size, 4);
  if (CAM_FAILED (ret))
    goto error;

  session->state = CAM_SL_SESSION_STATE_CLOSING;

  g_free (tpdu);

  return CAM_RETURN_OK;

error:
  g_free (tpdu);

  return ret;
}

void
cam_sl_calc_buffer_size (CamSL * sl, guint body_length,
    guint * buffer_size, guint * offset)
{
  /* an APDU is sent in a SESSION_NUMBER SPDU, which has a fixed header size (4
   * bytes) */
  cam_tl_calc_buffer_size (sl->tl, 4 + body_length, buffer_size, offset);
  *offset += 4;
}

CamReturn
cam_sl_session_write (CamSLSession * session,
    guint8 * buffer, guint buffer_size, guint body_length)
{
  guint8 *spdu;

  /* SPDU layout (4 + body_length bytes):
   * TAG_SESSION_NUMBER (1 byte)
   * length_field (1 byte)
   * session number (2 bytes)
   * one or more APDUs (body_length bytes)
   */

  spdu = (buffer + buffer_size) - body_length - 4;
  spdu[0] = TAG_SESSION_NUMBER;
  spdu[1] = 2;
  GST_WRITE_UINT16_BE (&spdu[2], session->session_nb);

  /* add our header to the body length */
  return cam_tl_connection_write (session->connection,
      buffer, buffer_size, 4 + body_length);
}

static CamReturn
send_open_session_response (CamSL * sl, CamSLSession * session, guint8 status)
{
  CamReturn ret;
  guint8 *tpdu;
  guint size;
  guint offset;
  guint8 *spdu;

  /* SPDU layout (9 bytes):
   * TAG_OPEN_SESSION_RESPONSE 1 byte
   * length_field () 1 byte
   * session_status 1 byte
   * resource_id 4 bytes
   * session_nb 2 bytes
   */

  cam_tl_calc_buffer_size (session->sl->tl, 9, &size, &offset);

  tpdu = g_malloc0 (size);
  spdu = tpdu + offset;

  spdu[0] = TAG_OPEN_SESSION_RESPONSE;
  /* fixed length_field () */
  spdu[1] = 7;
  spdu[2] = status;
  GST_WRITE_UINT32_BE (&spdu[3], session->resource_id);
  GST_WRITE_UINT16_BE (&spdu[7], session->session_nb);

  ret = cam_tl_connection_write (session->connection, tpdu, size, 9);
  g_free (tpdu);
  if (CAM_FAILED (ret))
    return ret;

  return CAM_RETURN_OK;
}

static CamReturn
send_close_session_response (CamSL * sl, CamSLSession * session, guint8 status)
{
  CamReturn ret;
  guint8 *tpdu;
  guint size;
  guint offset;
  guint8 *spdu;

  /* SPDU layout (5 bytes):
   * TAG_CLOSE_SESSION_RESPONSE 1 byte
   * length_field () 1 byte
   * session_status 1 byte
   * session_nb 2 bytes
   */

  cam_tl_calc_buffer_size (session->sl->tl, 5, &size, &offset);

  tpdu = g_malloc0 (size);
  spdu = tpdu + offset;

  spdu[0] = TAG_OPEN_SESSION_RESPONSE;
  /* fixed length_field() */
  spdu[1] = 3;
  spdu[2] = status;
  GST_WRITE_UINT16_BE (&spdu[3], session->session_nb);

  ret = cam_tl_connection_write (session->connection, tpdu, size, 5);
  g_free (tpdu);
  if (CAM_FAILED (ret))
    return ret;

  return CAM_RETURN_OK;
}

static CamReturn
handle_open_session_request (CamSL * sl, CamTLConnection * connection,
    guint8 * spdu, guint spdu_length)
{
  CamReturn ret;
  guint resource_id;
  guint status;
  guint16 session_nb;
  CamSLSession *session;

  /* SPDU layout (6 bytes):
   * TAG_OPEN_SESSION_REQUEST (1 byte)
   * length_field() (1 byte)
   * resource id (4 bytes)
   */
  if (spdu_length != 6) {
    GST_ERROR ("expected OPEN_SESSION_REQUEST to be 6 bytes, got %d",
        spdu_length);
    return CAM_RETURN_SESSION_ERROR;
  }

  /* skip tag and length_field () */
  resource_id = GST_READ_UINT32_BE (&spdu[2]);

  /* create a new session */
  if (sl->session_ids == G_MAXUINT16) {
    GST_ERROR ("too many sessions opened");
    return CAM_RETURN_SESSION_TOO_MANY_SESSIONS;
  }

  session_nb = ++sl->session_ids;
  session = cam_sl_session_new (sl, connection, session_nb, resource_id);

  GST_INFO ("session request: %d %x", session_nb, session->resource_id);

  if (sl->open_session_request) {
    /* forward the request to the upper layer */
    ret = sl->open_session_request (sl, session, &status);
    if (CAM_FAILED (ret))
      goto error;
  } else {
    status = 0xF0;
  }

  ret = send_open_session_response (sl, session, (guint8) status);
  if (CAM_FAILED (ret))
    goto error;

  GST_INFO ("session request response: %d %x", session_nb, status);

  if (status == CAM_SL_RESOURCE_STATUS_OPEN) {
    /* if the session has been accepted add it and signal */
    session->state = CAM_SL_SESSION_STATE_ACTIVE;
    g_hash_table_insert (sl->sessions,
        GINT_TO_POINTER ((guint) session_nb), session);

    if (sl->session_opened) {
      /* notify the upper layer */
      ret = sl->session_opened (sl, session);
      if (CAM_FAILED (ret))
        return ret;
    }
  } else {
    /* session request wasn't accepted */
    cam_sl_session_destroy (session);
  }

  return CAM_RETURN_OK;

error:
  cam_sl_session_destroy (session);

  return ret;
}

static CamReturn
handle_create_session_response (CamSL * sl, CamTLConnection * connection,
    guint8 * spdu, guint spdu_length)
{
  guint8 status;
  guint resource_id;
  guint16 session_nb;
  CamSLSession *session;

  /* SPDU layout (9 bytes):
   * TAG_CREATE_SESSION_RESPONSE (1 byte)
   * length_field() (1 byte)
   * status (1 byte)
   * resource id (4 bytes)
   * session number (2 bytes)
   */
  if (spdu_length != 9) {
    GST_ERROR ("expected CREATE_SESSION_RESPONSE to be 9 bytes, got %d",
        spdu_length);
    return CAM_RETURN_SESSION_ERROR;
  }

  /* skip tag and length */
  status = spdu[2];
  resource_id = GST_READ_UINT32_BE (&spdu[3]);
  session_nb = GST_READ_UINT16_BE (&spdu[7]);

  session = g_hash_table_lookup (sl->sessions,
      GINT_TO_POINTER ((guint) session_nb));
  if (session == NULL) {
    GST_DEBUG ("got CREATE_SESSION_RESPONSE for unknown session: %d",
        session_nb);
    return CAM_RETURN_SESSION_ERROR;
  }

  if (session->state == CAM_SL_SESSION_STATE_CLOSING) {
    GST_DEBUG ("ignoring CREATE_SESSION_RESPONSE for closing session: %d",
        session_nb);
    return CAM_RETURN_OK;
  }

  session->state = CAM_SL_SESSION_STATE_ACTIVE;

  GST_DEBUG ("session opened %d", session->session_nb);

  if (sl->session_opened)
    /* notify the upper layer */
    return sl->session_opened (sl, session);
  return CAM_RETURN_OK;
}

static CamReturn
handle_close_session_request (CamSL * sl, CamTLConnection * connection,
    guint8 * spdu, guint spdu_length)
{
  CamReturn ret;
  guint16 session_nb;
  CamSLSession *session;
  guint8 status = 0;

  /* SPDU layout (4 bytes):
   * TAG_CLOSE_SESSION_REQUEST (1 byte)
   * length_field () (1 byte)
   * session number (2 bytes)
   */
  if (spdu_length != 4) {
    GST_ERROR ("expected CLOSE_SESSION_REQUEST to be 4 bytes, got %d",
        spdu_length);
    return CAM_RETURN_SESSION_ERROR;
  }

  /* skip tag and length_field() */
  session_nb = GST_READ_UINT16_BE (&spdu[2]);

  GST_DEBUG ("close session request %d", session_nb);

  session = g_hash_table_lookup (sl->sessions,
      GINT_TO_POINTER ((guint) session_nb));
  if (session == NULL) {
    GST_WARNING ("got CLOSE_SESSION_REQUEST for unknown session: %d",
        session_nb);

    status = 0xF0;
  } else if (session->state == CAM_SL_SESSION_STATE_CLOSING) {
    GST_WARNING ("got CLOSE_SESSION_REQUEST for closing session: %d",
        session_nb);

    status = 0xF0;
  }

  GST_DEBUG ("close session response: %d %d", session->session_nb, status);

  ret = send_close_session_response (sl, session, status);
  if (CAM_FAILED (ret))
    return ret;

  if (session->state != CAM_SL_SESSION_STATE_CLOSING) {
    GST_DEBUG ("session closed %d", session->session_nb);

    if (sl->session_closed)
      ret = sl->session_closed (sl, session);

    g_hash_table_remove (sl->sessions,
        GINT_TO_POINTER ((guint) session->session_nb));

    if (CAM_FAILED (ret))
      return ret;
  }

  return CAM_RETURN_OK;
}

static CamReturn
handle_close_session_response (CamSL * sl, CamTLConnection * connection,
    guint8 * spdu, guint spdu_length)
{
  guint16 session_nb;
  CamSLSession *session;
  CamReturn ret = CAM_RETURN_OK;

  /* SPDU layout (5 bytes):
   * TAG_CLOSE_SESSION_RESPONSE (1 byte)
   * length_field () (1 byte)
   * status (1 byte)
   * session number (2 bytes)
   */

  if (spdu_length != 5) {
    GST_ERROR ("expected CLOSE_SESSION_RESPONSE to be 5 bytes, got %d",
        spdu_length);
    return CAM_RETURN_SESSION_ERROR;
  }

  /* skip tag, length_field() and session_status */
  session_nb = GST_READ_UINT16_BE (&spdu[3]);

  session = g_hash_table_lookup (sl->sessions,
      GINT_TO_POINTER ((guint) session_nb));
  if (session == NULL || session->state != CAM_SL_SESSION_STATE_ACTIVE) {
    GST_ERROR ("unexpected CLOSED_SESSION_RESPONSE");
    return CAM_RETURN_SESSION_ERROR;
  }

  GST_DEBUG ("session closed %d", session->session_nb);

  if (sl->session_closed)
    ret = sl->session_closed (sl, session);

  g_hash_table_remove (sl->sessions,
      GINT_TO_POINTER ((guint) session->session_nb));

  return ret;
}

static CamReturn
handle_session_data (CamSL * sl, CamTLConnection * connection,
    guint8 * spdu, guint length)
{
  guint16 session_nb;
  CamSLSession *session;

  /* SPDU layout (>= 4 bytes):
   * TAG_SESSION_NUMBER (1 byte)
   * length_field() (1 byte)
   * session number (2 bytes)
   * one or more APDUs 
   */

  if (length < 4) {
    GST_ERROR ("invalid SESSION_NUMBER SPDU length %d", length);
    return CAM_RETURN_SESSION_ERROR;
  }

  session_nb = GST_READ_UINT16_BE (&spdu[2]);

  session = g_hash_table_lookup (sl->sessions,
      GINT_TO_POINTER ((guint) session_nb));
  if (session == NULL) {
    GST_ERROR ("got SESSION_NUMBER on an unknown connection: %d", session_nb);
    return CAM_RETURN_SESSION_ERROR;
  }

  if (sl->session_data)
    /* pass the APDUs to the upper layer, removing our 4-bytes header */
    return sl->session_data (sl, session, spdu + 4, length - 4);

  return CAM_RETURN_OK;
}

static CamReturn
connection_data_cb (CamTL * tl, CamTLConnection * connection,
    guint8 * spdu, guint spdu_length)
{
  CamReturn ret;
  CamSL *sl = CAM_SL (tl->user_data);

  switch (spdu[I_TAG]) {
    case TAG_CREATE_SESSION_RESPONSE:
      ret = handle_create_session_response (sl, connection, spdu, spdu_length);
      break;
    case TAG_OPEN_SESSION_REQUEST:
      ret = handle_open_session_request (sl, connection, spdu, spdu_length);
      break;
    case TAG_CLOSE_SESSION_REQUEST:
      ret = handle_close_session_request (sl, connection, spdu, spdu_length);
      break;
    case TAG_CLOSE_SESSION_RESPONSE:
      ret = handle_close_session_response (sl, connection, spdu, spdu_length);
      break;
    case TAG_SESSION_NUMBER:
      ret = handle_session_data (sl, connection, spdu, spdu_length);
      break;
    default:
      g_return_val_if_reached (CAM_RETURN_SESSION_ERROR);
  }

  return ret;
}
