|
SASC
DVBSoftCAM
|
#include <stdlib.h>#include <stdio.h>#include <pthread.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <assert.h>#include <sys/ioctl.h>#include <linux/dvb/ca.h>#include <linux/dvb/dmx.h>#include "../sc/include/vdr/plugin.h"#include "../sc/include/vdr/dvbdevice.h"#include "../sc/include/vdr/sclink.h"#include "../sc/include/vdr/channels.h"#include "../sc/include/vdr/tools.h"#include "../sc/sasccam.h"#include "process_req.h"#include "plugin_getsid.h"#include "plugin_cam.h"#include "plugin_msg.h"#include "debug.h"Go to the source code of this file.
Classes | |
| struct | cam_epid |
| struct | fdmap_list |
| struct | scopt_list |
Defines | |
| #define | PLUGIN_ID 28 |
| #define | DBG_NAME "CAM" |
| #define | ll_find_elem(elem, lhead, item, value, type) |
Functions | |
| char * | get_camdir () |
| LIST_HEAD (sclist) | |
| LIST_HEAD (pid_empty_queue) | |
| LIST_HEAD (pid_list) | |
| LIST_HEAD (fdmap_empty_queue) | |
| LIST_HEAD (fdmap_ll) | |
| void | update_keys (int, unsigned char, int, unsigned char *, int) |
| void | SetCAMPrint (const char *_plugin_name, unsigned int plugin_id, unsigned int _print_level, unsigned int *_log_level) |
| static int | init_sc (void) |
| static struct sc_data * | find_sc_from_adpt (int adapter) |
| void | cam_del_pid (struct sc_data *sc_data, struct cam_epid *cam_epid) |
| void | _SetCaDescr (int adapter, ca_descr_t *ca_descr) |
| void | _SetCaPid (int adapter, ca_pid_t *ca_pid) |
| void | process_cam (struct msg *msg, unsigned int priority) |
| unsigned int | crc32 (const unsigned char *d, int len, unsigned int crc) |
| static int | parse_ca (unsigned char *buf, int len) |
| static void | replace_cat (unsigned char *buf, int len, int pid) |
| static void | dmxread_call (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| static void | dmxioctl_call (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| static void | dmxclose_call (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| void | connect_cam (struct parser_adpt *pc_all) |
| static void | launch_cam () |
| static void | shutdown_cam () |
| static void | usermsg_cam (char *str) |
| static struct option * | parseopt_cam (arg_enum_t cmd) |
| int | __attribute__ ((constructor)) |
Variables | |
| static int | cam_opt = 0 |
| static int | opt_budget = 0 |
| static int | opt_fixcat = 1 |
| static char | opt_camdir [256] = {"./sc_files"} |
| static char | opt_extau [256] |
| static struct option | Cam_Opts [] |
| struct scopt_list | scopts [32] = {{{'\0'}}} |
| static cPlugin * | sc = NULL |
| static char | scCap [80] |
| const char * | externalAU |
| static unsigned int | crc_table [256] |
| static struct plugin_cmd | plugin_cmds |
| #define DBG_NAME "CAM" |
Definition at line 26 of file plugin_cam.c.
Referenced by init_sc().
| #define ll_find_elem | ( | elem, | |
| lhead, | |||
| item, | |||
| value, | |||
| type | |||
| ) |
{ \
struct list_head *lptr; \
type *ptr; \
elem = NULL; \
list_for_each(lptr, &lhead) { \
ptr = list_entry(lptr, type); \
if(ptr->item == value) \
elem = ptr; \
} \
}
Definition at line 29 of file plugin_cam.c.
Referenced by close_demux(), dmxclose_call(), dmxioctl_call(), dmxread_call(), find_csa_from_adpt(), find_csa_from_rb(), find_sc_from_adpt(), process_cam(), process_scan(), process_ts(), read_pat(), read_pmt(), read_sid(), set_demux(), start(), and update_keys().
| #define PLUGIN_ID 28 |
Definition at line 25 of file plugin_cam.c.
Referenced by init_sc().
| int __attribute__ | ( | (constructor) | ) |
Definition at line 691 of file plugin_cam.c.
References plugin_cmd::list, list_add_tail(), and plugin_cmdlist.
{
list_add_tail(&plugin_cmds.list, &plugin_cmdlist);
return 0;
}
| void _SetCaDescr | ( | int | adapter, |
| ca_descr_t * | ca_descr | ||
| ) |
Definition at line 155 of file plugin_cam.c.
References sc_data::cafd, dprintf0, dprintf1, find_sc_from_adpt(), MSG_CAMUPDATE, MSG_LOW_PRIORITY, msg_send, NULL, update_keys(), and sc_data::virt.
Referenced by start_loopbackca().
{
struct sc_data *sc_data = find_sc_from_adpt(adapter);
unsigned long cadata;
if(!sc_data)
return;
dprintf1("Sending key(%d) %c %d %x%x...%x\n", sc_data->cafd,
(ca_descr->parity ? 'O' : 'E'), ca_descr->index,
ca_descr->cw[0], ca_descr->cw[1], ca_descr->cw[7]);
cadata = (ca_descr->index << 1) | (ca_descr->parity==0 ? 0 : 1);
msg_send(MSG_LOW_PRIORITY, MSG_CAMUPDATE, sc_data->virt, (void *)cadata);
if(sc_data->cafd >= 0) {
//Using a real CA
ca_descr_t tmp_dscr;
memcpy(&tmp_dscr, ca_descr, sizeof(tmp_dscr));
tmp_dscr.index--;
if(ioctl(sc_data->cafd,CA_SET_DESCR,&tmp_dscr)<0) {
dprintf0("CA_SET_DESCR failed (%s)\n", strerror(errno));
} else {
update_keys(sc_data->virt, 'N', ca_descr->index, NULL, 0);
}
} else {
update_keys(sc_data->virt, (ca_descr->parity==0) ? 'E' : 'O',
ca_descr->index, ca_descr->cw, 0);
}
}
| void _SetCaPid | ( | int | adapter, |
| ca_pid_t * | ca_pid | ||
| ) |
Definition at line 182 of file plugin_cam.c.
References sc_data::cafd, dprintf0, dprintf1, find_sc_from_adpt(), NULL, update_keys(), and sc_data::virt.
Referenced by start_loopbackca().
{
struct sc_data *sc_data = find_sc_from_adpt(adapter);
if(!sc_data)
return;
dprintf1("Sending (%d) key P %d PID: %d\n", sc_data->virt, ca_pid->index,
ca_pid->pid);
if(sc_data->cafd >= 0) {
//Using a real CA
ca_pid_t tmp_pid;
memcpy(&tmp_pid, ca_pid, sizeof(tmp_pid));
tmp_pid.index--;
if(ioctl(sc_data->cafd,CA_SET_PID,&tmp_pid) < 0 && tmp_pid.index > 0) {
dprintf0("CA_SET_PID failed (%s)\n", strerror(errno));
}
}
update_keys(sc_data->virt, 'P', ca_pid->index, NULL, ca_pid->pid);
}
Definition at line 135 of file plugin_cam.c.
References sascCam::AddPrg(), sc_data::cam, cam_epid::epid, cam_epid::list, list_add(), list_del(), list_entry, list_for_each, MAXDPIDS, and cam_epid::sid.
Referenced by process_cam().
{
//struct ScLink link;
struct list_head *ptr;
struct cam_epid *cam_epid1;
int epidlist[MAXDPIDS], *epidptr = epidlist;
list_del(&cam_epid->list);
list_for_each(ptr, &pid_list) {
cam_epid1 = list_entry(ptr, struct cam_epid);
if(cam_epid1->sid == cam_epid->sid)
*(epidptr++) = cam_epid1->epid;
}
*epidptr = 0;
sc_data->cam->AddPrg(cam_epid->sid,epidlist,0,0);
//PrepareScLink(&link, sc_data->dev, OP_DELPID);
//link.data.pids.pid=cam_epid->epid;
//link.data.pids.type=cam_epid->type;
//DoScLinkOp(sc, &link);
list_add(&cam_epid->list, &pid_empty_queue);
}
| void connect_cam | ( | struct parser_adpt * | pc_all | ) |
Definition at line 526 of file plugin_cam.c.
References ATTACH_CALLBACK, sc_data::cafd, sc_data::cam, cmd, parser_cmds::common, parser_adpt::demux, dmxclose_call(), dmxioctl_call(), dmxread_call(), dprintf0, free, parser_adpt::frontend, init_sc(), sc_data::list, list_add(), list_entry, list_for_each, open(), opt_budget, opt_fixcat, plugin_cmd::plugin, plugin_cmdlist, PLUGIN_GETSID, parser_cmds::post_read, parser_cmds::pre_close, parser_cmds::pre_ioctl, sc_data::real, common_data::real_adapt, scCap, plugin_cmd::send_msg, cPlugin::SetupParse(), sc_data::valid, sc_data::virt, and common_data::virt_adapt.
{
int cardnum = pc_all->frontend->common->real_adapt;
struct list_head *ptr;
char *cadev;
char tmpstr[5];
struct sc_data *sc_data;
if(! sc)
if(! init_sc())
return;
sc_data = (struct sc_data *)malloc(sizeof(struct sc_data));
memset(sc_data, 0, sizeof(struct sc_data));
sprintf(tmpstr," %d",cardnum+1);
strncat(scCap, tmpstr, 80);
sc->SetupParse("ScCaps",scCap);
sc_data->valid = 0;
sc_data->virt = pc_all->frontend->common->virt_adapt;
sc_data->real = cardnum;
sc_data->cam = new sascCam(cardnum);
if (opt_budget) {
sc_data->cafd = -1;
} else {
asprintf(&cadev, "/dev/dvb/adapter%d/ca0", cardnum);
sc_data->cafd = open(cadev, O_RDWR|O_NONBLOCK);
if (sc_data->cafd >= 0) {
ca_caps_t ca_caps;
if (ioctl(sc_data->cafd, CA_GET_CAP, &ca_caps) == 0 &&
ca_caps.slot_num > 0 && (ca_caps.slot_type & CA_CI_LINK)) {
dprintf0("Found a FF card\n");
} else {
sc_data->cafd = -1;
}
}
free(cadev);
}
list_add(&sc_data->list, &sclist);
if(opt_fixcat) {
ATTACH_CALLBACK(&pc_all->demux->pre_ioctl, dmxioctl_call, 0);
ATTACH_CALLBACK(&pc_all->demux->post_read, dmxread_call, 0);
ATTACH_CALLBACK(&pc_all->demux->pre_close, dmxclose_call, 0);
}
list_for_each(ptr, &plugin_cmdlist) {
struct plugin_cmd *cmd = list_entry(ptr, struct plugin_cmd);
if(cmd->plugin == PLUGIN_GETSID) {
cmd->send_msg(pc_all->frontend, 1);
break;
}
}
}
| unsigned int crc32 | ( | const unsigned char * | d, |
| int | len, | ||
| unsigned int | crc | ||
| ) |
Definition at line 409 of file plugin_cam.c.
Referenced by replace_cat().
| static void dmxclose_call | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 514 of file plugin_cam.c.
References poll_ll::fd, fd, fdmap_list::list, list_add(), list_del(), and ll_find_elem.
Referenced by connect_cam().
{
struct fdmap_list *fd_map;
ll_find_elem(fd_map, fdmap_ll, fd, fdptr->fd, struct fdmap_list);
if(fd_map) {
list_del(&fd_map->list);
list_add(&fd_map->list, &fdmap_empty_queue);
}
}
| static void dmxioctl_call | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 484 of file plugin_cam.c.
References fdmap_list::fd, poll_ll::fd, fd, fdmap_list::list, list_add(), ll_find_elem, fdmap_list::pid, and pop_entry_from_queue.
Referenced by connect_cam().
{
struct fdmap_list *fd_map;
int pid;
ll_find_elem(fd_map, fdmap_ll, fd, fdptr->fd, struct fdmap_list);
if(fd_map)
return;
if(cmd == DMX_SET_FILTER) {
struct dmx_sct_filter_params *dmx =
(struct dmx_sct_filter_params *)data;
pid = dmx->pid;
} else if(cmd == DMX_SET_PES_FILTER) {
struct dmx_pes_filter_params *dmx =
(struct dmx_pes_filter_params *)data;
pid = dmx->pid;
//supporting PES filters means parsing dvr. let's skip that for now.
return;
} else {
return;
}
//This is a hack. We need to get the pmt handels from the pat like getsid
if(pid > 100)
return;
pop_entry_from_queue(fd_map, &fdmap_empty_queue, struct fdmap_list);
fd_map->fd = fdptr->fd;
fd_map->pid = pid;
list_add(&fd_map->list, &fdmap_ll);
}
| static void dmxread_call | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 473 of file plugin_cam.c.
References poll_ll::fd, fd, ll_find_elem, parser_cmds::mmap, fdmap_list::pid, and replace_cat().
Referenced by connect_cam().
{
struct fdmap_list *fd_map;
ll_find_elem(fd_map, fdmap_ll, fd, fdptr->fd, struct fdmap_list);
if(! fd_map)
return;
replace_cat(pc->mmap, *ret, fd_map->pid);
}
| static struct sc_data* find_sc_from_adpt | ( | int | adapter | ) | [static, read] |
Definition at line 129 of file plugin_cam.c.
References ll_find_elem, and sc_data::real.
Referenced by _SetCaDescr(), _SetCaPid(), and process_cam().
{
struct sc_data *sc_data;
ll_find_elem(sc_data, sclist, real, adapter, struct sc_data);
return sc_data;
}
| char* get_camdir | ( | ) |
Definition at line 44 of file plugin_cam.c.
References opt_camdir.
Referenced by connect_scan().
{ return opt_camdir;}
| static int init_sc | ( | void | ) | [static] |
Definition at line 90 of file plugin_cam.c.
References _dbglvl, cmd, scopt_list::cmd, DBG_NAME, cPlugin::Description(), dprintf0, i, cPlugin::Initialize(), PLUGIN_ID, scCap, SetCAMPrint(), cPlugin::SetupParse(), cPlugin::Start(), scopt_list::value, VDRPluginCreator(), and cPlugin::Version().
Referenced by connect_cam().
{
sc=(cPlugin *)VDRPluginCreator();
dprintf0("initializing plugin: SoftCam (%s): %s\n", sc->Version(), sc->Description());
#ifndef __x86_64__
//I have no idea why 64bit systems crash with the redirect
SetCAMPrint(DBG_NAME, PLUGIN_ID, 0, &_dbglvl);
#endif
if (!sc->Initialize()) {
dprintf0("Failed to initialize sc\n");
return false;
}
dprintf0("starting plugin:\n");
if (!sc->Start()) {
dprintf0("Failed to start sc plugin\n");
return false;
}
memset(scCap, 0, 80);
sc->SetupParse("LoggerActive","2");
#ifdef USE_AUXSERVER
sc->SetupParse("Nagra2.AuxServerEnable", "1");
#ifdef AUXSERVER_PORT
sc->SetupParse("Nagra2.AuxServerPort", AUXSERVER_PORT);
#endif
#ifdef AUXSERVER_HOST
sc->SetupParse("Nagra2.AuxServerAddr", AUXSERVER_HOST);
#endif
#ifdef AUXSERVER_PASSWD
sc->SetupParse("Nagra2.AuxServerPass", AUXSERVER_PASSWD);
#endif
#endif
for(int i = 0; i < 32 && scopts[i].cmd[0] != '\0'; i++) {
dprintf0("Setting SC options: %s = %s\n", scopts[i].cmd, scopts[i].value);
sc->SetupParse(scopts[i].cmd, scopts[i].value);
}
return true;
}
| static void launch_cam | ( | ) | [static] |
Definition at line 582 of file plugin_cam.c.
References MSG_HOUSEKEEPING, MSG_LOW_PRIORITY, MSG_RECURRING, msg_send_replace(), and NULL.
{
//Call housecleaning every 60 seconds
msg_send_replace(MSG_LOW_PRIORITY, MSG_HOUSEKEEPING, 0, NULL,
60, MSG_RECURRING);
}
| LIST_HEAD | ( | sclist | ) |
| LIST_HEAD | ( | pid_list | ) |
| LIST_HEAD | ( | fdmap_empty_queue | ) |
| LIST_HEAD | ( | fdmap_ll | ) |
| LIST_HEAD | ( | pid_empty_queue | ) |
| static int parse_ca | ( | unsigned char * | buf, |
| int | len | ||
| ) | [static] |
| static struct option* parseopt_cam | ( | arg_enum_t | cmd | ) | [static, read] |
Definition at line 627 of file plugin_cam.c.
References ARG_HELP, ARG_INIT, cam_opt, Cam_Opts, scopt_list::cmd, dprintf0, externalAU, i, NULL, opt_budget, opt_camdir, opt_extau, and opt_fixcat.
{
if(cmd == ARG_INIT) {
return Cam_Opts;
}
if(cmd == ARG_HELP) {
printf(" --cam-budget : Force budget card mode\n");
printf(" --cam-dir <dir> : Set directory for sc files (default ./sc_files)\n");
printf(" --cam-nofixcat : Don't remove cat entries\n");
printf(" --cam-extau <cmd> : Execute cmd to retrieve updated keys\n");
printf(" --cam-scopts <cmd>: Set sc options (opt=value)\n");
return NULL;
}
if(! cam_opt)
return NULL;
switch(cam_opt) {
case 'b':
opt_budget = 1;
break;
case 'd':
strncpy(opt_camdir, optarg, sizeof(opt_camdir)-1);
opt_camdir[sizeof(opt_camdir)-1]=0;
break;
case 'e':
strncpy(opt_extau, optarg, sizeof(opt_extau)-1);
opt_extau[sizeof(opt_extau)-1]=0;
externalAU = opt_extau;
case 'f':
opt_fixcat = 0;
break;
case 'o':
{
int i;
for(i = 0; i < 32 && scopts[i].cmd[0] != '\0'; i++)
;
if(i == 32) {
dprintf0("Too many SC options. Ignoring: %s\n", optarg);
} else {
char *pos =optarg;
while(*pos != '=' && *pos != '\0')
pos++;
if(*pos == '\0') {
dprintf0("Could not parse SC argument: %s\n", optarg);
} else {
memcpy(scopts[i].cmd, optarg, pos - optarg);
memcpy(scopts[i].value, pos+1, strlen(optarg) - (1+pos - optarg));
printf("here: %s %s %d\n", scopts[i].cmd, scopts[i].value, i);
if(i != 31)
scopts[i+1].cmd[0] = '\0';
}
}
break;
}
}
//must reset cam_opt after every call
cam_opt = 0;
return NULL;
}
| void process_cam | ( | struct msg * | msg, |
| unsigned int | priority | ||
| ) |
Definition at line 200 of file plugin_cam.c.
References cListBase::Add(), sascCam::AddPrg(), BCD2INT(), sid_msg::ca, sid_msg::calen, sc_data::cam, cam_del_pid(), Channels, msg::data, cListBase::Del(), cam_epid::delayclose, dprintf0, dprintf1, sid_msg::epid, cam_epid::epid, sid_msg::epid_count, find_sc_from_adpt(), cList< T >::First(), free_sidmsg(), nit_data::frequency, cPlugin::Housekeeping(), i, msg::id, nit_data::is_east, cList< T >::Last(), cam_epid::list, list_add(), list_empty(), list_entry, list_for_each, ll_find_elem, MAXAPIDS, MAXDPIDS, MSG_ADDSID, MSG_HOUSEKEEPING, MSG_PROCESSED, MSG_REMOVESID, MSG_RESETSID, cList< T >::Next(), sid_msg::nit, NULL, nit_data::orbit, nit_data::polarization, pop_entry_from_queue, cChannel::SetCableTransponderData(), cChannel::SetId(), cChannel::SetPids(), cChannel::SetSatTransponderData(), sid_msg::sid, cChannel::Sid(), cam_epid::sid, sascCam::Stop(), nit_data::symbolrate, sascCam::Tune(), cam_epid::type, nit_data::type, msg::type, update_keys(), sc_data::valid, and sc_data::virt.
{
struct list_head *ptr;
struct cam_epid *cam_epid;
struct sid_msg *sidmsg;
int match = 0;
cChannel *ch;
int vpid = 0, ppid = 0, tpid = 0, dcnt = 0;
int apid[MAXAPIDS], dpid[MAXDPIDS];
//struct ScLink link;
struct sc_data *sc_data;
if (msg->type == MSG_RESETSID) {
sc_data = find_sc_from_adpt(msg->id);
assert(sc_data);
dprintf1("Got MSG_RESETSID\n");
while(! list_empty(&pid_list)) {
cam_epid = list_entry(pid_list.next, struct cam_epid);
cam_del_pid(sc_data, cam_epid);
}
sc_data->cam->Stop();
//PrepareScLink(&link, sc_data->dev, OP_TUNE);
//link.data.tune.source=0;
//link.data.tune.transponder=0;
//DoScLinkOp(sc, &link);
//sc_data->dev->SetChannelDevice(0, 0);
update_keys(sc_data->virt, 'I', 0, NULL, 0);
sc_data->valid = 0;
msg->type = MSG_PROCESSED;
return;
}
if (msg->type == MSG_REMOVESID) {
unsigned int sid = 0xffff & (unsigned long)(msg->data);
dprintf1("Got MSG_REMOVESID with sid: %d\n", sid);
//delay removal of pids so we can continue to watch for key-rolls
list_for_each(ptr, &pid_list) {
cam_epid = list_entry(ptr, struct cam_epid);
if(cam_epid->sid == sid) {
dprintf1("Mapped sid to %d\n", cam_epid->epid);
cam_epid->delayclose = 1;
//update_keys('C', 0, NULL, cam_epid->epid);
//cam_del_pid(sc_data, cam_epid);
}
}
msg->type = MSG_PROCESSED;
return;
}
if (msg->type == MSG_HOUSEKEEPING) {
sc->Housekeeping();
msg->type = MSG_PROCESSED;
return;
}
if (msg->type != MSG_ADDSID)
return;
sc_data = find_sc_from_adpt(msg->id);
assert(sc_data);
sidmsg = (struct sid_msg *)msg->data;
if (sidmsg->calen == 0) {
free_sidmsg(sidmsg);
return;
}
for(ch=Channels.First(); ch; ch=Channels.Next(ch)) {
if((unsigned int)ch->Sid() == sidmsg->sid) {
match = 1;
break;
}
}
if(match) {
//if the sid is the same as last time, and a tune hasn't happened, we're
//already good to go
if(sc_data->valid) {
list_for_each(ptr, &pid_list) {
cam_epid = list_entry(ptr, struct cam_epid);
if(cam_epid->delayclose && cam_epid->sid == sidmsg->sid) {
dprintf1("Reenabling delayed-closed sid: %d\n", sidmsg->sid);
cam_epid->delayclose = 0;
}
}
free_sidmsg(sidmsg);
return;
}
} else {
//the sid is different, but we may be on the same transponder, so clear
//all delayed-close pids before proceeding
while (1) {
ll_find_elem(cam_epid, pid_list, delayclose, 1, struct cam_epid);
if(cam_epid == NULL)
break;
dprintf1("Mapped sid %d to epid %d\n", cam_epid->sid, cam_epid->epid);
update_keys(sc_data->virt, 'C', 0, NULL, cam_epid->epid);
for(ch=Channels.First(); ch; ch=Channels.Next(ch)) {
if((unsigned int)ch->Sid() == cam_epid->sid) {
Channels.Del(ch);
break;
}
}
cam_del_pid(sc_data, cam_epid);
}
}
msg->type = MSG_PROCESSED;
//create new channel
memset(apid, 0, sizeof(int)*MAXAPIDS);
memset(dpid, 0, sizeof(int)*MAXDPIDS);
ch = new cChannel();
ch->SetId(0, 1, sidmsg->sid, 0);
if(sidmsg->nit.type==0x43) { //set source type to Satellite. Use orbit and E/W data
int source = 0x8000 | (BCD2INT(sidmsg->nit.orbit) & 0x7ff) | ((int)sidmsg->nit.is_east << 11);
static char Polarizations[] = { 'h', 'v', 'l', 'r' };
ch->SetSatTransponderData(source, BCD2INT(sidmsg->nit.frequency)/100, Polarizations[sidmsg->nit.polarization], BCD2INT(sidmsg->nit.symbolrate)/10, 0);
}
else if(sidmsg->nit.type==0x44) { //set source type to Cable
ch->SetCableTransponderData(0x4000, BCD2INT(sidmsg->nit.frequency)/10, 0, BCD2INT(sidmsg->nit.symbolrate)/10, 0);
}
dcnt = (MAXDPIDS >= sidmsg->epid_count) ?
sidmsg->epid_count : MAXDPIDS;
memcpy(dpid, sidmsg->epid, sizeof(int)*dcnt);
ch->SetPids(vpid, ppid, apid, NULL, dpid, NULL, tpid);
if(! sc_data->valid) {
sc_data->valid = 1;
while(Channels.First())
Channels.Del(Channels.First());
}
Channels.Add(ch);
if(Channels.First() == Channels.Last()) {
sc_data->cam->Tune(ch);
//This is the first channel
//PrepareScLink(&link, sc_data->dev, OP_TUNE);
//link.data.tune.source=ch->Source();
//link.data.tune.transponder=ch->Transponder();
//dprintf0("Sending Tune cmd to SC\n");
//DoScLinkOp(sc, &link);
dprintf0("SC completed Tune cmd\n");
}
int i, epidlist[MAXDPIDS], *epidptr = epidlist;
for(i=0; i < sidmsg->epid_count && i < MAXDPIDS; i++) {
pop_entry_from_queue(cam_epid, &pid_empty_queue, struct cam_epid);
cam_epid->delayclose = 0;
cam_epid->epid = sidmsg->epid[i];
cam_epid->type = 5; //epid->type;
cam_epid->sid = sidmsg->sid;
list_add(&cam_epid->list, &pid_list);
*(epidptr++) = sidmsg->epid[i];
dprintf1("Adding pid %d for sid %d to pidlist\n", cam_epid->epid, cam_epid->sid);
//PrepareScLink(&link, sc_data->dev, OP_ADDPID);
//link.data.pids.pid=epid->epid;
//link.data.pids.type = 5; //epid->type;
//DoScLinkOp(sc, &link);
}
*epidptr = 0;
sc_data->cam->AddPrg(sidmsg->sid,epidlist,sidmsg->ca,sidmsg->calen);
free_sidmsg(sidmsg);
}
| static void replace_cat | ( | unsigned char * | buf, |
| int | len, | ||
| int | pid | ||
| ) | [static] |
Definition at line 436 of file plugin_cam.c.
References count, crc32(), dprintf1, and parse_ca().
Referenced by dmxread_call().
{
int desc_len, count;
int found = 0;
int pos = 0;
if(len > 0) {
if (buf[0] == 0x02) {
count = (((buf[1] & 0x03) << 8) | buf[2]) + 3 - 4;
desc_len = ((buf[10] & 0x03) << 8) | buf[11];
if(desc_len > len - 12 || count > len) {
//bogus data
return;
}
found+=parse_ca(buf+12, desc_len);
//handle epids here
for(pos = 12 + desc_len; pos < count;) {
desc_len = ((buf[pos+3] & 0x03) << 8) | buf[pos+4];
if(pos+desc_len +5 > count) {
//bogus data
return;
}
found+=parse_ca(buf+pos+5, desc_len);
pos += desc_len + 5;
}
if(found) {
//compute CRC32
int crc = crc32(buf, len-4, 0xFFFFFFFF);
buf[len-4] = (crc >> 24) & 0xff;
buf[len-3] = (crc >> 16) & 0xff;
buf[len-2] = (crc >> 8) & 0xff;
buf[len-1] = (crc >> 0) & 0xff;
}
dprintf1("Replaced %d cas on pid %d (len=%d)\n", found, pid, len);
}
}
}
| void SetCAMPrint | ( | const char * | _plugin_name, |
| unsigned int | plugin_id, | ||
| unsigned int | _print_level, | ||
| unsigned int * | _log_level | ||
| ) |
Definition at line 15 of file log.cpp.
References log_level, LogPrintSasc(), plugin_name, print_level, and cLogging::SetLogPrint().
Referenced by init_sc().
{
plugin_name = _plugin_name;
id = plugin_id;
log_level = _log_level;
print_level = _print_level;
cLogging::SetLogPrint(&LogPrintSasc);
}
| static void shutdown_cam | ( | ) | [static] |
Definition at line 589 of file plugin_cam.c.
References sc_data::cafd, list_entry, list_for_each, NULL, sc, cPlugin::Stop(), and sc_data::valid.
| void update_keys | ( | int | , |
| unsigned | char, | ||
| int | , | ||
| unsigned char * | , | ||
| int | |||
| ) |
Definition at line 81 of file plugin_ffdecsa.c.
References dprintf0, dprintf1, ENCRYPTED_NOT_READY, keyindex::even, FF_MAX_IDX, find_csa_from_adpt(), i, pid::index, csastruct::keyindex, csastruct::keylock, pid::list, list_add(), list_del(), list_empty(), list_entry, list_lock, ll_find_elem, list_head::next, csastruct::nexus_fixup, NOT_ENCRYPTED, NULL, keyindex::odd, pid::pid, csastruct::pid_map, pop_entry_from_queue_l, push_empty_queue, keyindex::queued, csastruct::state, csastruct::state_lock, keyindex::status, and keyindex::valid.
Referenced by _SetCaDescr(), _SetCaPid(), and process_cam().
{
int i;
struct pid *pid_ll;
struct csastruct *csa = find_csa_from_adpt(adpt);
if(key == NULL) {
dprintf0("Got command(%d): %c idx: %d pid: %d\n", adpt, keytype, index,
pid);
} else {
dprintf0("Got command(%d): %c idx: %d pid: %d key: "
"%02x%02x...%02x\n", adpt, keytype, index, pid,
key[0], key[1], key[7]);
}
assert(csa);
if(! csa)
return;
if(index < 0 || index >= FF_MAX_IDX)
return;
pthread_mutex_lock(&csa->state_lock);
if (keytype == 'I') //Invalidate
{
csa->state = NOT_ENCRYPTED;
dprintf1("Setting state: NOT_ENCRYPTED\n");
pthread_mutex_lock(&csa->keylock);
for(i=0; i < FF_MAX_IDX; i++)
csa->keyindex[i].valid = 0;
//csa_ready = 0;
pthread_mutex_unlock(&csa->keylock);
while(! list_empty(&csa->pid_map)) {
pid_ll = list_entry(csa->pid_map.next, struct pid);
list_del(&pid_ll->list);
push_empty_queue(&pid_ll->list, &pidmap_empty_queue);
}
pthread_mutex_unlock(&csa->state_lock);
return;
}
if (keytype == 'P') //PID
{
ll_find_elem(pid_ll, csa->pid_map, pid, pid, struct pid);
if(pid_ll) {
pthread_mutex_unlock(&csa->state_lock);
return;
}
if(! csa->keyindex[index].valid) {
csa->keyindex[index].valid = 1;
csa->keyindex[index].status = 0;
csa->keyindex[index].queued = 0;
}
pop_entry_from_queue_l(pid_ll, &pidmap_empty_queue, struct pid, &list_lock);
pid_ll->pid = pid;
pid_ll->index = index;
list_add(&pid_ll->list, &csa->pid_map);
pthread_mutex_unlock(&csa->state_lock);
dprintf1("Adding pid %d to list\n", pid);
return;
}
if (keytype == 'C') //Close PID
{
ll_find_elem(pid_ll, csa->pid_map, pid, pid, struct pid);
if(pid_ll) {
index = pid_ll->index;
list_del(&pid_ll->list);
push_empty_queue(&pid_ll->list, &pidmap_empty_queue);
ll_find_elem(pid_ll, csa->pid_map, index, index, struct pid);
if(pid_ll == NULL) {
//no valid pids on this index
csa->keyindex[index].status = 0;
if(list_empty(&csa->pid_map)) {
//state = ENCRYPTED_NOT_READY;
csa->state = NOT_ENCRYPTED;
dprintf1("Setting state: NOT_ENCRYPTED\n");
}
}
}
pthread_mutex_unlock(&csa->state_lock);
dprintf1("Removing pid %d to list state = %d\n", pid, csa->state);
return;
}
ll_find_elem(pid_ll, csa->pid_map, index, index, struct pid);
if(pid_ll == NULL) {
pthread_mutex_unlock(&csa->state_lock);
return;
}
pthread_mutex_lock(&csa->keylock);
if (keytype == 'E') //Even
{
memcpy( csa->keyindex[index].even, key, 8);
csa->keyindex[index].queued |= 0x02;
csa->keyindex[index].status |= 0x02;
if(csa->state == NOT_ENCRYPTED && csa->keyindex[index].status == 3) {
csa->state = ENCRYPTED_NOT_READY;
dprintf1("Setting state: ENCRYPTED_NOT_READY\n");
}
dprintf1("Processed Even Key (idx=%d): State = %d, ready = %d\n",
index, csa->state, csa->keyindex[index].status);
}
else if (keytype == 'O') //Odd
{
memcpy( csa->keyindex[index].odd, key, 8);
csa->keyindex[index].queued |= 0x01;
csa->keyindex[index].status |= 0x01;
if(csa->state == NOT_ENCRYPTED && csa->keyindex[index].status == 3) {
csa->state = ENCRYPTED_NOT_READY;
dprintf1("Setting state: ENCRYPTED_NOT_READY\n");
}
dprintf1("Processed Odd Key (idx=%d): State = %d, ready = %d\n",
index, csa->state, csa->keyindex[index].status);
}
else if (keytype == 'N') //Nexus
{
csa->nexus_fixup = 1;
if(csa->state == NOT_ENCRYPTED) {
csa->state = ENCRYPTED_NOT_READY;
dprintf1("Setting state: ENCRYPTED_NOT_READY\n");
}
}
pthread_mutex_unlock(&csa->keylock);
pthread_mutex_unlock(&csa->state_lock);
return;
}
| static void usermsg_cam | ( | char * | str | ) | [static] |
Definition at line 609 of file plugin_cam.c.
References data, and cPlugin::SVDRPCommand().
{
char *data;
cString outstr;
int res;
if(sc) {
printf(":: %s ||\n", str);
data = strchr(str, ' ');
if(data) {
*data = '\0';
data++;
}
printf("User Message %s data: %s\n", str, data);
outstr = sc->SVDRPCommand((const char *)str, (const char *)data, res);
printf("%s",*outstr);
printf("User Message %s returned: %d\n", str, res);
}
}
int cam_opt = 0 [static] |
Definition at line 40 of file plugin_cam.c.
Referenced by parseopt_cam().
struct option Cam_Opts[] [static] |
{
{"cam-budget", 0, &cam_opt, 'b'},
{"cam-dir", 1, &cam_opt, 'd'},
{"cam-nofixcat", 0, &cam_opt, 'f'},
{"cam-extau", 1, &cam_opt, 'e'},
{"cam-scopts", 1, &cam_opt, 'o'},
{0, 0, 0, 0},
}
Definition at line 46 of file plugin_cam.c.
Referenced by parseopt_cam().
unsigned int crc_table[256] [static] |
Definition at line 364 of file plugin_cam.c.
Referenced by crc32().
| const char* externalAU |
Definition at line 879 of file data.c.
Referenced by main(), parseopt_cam(), and cScPlugin::ProcessArgs().
int opt_budget = 0 [static] |
Definition at line 41 of file plugin_cam.c.
Referenced by connect_cam(), and parseopt_cam().
char opt_camdir[256] = {"./sc_files"} [static] |
Definition at line 43 of file plugin_cam.c.
Referenced by cPlugin::ConfigDirectory(), get_camdir(), and parseopt_cam().
char opt_extau[256] [static] |
Definition at line 45 of file plugin_cam.c.
Referenced by parseopt_cam().
int opt_fixcat = 1 [static] |
Definition at line 42 of file plugin_cam.c.
Referenced by connect_cam(), and parseopt_cam().
struct plugin_cmd plugin_cmds [static] |
{{NULL, NULL}, PLUGIN_ID, "cam",
parseopt_cam, connect_cam, launch_cam, process_cam, NULL,
shutdown_cam, usermsg_cam}
Definition at line 687 of file plugin_cam.c.
Definition at line 82 of file plugin_cam.c.
Referenced by cSmartCardSlot::Action(), cSmartCards::LockCard(), and shutdown_cam().
char scCap[80] [static] |
Definition at line 83 of file plugin_cam.c.
Referenced by connect_cam(), and init_sc().
| struct scopt_list scopts[32] = {{{'\0'}}} |
Definition at line 80 of file plugin_cam.c.