/*
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, 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);

static 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;
}

static 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)
{
  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);
    return CAM_RETURN_OK;
  }

  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;
}
