aboutsummaryrefslogtreecommitdiffstats
path: root/util/zap/zap_ca.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/zap/zap_ca.c')
-rw-r--r--util/zap/zap_ca.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/util/zap/zap_ca.c b/util/zap/zap_ca.c
new file mode 100644
index 0000000..b78fdcf
--- /dev/null
+++ b/util/zap/zap_ca.c
@@ -0,0 +1,198 @@
+/*
+ ZAP utility CA functions
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser 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 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <pthread.h>
+#include <libdvben50221/en50221_stdcam.h>
+#include "zap_ca.h"
+
+
+static int zap_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids);
+static int zap_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string);
+static void *camthread_func(void* arg);
+
+static struct en50221_transport_layer *tl = NULL;
+static struct en50221_session_layer *sl = NULL;
+static struct en50221_stdcam *stdcam = NULL;
+
+static int ca_resource_connected = 0;
+
+static int camthread_shutdown = 0;
+static pthread_t camthread;
+static int seenpmt = 0;
+static int moveca = 0;
+
+void zap_ca_start(struct zap_ca_params *params)
+{
+ // create transport layer
+ tl = en50221_tl_create(1, 16);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ return;
+ }
+
+ // create session layer
+ sl = en50221_sl_create(tl, 16);
+ if (sl == NULL) {
+ fprintf(stderr, "Failed to create session layer\n");
+ en50221_tl_destroy(tl);
+ return;
+ }
+
+ // create the stdcam instance
+ stdcam = en50221_stdcam_create(params->adapter_id, params->caslot_num, tl, sl);
+ if (stdcam == NULL) {
+ en50221_sl_destroy(sl);
+ en50221_tl_destroy(tl);
+ return;
+ }
+
+ // hook up the AI callbacks
+ if (stdcam->ai_resource) {
+ en50221_app_ai_register_callback(stdcam->ai_resource, zap_ai_callback, stdcam);
+ }
+
+ // hook up the CA callbacks
+ if (stdcam->ca_resource) {
+ en50221_app_ca_register_info_callback(stdcam->ca_resource, zap_ca_info_callback, stdcam);
+ }
+
+ // any other stuff
+ moveca = params->moveca;
+
+ // start the cam thread
+ pthread_create(&camthread, NULL, camthread_func, NULL);
+}
+
+void zap_ca_stop(void)
+{
+ if (stdcam == NULL)
+ return;
+
+ // shutdown the cam thread
+ camthread_shutdown = 1;
+ pthread_join(camthread, NULL);
+
+ // destroy session layer
+ en50221_sl_destroy(sl);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ // destroy the stdcam
+ if (stdcam->destroy)
+ stdcam->destroy(stdcam, 1);
+}
+
+int zap_ca_new_pmt(struct mpeg_pmt_section *pmt)
+{
+ uint8_t capmt[4096];
+ int size;
+
+ if (stdcam == NULL)
+ return -1;
+
+ if (ca_resource_connected) {
+ fprintf(stderr, "Received new PMT - sending to CAM...\n");
+
+ // translate it into a CA PMT
+ int listmgmt = CA_LIST_MANAGEMENT_ONLY;
+ if (seenpmt) {
+ listmgmt = CA_LIST_MANAGEMENT_UPDATE;
+ }
+ seenpmt = 1;
+
+ if ((size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), moveca, listmgmt,
+ CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
+ fprintf(stderr, "Failed to format PMT\n");
+ return -1;
+ }
+
+ // set it
+ if (en50221_app_ca_pmt(stdcam->ca_resource, stdcam->ca_session_number, capmt, size)) {
+ fprintf(stderr, "Failed to send PMT\n");
+ return -1;
+ }
+
+ // we've seen this PMT
+ return 1;
+ }
+
+ return 0;
+}
+
+void zap_ca_new_dvbtime(time_t dvb_time)
+{
+ if (stdcam == NULL)
+ return;
+
+ if (stdcam->dvbtime)
+ stdcam->dvbtime(stdcam, dvb_time);
+}
+
+static void *camthread_func(void* arg)
+{
+ (void) arg;
+
+ while(!camthread_shutdown) {
+ stdcam->poll(stdcam);
+ }
+
+ return 0;
+}
+
+static int zap_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+
+ printf("CAM Application type: %02x\n", application_type);
+ printf("CAM Application manufacturer: %04x\n", application_manufacturer);
+ printf("CAM Manufacturer code: %04x\n", manufacturer_code);
+ printf("CAM Menu string: %.*s\n", menu_string_length, menu_string);
+
+ return 0;
+}
+
+static int zap_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+
+ printf("CAM supports the following ca system ids:\n");
+ uint32_t i;
+ for(i=0; i< ca_id_count; i++) {
+ printf(" 0x%04x\n", ca_ids[i]);
+ }
+ ca_resource_connected = 1;
+ return 0;
+}