/*
 * camconditionalaccess.c - CAM (EN50221) Conditional Access Resource
 * 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.1 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 <unistd.h>
#include <string.h>
#include "camutils.h"
#include "camconditionalaccess.h"

#define GST_CAT_DEFAULT cam_debug_cat
#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

static CamReturn session_request_impl (CamALApplication * application,
    CamSLSession * session, CamSLResourceStatus * status);
static CamReturn open_impl (CamALApplication * application,
    CamSLSession * session);
static CamReturn close_impl (CamALApplication * application,
    CamSLSession * session);
static CamReturn data_impl (CamALApplication * application,
    CamSLSession * session, guint tag, guint8 * buffer, guint length);

CamConditionalAccess *
cam_conditional_access_new (void)
{
  CamConditionalAccess *cas;
  CamALApplication *application;

  cas = g_new0 (CamConditionalAccess, 1);

  application = CAM_AL_APPLICATION (cas);
  _cam_al_application_init (application);
  application->resource_id = CAM_AL_CONDITIONAL_ACCESS_ID;
  application->session_request = session_request_impl;
  application->open = open_impl;
  application->close = close_impl;
  application->data = data_impl;

  cas->ready = FALSE;

  return cas;
}

void
cam_conditional_access_destroy (CamConditionalAccess * cas)
{
  _cam_al_application_destroy (CAM_AL_APPLICATION (cas));
  g_free (cas);
}

static CamReturn
send_ca_pmt (CamConditionalAccess * cas, GstMpegtsPMT * pmt,
    guint8 list_management, guint8 cmd_id)
{
  CamReturn ret;
  guint8 *buffer;
  guint buffer_size;
  guint offset;
  guint8 *ca_pmt;
  guint ca_pmt_size;
  GList *walk;

  ca_pmt = cam_build_ca_pmt (pmt, list_management, cmd_id, &ca_pmt_size);
  cam_al_calc_buffer_size (CAM_AL_APPLICATION (cas)->al,
      ca_pmt_size, &buffer_size, &offset);

  buffer = g_malloc0 (buffer_size);
  memcpy (buffer + offset, ca_pmt, ca_pmt_size);

  for (walk = CAM_AL_APPLICATION (cas)->sessions; walk; walk = walk->next) {
    CamSLSession *session = CAM_SL_SESSION (walk->data);

    ret = cam_al_application_write (CAM_AL_APPLICATION (cas), session,
        TAG_CONDITIONAL_ACCESS_PMT, buffer, buffer_size, ca_pmt_size);
    if (CAM_FAILED (ret)) {
      GST_ERROR ("error sending ca_pmt to slot %d, error: %d",
          session->connection->slot, ret);
      continue;
    }
  }

  g_free (ca_pmt);
  g_free (buffer);

  return CAM_RETURN_OK;
}

CamReturn
cam_conditional_access_set_pmt (CamConditionalAccess * cas,
    GstMpegtsPMT * pmt, CamConditionalAccessPmtFlag flag)
{
  return send_ca_pmt (cas, pmt, flag, 0x01 /* ok_descrambling */ );
}

static CamReturn
send_simple (CamConditionalAccess * cas, CamSLSession * session, guint tag)
{
  guint8 *buffer;
  guint offset;
  guint buffer_size;
  CamReturn ret;

  cam_al_calc_buffer_size (CAM_AL_APPLICATION (cas)->al, 0, &buffer_size,
      &offset);
  buffer = g_malloc (buffer_size);

  ret = cam_al_application_write (CAM_AL_APPLICATION (cas), session,
      tag, buffer, buffer_size, 0);

  g_free (buffer);

  return ret;
}

static CamReturn
send_conditional_access_enquiry (CamConditionalAccess * cas,
    CamSLSession * session)
{
  GST_DEBUG ("sending application CAS enquiry");
  return send_simple (cas, session, TAG_CONDITIONAL_ACCESS_INFO_ENQUIRY);
}

static CamReturn
session_request_impl (CamALApplication * application,
    CamSLSession * session, CamSLResourceStatus * status)
{
  *status = CAM_SL_RESOURCE_STATUS_OPEN;

  return CAM_RETURN_OK;
}

static CamReturn
open_impl (CamALApplication * application, CamSLSession * session)
{
  CamConditionalAccess *cas = CAM_CONDITIONAL_ACCESS (application);

  GST_INFO ("opening conditional access session %d", session->session_nb);

  return send_conditional_access_enquiry (cas, session);
}

static CamReturn
close_impl (CamALApplication * application, CamSLSession * session)
{
  GST_INFO ("closing conditional access session %d", session->session_nb);

  return CAM_RETURN_OK;
}

static CamReturn
handle_conditional_access_info_reply (CamConditionalAccess * cas,
    CamSLSession * session, guint8 * buffer, guint length)
{
#ifndef GST_DISABLE_GST_DEBUG
  int i;
  guint16 cas_id;

  GST_INFO ("conditional access info enquiry reply");

  for (i = 0; i < length / 2; ++i) {
    cas_id = GST_READ_UINT16_BE (buffer);

    GST_INFO ("slot %d, cas_id 0x%x", session->connection->slot, cas_id);

    buffer += 2;
  }

  cas->ready = TRUE;
#endif

  return CAM_RETURN_OK;
}

static CamReturn
handle_conditional_access_pmt_reply (CamConditionalAccess * cas,
    CamSLSession * session, guint8 * buffer, guint length)
{
#ifndef GST_DISABLE_GST_DEBUG
  guint16 program_num;
  guint8 version_num, current_next_indicator;

  GST_INFO ("conditional access PMT reply");

  program_num = GST_READ_UINT16_BE (buffer);
  buffer += 2;

  GST_INFO ("program_number : %d", program_num);

  version_num = *buffer >> 1 & 0x1f;
  current_next_indicator = *buffer & 0x1;
  buffer++;

  GST_INFO ("version_num:%d, current_next_indicator:%d",
      version_num, current_next_indicator);

  GST_INFO ("CA_enable : %d (0x%x)", *buffer >> 7 ? *buffer & 0x7f : 0,
      *buffer);
  buffer++;

  length -= 4;

  while (length > 0) {
    guint16 PID = GST_READ_UINT16_BE (buffer);
    buffer += 2;
    GST_INFO ("PID 0x%x CA_enable : %d (0x%x)", PID,
        *buffer >> 7 ? *buffer & 0x7f : 0, *buffer);
    buffer++;

    length -= 3;
  }
#endif

  return CAM_RETURN_OK;
}

static CamReturn
data_impl (CamALApplication * application, CamSLSession * session,
    guint tag, guint8 * buffer, guint length)
{
  CamReturn ret;
  CamConditionalAccess *cas = CAM_CONDITIONAL_ACCESS (application);

  switch (tag) {
    case TAG_CONDITIONAL_ACCESS_INFO_REPLY:
      ret = handle_conditional_access_info_reply (cas, session, buffer, length);
      break;
    case TAG_CONDITIONAL_ACCESS_PMT_REPLY:
      ret = handle_conditional_access_pmt_reply (cas, session, buffer, length);
      break;
    default:
      GST_WARNING ("Got unknown callback, tag 0x%x", tag);
      g_return_val_if_reached (CAM_RETURN_ERROR);
  }

  return ret;
}
