/*
 * camconditionalaccess.c - CAM (EN50221) Conditional Access resource
 * Copyright (C) 2007 Alessandro Decina
 * 
 * Authors:
 *   Alessandro Decina <alessandro@nnva.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; 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;
}
