descrambler: Merge the common descrambler code - tvhcsa_descramble() calls
This commit is contained in:
parent
2ca5d1e215
commit
7425d43a23
8 changed files with 99 additions and 166 deletions
2
Makefile
2
Makefile
|
@ -125,7 +125,6 @@ SRCS = src/version.c \
|
|||
src/lang_str.c \
|
||||
src/imagecache.c \
|
||||
src/tvhtime.c \
|
||||
src/descrambler/descrambler.c \
|
||||
src/service_mapper.c \
|
||||
src/input.c \
|
||||
src/httpc.c \
|
||||
|
@ -193,6 +192,7 @@ SRCS += src/muxer.c \
|
|||
|
||||
# MPEGTS core
|
||||
SRCS-$(CONFIG_MPEGTS) += \
|
||||
src/descrambler/descrambler.c \
|
||||
src/input/mpegts.c \
|
||||
src/input/mpegts/mpegts_input.c \
|
||||
src/input/mpegts/mpegts_network.c \
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
#define __TVH_DESCRAMBLER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
struct service;
|
||||
struct elementary_stream;
|
||||
struct tvhcsa;
|
||||
|
||||
/**
|
||||
* Descrambler superclass
|
||||
|
@ -34,12 +34,18 @@ struct elementary_stream;
|
|||
typedef struct th_descrambler {
|
||||
LIST_ENTRY(th_descrambler) td_service_link;
|
||||
|
||||
void (*td_table)(struct th_descrambler *d, struct service *t,
|
||||
struct elementary_stream *st,
|
||||
const uint8_t *section, int section_len);
|
||||
enum {
|
||||
DS_UNKNOWN,
|
||||
DS_RESOLVED,
|
||||
DS_FORBIDDEN,
|
||||
DS_IDLE
|
||||
} td_keystate;
|
||||
|
||||
int (*td_descramble)(struct th_descrambler *d, struct service *t,
|
||||
struct elementary_stream *st, const uint8_t *tsb);
|
||||
struct service *td_service;
|
||||
struct tvhcsa *td_csa;
|
||||
|
||||
void (*td_table)(struct th_descrambler *d, struct elementary_stream *st,
|
||||
const uint8_t *section, int section_len);
|
||||
|
||||
void (*td_stop)(struct th_descrambler *d);
|
||||
|
||||
|
@ -79,9 +85,12 @@ LIST_HEAD(caid_list, caid);
|
|||
void descrambler_init ( void );
|
||||
void descrambler_done ( void );
|
||||
void descrambler_service_start ( struct service *t );
|
||||
const char *descrambler_caid2name(uint16_t caid);
|
||||
uint16_t descrambler_name2caid(const char *str);
|
||||
card_type_t detect_card_type(const uint16_t caid);
|
||||
int descrambler_descramble ( th_descrambler_t *td,
|
||||
struct elementary_stream *st,
|
||||
const uint8_t *tsb );
|
||||
const char *descrambler_caid2name( uint16_t caid );
|
||||
uint16_t descrambler_name2caid ( const char *str );
|
||||
card_type_t detect_card_type ( const uint16_t caid );
|
||||
|
||||
#endif /* __TVH_DESCRAMBLER_H__ */
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "tvheadend.h"
|
||||
#include "input.h"
|
||||
#include "service.h"
|
||||
#include "tcp.h"
|
||||
#include "capmt.h"
|
||||
|
||||
|
@ -148,9 +149,7 @@ typedef struct capmt_caid_ecm {
|
|||
*
|
||||
*/
|
||||
typedef struct capmt_service {
|
||||
th_descrambler_t ct_head;
|
||||
|
||||
mpegts_service_t *ct_service;
|
||||
th_descrambler_t;
|
||||
|
||||
struct capmt *ct_capmt;
|
||||
|
||||
|
@ -159,15 +158,6 @@ typedef struct capmt_service {
|
|||
/* list of used ca-systems with ids and last ecm */
|
||||
struct capmt_caid_ecm_list ct_caid_ecm;
|
||||
|
||||
/**
|
||||
* Status of the key(s) in ct_keys
|
||||
*/
|
||||
enum {
|
||||
CT_UNKNOWN,
|
||||
CT_RESOLVED,
|
||||
CT_FORBIDDEN
|
||||
} ct_keystate;
|
||||
|
||||
tvhcsa_t ct_csa;
|
||||
|
||||
/* current sequence number */
|
||||
|
@ -336,11 +326,13 @@ capmt_send_msg(capmt_t *capmt, int sid, const uint8_t *buf, size_t len)
|
|||
static void
|
||||
capmt_send_stop(capmt_service_t *t)
|
||||
{
|
||||
mpegts_service_t *s = (mpegts_service_t *)t->td_service;
|
||||
|
||||
if (t->ct_capmt->capmt_oscam) {
|
||||
int i;
|
||||
// searching for socket to close
|
||||
for (i = 0; i < MAX_SOCKETS; i++)
|
||||
if (t->ct_capmt->sids[i] == t->ct_service->s_dvb_service_id)
|
||||
if (t->ct_capmt->sids[i] == s->s_dvb_service_id)
|
||||
break;
|
||||
|
||||
if (i == MAX_SOCKETS) {
|
||||
|
@ -362,7 +354,7 @@ capmt_send_stop(capmt_service_t *t)
|
|||
capmt_header_t head = {
|
||||
.capmt_indicator = { 0x9F, 0x80, 0x32, 0x82, 0x00, 0x00 },
|
||||
.capmt_list_management = CAPMT_LIST_ONLY,
|
||||
.program_number = t->ct_service->s_dvb_service_id,
|
||||
.program_number = s->s_dvb_service_id,
|
||||
.version_number = 0,
|
||||
.current_next_indicator = 0,
|
||||
.program_info_length = 0,
|
||||
|
@ -377,13 +369,13 @@ capmt_send_stop(capmt_service_t *t)
|
|||
pos += sizeof(end);
|
||||
buf[4] = ((pos - 6) >> 8);
|
||||
buf[5] = ((pos - 6) & 0xFF);
|
||||
buf[7] = t->ct_service->s_dvb_service_id >> 8;
|
||||
buf[8] = t->ct_service->s_dvb_service_id & 0xFF;
|
||||
buf[7] = s->s_dvb_service_id >> 8;
|
||||
buf[8] = s->s_dvb_service_id & 0xFF;
|
||||
buf[9] = 1;
|
||||
buf[10] = ((pos - 5 - 12) & 0xF00) >> 8;
|
||||
buf[11] = ((pos - 5 - 12) & 0xFF);
|
||||
|
||||
capmt_send_msg(t->ct_capmt, t->ct_service->s_dvb_service_id, buf, pos);
|
||||
capmt_send_msg(t->ct_capmt, s->s_dvb_service_id, buf, pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -501,8 +493,8 @@ handle_ca0(capmt_t* capmt) {
|
|||
|
||||
// we are not connected any more - set services as unavailable
|
||||
LIST_FOREACH(ct, &capmt->capmt_services, ct_link) {
|
||||
if (ct->ct_keystate != CT_FORBIDDEN) {
|
||||
ct->ct_keystate = CT_FORBIDDEN;
|
||||
if (ct->td_keystate != DS_FORBIDDEN) {
|
||||
ct->td_keystate = DS_FORBIDDEN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -581,13 +573,13 @@ handle_ca0(capmt_t* capmt) {
|
|||
// processing key
|
||||
if (process_key) {
|
||||
LIST_FOREACH(ct, &capmt->capmt_services, ct_link) {
|
||||
t = ct->ct_service;
|
||||
t = (mpegts_service_t *)ct->td_service;
|
||||
|
||||
if (!capmt->capmt_oscam && ret < bufsize) {
|
||||
if(ct->ct_keystate != CT_FORBIDDEN) {
|
||||
if(ct->td_keystate != DS_FORBIDDEN) {
|
||||
tvhlog(LOG_ERR, "capmt", "Can not descramble service \"%s\", access denied", t->s_dvb_svcname);
|
||||
|
||||
ct->ct_keystate = CT_FORBIDDEN;
|
||||
ct->td_keystate = DS_FORBIDDEN;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -601,10 +593,10 @@ handle_ca0(capmt_t* capmt) {
|
|||
if (memcmp(odd, invalid, 8))
|
||||
tvhcsa_set_key_odd(&ct->ct_csa, odd);
|
||||
|
||||
if(ct->ct_keystate != CT_RESOLVED)
|
||||
if(ct->td_keystate != DS_RESOLVED)
|
||||
tvhlog(LOG_DEBUG, "capmt", "Obtained key for service \"%s\"",t->s_dvb_svcname);
|
||||
|
||||
ct->ct_keystate = CT_RESOLVED;
|
||||
ct->td_keystate = DS_RESOLVED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -738,19 +730,19 @@ capmt_thread(void *aux)
|
|||
*
|
||||
*/
|
||||
static void
|
||||
capmt_table_input(struct th_descrambler *td, struct service *s,
|
||||
capmt_table_input(struct th_descrambler *td,
|
||||
struct elementary_stream *st, const uint8_t *data, int len)
|
||||
{
|
||||
extern const idclass_t mpegts_service_class;
|
||||
extern const idclass_t linuxdvb_frontend_class;
|
||||
capmt_service_t *ct = (capmt_service_t *)td;
|
||||
capmt_t *capmt = ct->ct_capmt;
|
||||
mpegts_service_t *t = (mpegts_service_t*)s;
|
||||
mpegts_service_t *t = (mpegts_service_t*)td->td_service;
|
||||
linuxdvb_frontend_t *lfe;
|
||||
int total_caids = 0, current_caid = 0;
|
||||
|
||||
/* Validate */
|
||||
if (!idnode_is_instance(&s->s_id, &mpegts_service_class))
|
||||
if (!idnode_is_instance(&td->td_service->s_id, &mpegts_service_class))
|
||||
return;
|
||||
if (!t->s_dvb_active_input) return;
|
||||
lfe = (linuxdvb_frontend_t*)t->s_dvb_active_input;
|
||||
|
@ -805,7 +797,7 @@ capmt_table_input(struct th_descrambler *td, struct service *s,
|
|||
|
||||
if(!capmt->capmt_oscam && capmt->capmt_sock[0] == 0) {
|
||||
/* New key, but we are not connected (anymore), can not descramble */
|
||||
ct->ct_keystate = CT_UNKNOWN;
|
||||
ct->td_keystate = DS_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -833,7 +825,7 @@ static void
|
|||
capmt_send_request(capmt_service_t *ct, int es_pid, int lm)
|
||||
{
|
||||
capmt_t *capmt = ct->ct_capmt;
|
||||
mpegts_service_t *t = ct->ct_service;
|
||||
mpegts_service_t *t = (mpegts_service_t *)ct->td_service;
|
||||
uint16_t sid = t->s_dvb_service_id;
|
||||
uint16_t ecmpid = es_pid;
|
||||
uint16_t transponder = t->s_dvb_mux->mm_tsid;
|
||||
|
@ -946,7 +938,7 @@ capmt_send_request(capmt_service_t *ct, int es_pid, int lm)
|
|||
buf[8] = sid & 0xFF;
|
||||
|
||||
|
||||
if(ct->ct_keystate != CT_RESOLVED)
|
||||
if(ct->td_keystate != DS_RESOLVED)
|
||||
tvhlog(LOG_DEBUG, "capmt",
|
||||
"Trying to obtain key for service \"%s\"",t->s_dvb_svcname);
|
||||
|
||||
|
@ -967,7 +959,7 @@ capmt_enumerate_services(capmt_t *capmt, int es_pid, int force)
|
|||
capmt_service_t *ct;
|
||||
LIST_FOREACH(ct, &capmt->capmt_services, ct_link) {
|
||||
all_srv_count++;
|
||||
if (ct->ct_keystate == CT_RESOLVED)
|
||||
if (ct->td_keystate == DS_RESOLVED)
|
||||
res_srv_count++;
|
||||
}
|
||||
|
||||
|
@ -991,28 +983,6 @@ capmt_enumerate_services(capmt_t *capmt, int es_pid, int force)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
capmt_descramble
|
||||
(th_descrambler_t *td, service_t *t, struct elementary_stream *st,
|
||||
const uint8_t *tsb)
|
||||
{
|
||||
capmt_service_t *ct = (capmt_service_t *)td;
|
||||
|
||||
if(ct->ct_keystate == CT_FORBIDDEN)
|
||||
return 1;
|
||||
|
||||
if(ct->ct_keystate != CT_RESOLVED)
|
||||
return -1;
|
||||
|
||||
tvhcsa_descramble(&ct->ct_csa, (mpegts_service_t*)t, st, tsb, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if our CAID's matches, and if so, link
|
||||
*
|
||||
|
@ -1045,7 +1015,7 @@ capmt_service_start(service_t *s)
|
|||
TAILQ_FOREACH(capmt, &capmts, capmt_link) {
|
||||
LIST_FOREACH(ct, &capmt->capmt_services, ct_link) {
|
||||
/* skip, if we already have this service */
|
||||
if (ct->ct_service == t)
|
||||
if (ct->td_service == (service_t *)t)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1063,9 +1033,7 @@ capmt_service_start(service_t *s)
|
|||
|
||||
/* create new capmt service */
|
||||
ct = calloc(1, sizeof(capmt_service_t));
|
||||
tvhcsa_init(&ct->ct_csa);
|
||||
ct->ct_capmt = capmt;
|
||||
ct->ct_service = t;
|
||||
ct->ct_seq = capmt->capmt_seq++;
|
||||
|
||||
|
||||
|
@ -1092,10 +1060,11 @@ capmt_service_start(service_t *s)
|
|||
}
|
||||
}
|
||||
|
||||
td = &ct->ct_head;
|
||||
td = (th_descrambler_t *)ct;
|
||||
tvhcsa_init(td->td_csa = &ct->ct_csa);
|
||||
td->td_service = s;
|
||||
td->td_stop = capmt_service_destroy;
|
||||
td->td_table = capmt_table_input;
|
||||
td->td_descramble = capmt_descramble;
|
||||
LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link);
|
||||
|
||||
LIST_INSERT_HEAD(&capmt->capmt_services, ct, ct_link);
|
||||
|
|
|
@ -124,9 +124,7 @@ typedef struct ecm_pid {
|
|||
*
|
||||
*/
|
||||
typedef struct cwc_service {
|
||||
th_descrambler_t cs_head;
|
||||
|
||||
mpegts_service_t *cs_service;
|
||||
th_descrambler_t;
|
||||
|
||||
struct cwc *cs_cwc;
|
||||
|
||||
|
@ -143,19 +141,6 @@ typedef struct cwc_service {
|
|||
ECM_RESET
|
||||
} ecm_state;
|
||||
|
||||
/**
|
||||
* Status of the key(s) in cs_keys
|
||||
*/
|
||||
enum {
|
||||
CS_UNKNOWN,
|
||||
CS_RESOLVED,
|
||||
CS_FORBIDDEN,
|
||||
CS_IDLE
|
||||
} cs_keystate;
|
||||
|
||||
uint8_t cs_cw[16];
|
||||
int cs_pending_cw_update;
|
||||
|
||||
tvhcsa_t cs_csa;
|
||||
|
||||
LIST_HEAD(, ecm_pid) cs_pids;
|
||||
|
@ -696,7 +681,7 @@ static void
|
|||
handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
||||
int len, int seq)
|
||||
{
|
||||
mpegts_service_t *t = ct->cs_service;
|
||||
mpegts_service_t *t = (mpegts_service_t *)ct->td_service;
|
||||
ecm_pid_t *ep, *epn;
|
||||
cwc_service_t *ct2;
|
||||
cwc_t *cwc2;
|
||||
|
@ -714,7 +699,7 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
if (es->es_nok < 3)
|
||||
es->es_nok++;
|
||||
|
||||
if(ct->cs_keystate == CS_FORBIDDEN)
|
||||
if(ct->td_keystate == DS_FORBIDDEN)
|
||||
return; // We already know it's bad
|
||||
|
||||
if (es->es_nok > 2) {
|
||||
|
@ -727,8 +712,8 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
|
||||
TAILQ_FOREACH(cwc2, &cwcs, cwc_link) {
|
||||
LIST_FOREACH(ct2, &cwc2->cwc_services, cs_link) {
|
||||
if (ct != ct2 && ct2->cs_service == t &&
|
||||
ct2->cs_keystate == CS_RESOLVED) {
|
||||
if (ct != ct2 && ct2->td_service == (service_t *)t &&
|
||||
ct2->td_keystate == DS_RESOLVED) {
|
||||
tvhlog(LOG_DEBUG, "cwc",
|
||||
"NOK from %s:%i: Already has a key for service \"%s\", from %s:%i",
|
||||
ct->cs_cwc->cwc_hostname, ct->cs_cwc->cwc_port,
|
||||
|
@ -759,7 +744,7 @@ forbid:
|
|||
"Req delay: %"PRId64" ms)",
|
||||
t->s_dvb_svcname, seq, delay);
|
||||
|
||||
ct->cs_keystate = CS_FORBIDDEN;
|
||||
ct->td_keystate = DS_FORBIDDEN;
|
||||
ct->ecm_state = ECM_RESET;
|
||||
|
||||
return;
|
||||
|
@ -790,9 +775,9 @@ forbid:
|
|||
|
||||
TAILQ_FOREACH(cwc2, &cwcs, cwc_link) {
|
||||
LIST_FOREACH(ct2, &cwc2->cwc_services, cs_link) {
|
||||
if (ct != ct2 && ct2->cs_service == t &&
|
||||
ct2->cs_keystate == CS_RESOLVED) {
|
||||
ct->cs_keystate = CS_IDLE;
|
||||
if (ct != ct2 && ct2->td_service == (service_t *)t &&
|
||||
ct2->td_keystate == DS_RESOLVED) {
|
||||
ct->td_keystate = DS_IDLE;
|
||||
tvhlog(LOG_DEBUG, "cwc",
|
||||
"Already has a key for service \"%s\", from %s:%i",
|
||||
t->s_dvb_svcname, ct2->cs_cwc->cwc_hostname, ct2->cs_cwc->cwc_port);
|
||||
|
@ -801,15 +786,23 @@ forbid:
|
|||
}
|
||||
}
|
||||
|
||||
if(ct->cs_keystate != CS_RESOLVED)
|
||||
if(ct->td_keystate != DS_RESOLVED)
|
||||
tvhlog(LOG_DEBUG, "cwc",
|
||||
"Obtained key for service \"%s\" in %"PRId64" ms, from %s:%i",
|
||||
t->s_dvb_svcname, delay, ct->cs_cwc->cwc_hostname,
|
||||
ct->cs_cwc->cwc_port);
|
||||
|
||||
ct->cs_keystate = CS_RESOLVED;
|
||||
memcpy(ct->cs_cw, msg + 3, 16);
|
||||
ct->cs_pending_cw_update = 1;
|
||||
ct->td_keystate = DS_RESOLVED;
|
||||
for (i = 3; i < 3 + 8; i++)
|
||||
if (msg[i]) {
|
||||
tvhcsa_set_key_even(&ct->cs_csa, msg + 3);
|
||||
break;
|
||||
}
|
||||
for (i = 3 + 8; i < 3 + 8 + 8; i++)
|
||||
if (msg[i]) {
|
||||
tvhcsa_set_key_odd(&ct->cs_csa, msg + 3 + 8);
|
||||
break;
|
||||
}
|
||||
|
||||
ep = LIST_FIRST(&ct->cs_pids);
|
||||
while(ep != NULL) {
|
||||
|
@ -1210,9 +1203,9 @@ cwc_thread(void *aux)
|
|||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
|
||||
while((ct = LIST_FIRST(&cwc->cwc_services)) != NULL) {
|
||||
t = ct->cs_service;
|
||||
t = (mpegts_service_t *)ct->td_service;
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
cwc_service_destroy(&ct->cs_head);
|
||||
cwc_service_destroy((th_descrambler_t *)&ct);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
}
|
||||
|
||||
|
@ -1601,11 +1594,11 @@ cwc_emm_viaccess(cwc_t *cwc, struct cs_card_data *pcard, uint8_t *data, int mlen
|
|||
* t->s_streaming_mutex is held
|
||||
*/
|
||||
static void
|
||||
cwc_table_input(struct th_descrambler *td, service_t *s,
|
||||
cwc_table_input(struct th_descrambler *td,
|
||||
struct elementary_stream *st, const uint8_t *data, int len)
|
||||
{
|
||||
cwc_service_t *ct = (cwc_service_t *)td;
|
||||
mpegts_service_t *t = (mpegts_service_t*)s;
|
||||
mpegts_service_t *t = (mpegts_service_t*)td->td_service;
|
||||
uint16_t sid = t->s_dvb_service_id;
|
||||
cwc_t *cwc = ct->cs_cwc;
|
||||
int channel;
|
||||
|
@ -1615,7 +1608,7 @@ cwc_table_input(struct th_descrambler *td, service_t *s,
|
|||
char chaninfo[32];
|
||||
caid_t *c;
|
||||
|
||||
if (ct->cs_keystate == CS_IDLE)
|
||||
if (ct->td_keystate == DS_IDLE)
|
||||
return;
|
||||
|
||||
if(len > 4096)
|
||||
|
@ -1708,7 +1701,7 @@ cwc_table_input(struct th_descrambler *td, service_t *s,
|
|||
|
||||
if(cwc->cwc_fd == -1) {
|
||||
// New key, but we are not connected (anymore), can not descramble
|
||||
ct->cs_keystate = CS_UNKNOWN;
|
||||
ct->td_keystate = DS_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
es->es_channel = channel;
|
||||
|
@ -1897,56 +1890,6 @@ cwc_emm_bulcrypt(cwc_t *cwc, struct cs_card_data *pcard, uint8_t *data, int len)
|
|||
cwc_send_msg(cwc, data, len, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
update_keys(cwc_service_t *ct)
|
||||
{
|
||||
int i;
|
||||
ct->cs_pending_cw_update = 0;
|
||||
for(i = 0; i < 8; i++)
|
||||
if(ct->cs_cw[i]) {
|
||||
tvhcsa_set_key_even(&ct->cs_csa, ct->cs_cw);
|
||||
break;
|
||||
}
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
if(ct->cs_cw[8 + i]) {
|
||||
tvhcsa_set_key_odd(&ct->cs_csa, ct->cs_cw+8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
cwc_descramble
|
||||
(th_descrambler_t *td, service_t *t, struct elementary_stream *st,
|
||||
const uint8_t *tsb)
|
||||
{
|
||||
cwc_service_t *ct = (cwc_service_t *)td;
|
||||
|
||||
if(ct->cs_keystate == CS_FORBIDDEN)
|
||||
return 1;
|
||||
|
||||
if(ct->cs_keystate != CS_RESOLVED)
|
||||
return -1;
|
||||
|
||||
if(ct->cs_csa.csa_fill == 0 && ct->cs_pending_cw_update)
|
||||
update_keys(ct);
|
||||
|
||||
tvhcsa_descramble(&ct->cs_csa, (mpegts_service_t*)t, st, tsb,
|
||||
ct->cs_pending_cw_update);
|
||||
|
||||
if(ct->cs_pending_cw_update)
|
||||
update_keys(ct);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cwc_mutex is held
|
||||
* s_stream_mutex is held
|
||||
|
@ -2012,7 +1955,7 @@ cwc_service_start(service_t *t)
|
|||
pthread_mutex_lock(&cwc_mutex);
|
||||
TAILQ_FOREACH(cwc, &cwcs, cwc_link) {
|
||||
LIST_FOREACH(ct, &cwc->cwc_services, cs_link) {
|
||||
if (ct->cs_service == (mpegts_service_t*)t && ct->cs_cwc == cwc)
|
||||
if (ct->td_service == t && ct->cs_cwc == cwc)
|
||||
break;
|
||||
}
|
||||
LIST_FOREACH(pcard,&cwc->cwc_cards, cs_card) {
|
||||
|
@ -2029,16 +1972,15 @@ cwc_service_start(service_t *t)
|
|||
mpegts_table_register_caid(((mpegts_service_t *)t)->s_dvb_mux, pcard->cwc_caid);
|
||||
|
||||
ct = calloc(1, sizeof(cwc_service_t));
|
||||
tvhcsa_init(&ct->cs_csa);
|
||||
ct->cs_cwc = cwc;
|
||||
ct->cs_service = (mpegts_service_t*)t;
|
||||
ct->cs_channel = -1;
|
||||
ct->ecm_state = ECM_INIT;
|
||||
|
||||
td = &ct->cs_head;
|
||||
td->td_stop = cwc_service_destroy;
|
||||
td->td_table = cwc_table_input;
|
||||
td->td_descramble = cwc_descramble;
|
||||
td = (th_descrambler_t *)ct;
|
||||
tvhcsa_init(td->td_csa = &ct->cs_csa);
|
||||
td->td_service = t;
|
||||
td->td_stop = cwc_service_destroy;
|
||||
td->td_table = cwc_table_input;
|
||||
LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link);
|
||||
|
||||
LIST_INSERT_HEAD(&cwc->cwc_services, ct, cs_link);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "capmt.h"
|
||||
#include "ffdecsa/FFdecsa.h"
|
||||
#include "service.h"
|
||||
#include "tvhcsa.h"
|
||||
|
||||
static struct strtab caidnametab[] = {
|
||||
{ "Seca", 0x0100 },
|
||||
|
@ -133,6 +134,21 @@ descrambler_service_start ( service_t *t )
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
descrambler_descramble ( th_descrambler_t *td,
|
||||
struct elementary_stream *st,
|
||||
const uint8_t *tsb )
|
||||
{
|
||||
if (td->td_keystate == DS_FORBIDDEN)
|
||||
return 1;
|
||||
if (td->td_keystate != DS_RESOLVED)
|
||||
return -1;
|
||||
tvhcsa_descramble(td->td_csa,
|
||||
(struct mpegts_service *)td->td_service,
|
||||
st, tsb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: might actually put const char* into caid_t
|
||||
const char *
|
||||
descrambler_caid2name(uint16_t caid)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
void
|
||||
tvhcsa_descramble
|
||||
( tvhcsa_t *csa, struct mpegts_service *s, struct elementary_stream *st,
|
||||
const uint8_t *tsb, int cw_update_pending )
|
||||
const uint8_t *tsb )
|
||||
{
|
||||
#if ENABLE_DVBCSA
|
||||
uint8_t *pkt;
|
||||
|
@ -134,9 +134,6 @@ tvhcsa_descramble
|
|||
if(r > 0)
|
||||
memmove(csa->csa_tsbcluster, t0, r * 188);
|
||||
csa->csa_fill = r;
|
||||
|
||||
if(cw_update_pending && r > 0)
|
||||
continue;
|
||||
} else {
|
||||
csa->csa_fill = 0;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef struct tvhcsa
|
|||
void
|
||||
tvhcsa_descramble
|
||||
( tvhcsa_t *csa, struct mpegts_service *s, struct elementary_stream *st,
|
||||
const uint8_t *tsb, int cw_update_pending );
|
||||
const uint8_t *tsb );
|
||||
|
||||
void tvhcsa_init ( tvhcsa_t *csa );
|
||||
void tvhcsa_destroy ( tvhcsa_t *csa );
|
||||
|
|
|
@ -56,7 +56,7 @@ got_ca_section(const uint8_t *data, size_t len, void *opaque)
|
|||
mpegts_service_t *t = (mpegts_service_t*)st->es_service;
|
||||
|
||||
LIST_FOREACH(td, &t->s_descramblers, td_service_link)
|
||||
td->td_table(td, (service_t*)t, st, data, len);
|
||||
td->td_table(td, st, data, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -249,7 +249,7 @@ ts_recv_packet1
|
|||
LIST_FOREACH(td, &t->s_descramblers, td_service_link) {
|
||||
n++;
|
||||
|
||||
r = td->td_descramble(td, (service_t*)t, st, tsb);
|
||||
r = descrambler_descramble(td, st, tsb);
|
||||
if(r == 0) {
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
return 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue