/*
 * camtransport.c - GStreamer CAM (EN50221) transport 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 "camtransport.h"
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

#define GST_CAT_DEFAULT cam_debug_cat
#define READ_TIMEOUT_SEC 2
#define READ_TIMEOUT_USEC 0

#define POLL_INTERVAL 0.300

/* Layer tags */
#define TAG_SB 0x80
#define TAG_RCV 0x81
#define TAG_CREATE_T_C 0x82
#define TAG_C_T_C_REPLY 0x83
#define TAG_DELETE_T_C 0x84
#define TAG_D_T_C_REPLY 0x85
#define TAG_REQUEST_T_C 0x86
#define TAG_NEW_T_C 0x87
#define TAG_T_C_ERROR 0x88
#define TAG_DATA_MORE 0xA1
#define TAG_DATA_LAST 0xA0

/* Session tags */
#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


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

static const CamTagMessage debugmessage[] = {
  {TAG_SB, "SB"},
  {TAG_RCV, "RCV"},
  {TAG_CREATE_T_C, "CREATE_T_C"},
  {TAG_C_T_C_REPLY, "CREATE_T_C_REPLY"},
  {TAG_DELETE_T_C, "DELETE_T_C"},
  {TAG_D_T_C_REPLY, "DELETE_T_C_REPLY"},
  {TAG_REQUEST_T_C, "REQUEST_T_C"},
  {TAG_NEW_T_C, "NEW_T_C"},
  {TAG_T_C_ERROR, "T_C_ERROR"},
  {TAG_SESSION_NUMBER, "SESSION_NUMBER"},
  {TAG_OPEN_SESSION_REQUEST, "OPEN_SESSION_REQUEST"},
  {TAG_OPEN_SESSION_RESPONSE, "OPEN_SESSION_RESPONSE"},
  {TAG_CREATE_SESSION, "CREATE_SESSION"},
  {TAG_CREATE_SESSION_RESPONSE, "CREATE_SESSION_RESPONSE"},
  {TAG_CLOSE_SESSION_REQUEST, "CLOSE_SESSION_REQUEST"},
  {TAG_CLOSE_SESSION_RESPONSE, "CLOSE_SESSION_RESPONSE"},
  {TAG_DATA_MORE, "DATA_MORE"},
  {TAG_DATA_LAST, "DATA_LAST"}
};

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

/* utility struct used to store the state of the connections in cam_tl_read_next
 */
typedef struct
{
  GList *active;
  GList *idle;
} CamTLConnectionsStatus;

void cam_gst_util_dump_mem (const guchar * mem, guint size);

static CamTLConnection *
cam_tl_connection_new (CamTL * tl, guint8 id)
{
  CamTLConnection *connection;

  connection = g_new0 (CamTLConnection, 1);
  connection->tl = tl;
  connection->id = id;
  connection->state = CAM_TL_CONNECTION_STATE_CLOSED;
  connection->has_data = FALSE;

  return connection;
}

static void
cam_tl_connection_destroy (CamTLConnection * connection)
{
  if (connection->last_poll)
    g_timer_destroy (connection->last_poll);

  g_free (connection);
}

CamTL *
cam_tl_new (int fd)
{
  CamTL *tl;

  tl = g_new0 (CamTL, 1);
  tl->fd = fd;
  tl->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, (GDestroyNotify) cam_tl_connection_destroy);

  return tl;
}

void
cam_tl_destroy (CamTL * tl)
{
  g_hash_table_destroy (tl->connections);

  g_free (tl);
}

/* read data from the module without blocking indefinitely */
static CamReturn
cam_tl_read_timeout (CamTL * tl, struct timeval *timeout)
{
  fd_set read_fd;
  int sret;

  FD_ZERO (&read_fd);
  FD_SET (tl->fd, &read_fd);

  sret = select (tl->fd + 1, &read_fd, NULL, NULL, timeout);
  if (sret == 0) {
    GST_DEBUG ("read timeout");
    return CAM_RETURN_TRANSPORT_TIMEOUT;
  }

  tl->buffer_size = read (tl->fd, &tl->buffer, HOST_BUFFER_SIZE);
  if (tl->buffer_size == -1) {
    GST_ERROR ("error reading tpdu: %s", g_strerror (errno));
    return CAM_RETURN_TRANSPORT_ERROR;
  }

  return CAM_RETURN_OK;
}

/* read data from the module using the default timeout */
static CamReturn
cam_tl_read (CamTL * tl)
{
  struct timeval timeout;

  timeout.tv_sec = READ_TIMEOUT_SEC;
  timeout.tv_usec = READ_TIMEOUT_USEC;

  return cam_tl_read_timeout (tl, &timeout);
}

/* get the number of bytes to allocate for a TPDU with a body of body_length
 * bytes. Also get the offset from the beginning of the buffer that marks the
 * position of the first byte of the TPDU body */
void
cam_tl_calc_buffer_size (CamTL * tl, guint body_length,
    guint * buffer_size, guint * offset)
{
  guint length_field_len;

  /* the size of a TPDU is:
   * 1 byte slot number
   * 1 byte connection id 
   * length_field_len bytes length field 
   * 1 byte connection id
   * body_length bytes body
   */

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

  *offset = 3 + length_field_len + 1;
  *buffer_size = *offset + body_length;
}

/* write the header of a TPDU
 * NOTE: this function assumes that the buffer is large enough to contain the
 * complete TPDU (see cam_tl_calc_buffer_size ()) and that enough space has been
 * left from the beginning of the buffer to write the TPDU header.
 */
static CamReturn
cam_tl_connection_write_tpdu (CamTLConnection * connection,
    guint8 tag, guint8 * buffer, guint buffer_size, guint body_length)
{
  int sret;
  CamTL *tl = connection->tl;
  guint8 length_field_len;

  /* slot number */
  buffer[0] = connection->slot;
  /* connection number */
  buffer[1] = connection->id;
  /* tag */
  buffer[2] = tag;
  /* length can take 1 to 4 bytes */
  length_field_len = cam_write_length_field (&buffer[3], body_length);
  buffer[3 + length_field_len] = connection->id;

  GST_DEBUG ("writing TPDU %x (%s) connection %d (size:%d)",
      buffer[2], tag_get_name (buffer[2]), connection->id, buffer_size);

  //cam_gst_util_dump_mem (buffer, buffer_size);

  sret = write (tl->fd, buffer, buffer_size);
  if (sret == -1) {
    GST_ERROR ("error witing TPDU (%d): %s", errno, g_strerror (errno));
    return CAM_RETURN_TRANSPORT_ERROR;
  }

  tl->expected_tpdus += 1;

  GST_DEBUG ("Sucess writing tpdu 0x%x (%s)", buffer[2],
      tag_get_name (buffer[2]));

  return CAM_RETURN_OK;
}

/* convenience function to write control TPDUs (TPDUs having a single-byte body)
 */
static CamReturn
cam_tl_connection_write_control_tpdu (CamTLConnection * connection, guint8 tag)
{
  guint8 tpdu[5];

  /* TPDU layout (5 bytes):
   *
   * slot number (1 byte)
   * connection id (1 byte)
   * tag (1 byte)
   * length (1 byte)
   * connection id (1 byte)
   */

  return cam_tl_connection_write_tpdu (connection, tag, tpdu, 5, 1);
}

/* read the next TPDU from the CAM */
static CamReturn
cam_tl_read_tpdu_next (CamTL * tl, CamTLConnection ** out_connection)
{
  CamReturn ret;
  CamTLConnection *connection;
  guint8 connection_id;
  guint8 *tpdu;
  guint8 length_field_len;
  guint8 status;

  ret = cam_tl_read (tl);
  if (CAM_FAILED (ret))
    return ret;

  tpdu = tl->buffer;

  /* must hold at least slot, connection_id, 1byte length_field, connection_id
   */
  if (tl->buffer_size < 4) {
    GST_ERROR ("invalid TPDU length %d", tl->buffer_size);
    return CAM_RETURN_TRANSPORT_ERROR;
  }

  /* LPDU slot */
  /* slot = tpdu[0]; */
  /* LPDU connection id */
  connection_id = tpdu[1];

  connection = g_hash_table_lookup (tl->connections,
      GINT_TO_POINTER ((guint) connection_id));
  if (connection == NULL) {
    /* WHAT? */
    GST_ERROR ("CAM sent a TPDU on an unknown connection: %d", connection_id);
    return CAM_RETURN_TRANSPORT_ERROR;
  }

  /* read the length_field () */
  length_field_len = cam_read_length_field (&tpdu[3], &tl->body_length);

  if (tl->body_length + 3 > tl->buffer_size) {
    GST_ERROR ("invalid TPDU length_field (%d) exceeds "
        "the size of the buffer (%d)", tl->body_length, tl->buffer_size);
    return CAM_RETURN_TRANSPORT_ERROR;
  }

  /* skip slot + connection id + tag + lenght_field () + connection id */
  tl->body = tpdu + 4 + length_field_len;
  /* do not count the connection id byte as part of the body */
  tl->body_length -= 1;

  if (tl->buffer[tl->buffer_size - 4] != TAG_SB) {
    GST_ERROR ("no TAG_SB appended to TPDU");
    return CAM_RETURN_TRANSPORT_ERROR;
  }

  status = tl->buffer[tl->buffer_size - 1];
  if (status & 0x80) {
    connection->has_data = TRUE;
  } else {
    connection->has_data = FALSE;
  }

  GST_DEBUG ("received TPDU %x (%s) more data %d", tpdu[2],
      tag_get_name (tpdu[2]), connection->has_data);
  tl->expected_tpdus -= 1;

  *out_connection = connection;

  return CAM_RETURN_OK;
}

/* create a connection with the module */
CamReturn
cam_tl_create_connection (CamTL * tl, guint8 slot,
    CamTLConnection ** connection)
{
  CamReturn ret;
  CamTLConnection *conn = NULL;
  guint count = 10;

  if (tl->connection_ids == 255)
    return CAM_RETURN_TRANSPORT_TOO_MANY_CONNECTIONS;

  conn = cam_tl_connection_new (tl, ++tl->connection_ids);

  /* Some CA devices take a long time to set themselves up,
   * therefore retry every 250ms (for a maximum of 2.5s)
   */
  while (TRUE) {
    /* send a TAG_CREATE_T_C TPDU */
    ret = cam_tl_connection_write_control_tpdu (conn, TAG_CREATE_T_C);
    if (!CAM_FAILED (ret))
      break;
    if (!count)
      goto error;
    GST_DEBUG ("Failed sending initial connection message .. but retrying");
    count--;
    /* Wait 250ms */
    g_usleep (G_USEC_PER_SEC / 4);
  }

  g_hash_table_insert (tl->connections, GINT_TO_POINTER (conn->id), conn);

  *connection = conn;

  return CAM_RETURN_OK;

error:
  if (conn)
    cam_tl_connection_destroy (conn);

  return ret;
}

CamReturn
cam_tl_connection_delete (CamTLConnection * connection)
{
  CamReturn ret;

  ret = cam_tl_connection_write_control_tpdu (connection, TAG_DELETE_T_C);
  if (CAM_FAILED (ret))
    return ret;

  connection->state = CAM_TL_CONNECTION_STATE_IN_DELETION;

  return CAM_RETURN_OK;
}

static CamReturn
handle_control_tpdu (CamTL * tl, CamTLConnection * connection)
{
  if (tl->body_length != 0) {
    GST_ERROR ("got control tpdu of invalid length: %d", tl->body_length);
    return CAM_RETURN_TRANSPORT_ERROR;
  }

  switch (tl->buffer[2]) {
      /* create transport connection reply */
    case TAG_C_T_C_REPLY:
      /* a connection might be closed before it's acknowledged */
      if (connection->state != CAM_TL_CONNECTION_STATE_IN_DELETION) {
        GST_DEBUG ("connection created %d", connection->id);
        connection->state = CAM_TL_CONNECTION_STATE_OPEN;

        if (tl->connection_created)
          tl->connection_created (tl, connection);
      }
      break;
      /* delete transport connection reply */
    case TAG_D_T_C_REPLY:
      connection->state = CAM_TL_CONNECTION_STATE_CLOSED;
      GST_DEBUG ("connection closed %d", connection->id);

      if (tl->connection_deleted)
        tl->connection_deleted (tl, connection);

      g_hash_table_remove (tl->connections,
          GINT_TO_POINTER ((guint) connection->id));
      break;
  }

  return CAM_RETURN_OK;
}

static CamReturn
handle_data_tpdu (CamTL * tl, CamTLConnection * connection)
{
  if (tl->body_length == 0) {
    /* FIXME: figure out why this seems to happen from time to time with the
     * predator cam */
    GST_WARNING ("Empty data TPDU received");
    return CAM_RETURN_OK;
  }

  if (tl->connection_data)
    return tl->connection_data (tl, connection, tl->body, tl->body_length);

  return CAM_RETURN_OK;
}

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

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

CamReturn
cam_tl_connection_poll (CamTLConnection * connection, gboolean force)
{
  CamReturn ret;

  if (connection->last_poll == NULL) {
    connection->last_poll = g_timer_new ();
  } else if (!force &&
      g_timer_elapsed (connection->last_poll, NULL) < POLL_INTERVAL) {
    return CAM_RETURN_TRANSPORT_POLL;
  }

  GST_DEBUG ("polling connection %d", connection->id);
  ret = cam_tl_connection_write_control_tpdu (connection, TAG_DATA_LAST);
  if (CAM_FAILED (ret))
    return ret;

  g_timer_start (connection->last_poll);

  return CAM_RETURN_OK;
}

/* read all the queued TPDUs */
CamReturn
cam_tl_read_all (CamTL * tl, gboolean poll)
{
  CamReturn ret = CAM_RETURN_OK;
  CamTLConnection *connection;
  GList *connections = NULL;
  GList *walk;
  gboolean done = FALSE;

  while (!done) {
    while (tl->expected_tpdus) {
      /* read the next TPDU from the connection */
      ret = cam_tl_read_tpdu_next (tl, &connection);
      if (CAM_FAILED (ret)) {
        GST_ERROR ("error reading TPDU from module: %d", ret);
        goto out;
      }

      switch (tl->buffer[2]) {
        case TAG_C_T_C_REPLY:
        case TAG_D_T_C_REPLY:
          connection->empty_data = 0;
          ret = handle_control_tpdu (tl, connection);
          break;
        case TAG_DATA_MORE:
        case TAG_DATA_LAST:
          connection->empty_data = 0;
          ret = handle_data_tpdu (tl, connection);
          break;
        case TAG_SB:
          /* this is handled by tpdu_next */
          break;
      }

      if (CAM_FAILED (ret))
        goto out;
    }

    done = TRUE;

    connections = NULL;
    g_hash_table_foreach (tl->connections,
        foreach_connection_get, &connections);

    for (walk = connections; walk; walk = walk->next) {
      CamTLConnection *connection = CAM_TL_CONNECTION (walk->data);

      if (connection->has_data == TRUE && connection->empty_data < 10) {
        ret = cam_tl_connection_write_control_tpdu (connection, TAG_RCV);
        if (CAM_FAILED (ret)) {
          g_list_free (connections);
          goto out;
        }
        /* increment the empty_data counter. If we get data, this will be reset
         * to 0 */
        connection->empty_data++;
        done = FALSE;
      } else if (poll) {
        ret = cam_tl_connection_poll (connection, FALSE);
        if (ret == CAM_RETURN_TRANSPORT_POLL)
          continue;

        if (CAM_FAILED (ret)) {
          g_list_free (connections);
          goto out;
        }

        done = FALSE;
      }
    }

    g_list_free (connections);
  }

out:
  return ret;
}

CamReturn
cam_tl_connection_write (CamTLConnection * connection,
    guint8 * buffer, guint buffer_size, guint body_length)
{
  return cam_tl_connection_write_tpdu (connection,
      TAG_DATA_LAST, buffer, buffer_size, 1 + body_length);
}
