📄 cam.cpp
字号:
//===========================================================// Main code (C++)// Handles demux & ca devices and joins all objects// Contains main program flow logic// Code is independent of encryption schemes used// (c) Aug 2008 by Dirktator//===========================================================//compatibility - change if using DVB API 3.0 instead of default 1.0// - change if non-PLI images used!#define CADEV "/dev/ca0" //CA device (Linux DVB API), note that /dev/dvb/card0/ca0 does not (always?) work! in PLi#define DMXDEV "/dev/dvb/card0/demux0" //Demultiplexer (Linux DVB API)#include <fcntl.h>#include "/data/dreambox/tuxbox-bb/build/tmp/staging/powerpc-linux/include/ost/ca.h"#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#include <sys/poll.h>#include <sys/socket.h>#include <sys/types.h>#include <stropts.h> #include <sys/un.h>#include <unistd.h>#include <errno.h>//Include the objects required for this cam#include "dvbo.h"#include "newcamd-client.h" #include "capmt.h" //Global variablesnewcamd_client *ncc; //newcamd client object pointerdvbo_handler *dvh; //DVB handler object pointerca_handler *cph; //CAPMT object pointerint ca, fd; //file handles for the demux and ca device//Main program loopint main(int argc,char* argv[]){ int prognr, pmtnr, provid; char srv_url[1024]; int dbg, n, m; //check if a debug cmd line parameter was given dbg = 0; if (argc==2) { if (!strncmp(argv[1],"-d",2)) dbg=1; if (!strncmp(argv[1],"-D",2)) dbg=1; if (dbg) printf("DEBUG mode\n\n\n"); } else printf("TCAM - NORMAL mode\n"); //start newcamd client, connect and login sprintf(srv_url,"newcamd://local:local@127.0.0.1:10000/0102030405060708091011121314/EMM"); if (ncc = new newcamd_client(srv_url,15000,VERSION_525), !ncc) { perror("NEWCAMD client"); return(0); } ncc->dbg=dbg; //open DMX device if ((fd = open(DMXDEV,O_RDWR)) < 0) { perror("DEMUX DEVICE"); return(0); } //open CA device if ((ca = open(CADEV,O_RDWR)) < 0) { perror("CA DEVICE"); return(0); } //Create CAPMT object and get current program number, pass debug flag to the constructor if (cph = new ca_handler(dbg), !cph) { perror("CAPMT object"); return(0); } // Main decryption loop while (1) //infinite loop { if (dbg) printf("INFINI LOOP\n"); prognr = cph->Read_CAPMT(); //Create new dvb_handler object to analyze the programs data from the DVB PSI, pass debug flag to the constructor if (dvh = new dvbo_handler(prognr, fd, dbg),!dvh) { perror("DVB object"); return(0); } //PAT section if (!dvh->Set_Filter(0,0,0xFF)) //We start looking at the PAT: filter on exact value 0x00 (so mask 0xFF) { perror("PAT"); return(0); } pmtnr = dvh->Parse_PAT(prognr); //Retrieve the PMTid from the PAT dvh->Stop_Filter(); //Done, stop filtering for the PAT //PMT section if (!dvh->Set_Filter(pmtnr,0x02,0xFF)) { perror("PMT"); return(0); //filter on PMT id and exact value 0x02, (so mask 0xFF) } if (!dvh->Parse_PMT(prognr)) //Parse_PMT returns numECMs and sets the dvh->numECMs variable { printf("Cannot find any ECM/EMMM pids!\n"); return(0); } printf("\t%d Video ECM/EMM pids identified\n",dvh->ECMpidcount); if (!dvh->lock) //already found a working ECM pid/CAid pair? { //====================================================================================================== //Now analyze ECMs, see if they can be sent to cardserver //if there is no match with the cardservers program id, launch an EMU (FUTURE!!!!) //====================================================================================================== for (n=0; n<dvh->ECMpidcount; n++) //try all video ECM pids received { dvh->Stop_Filter(); if (!dvh->Set_Filter(dvh->ECMpids[n].CA_PID,0x80,0xF0)) //filter on ECM pid and 0x80 or 0x81 (so mask 0xF0) { perror("ECM filtering"); return(0); } //Now its time to get the ECM data into the dvb->ECMbuffer and retrieve the providerid provid = dvh->Parse_ECM(dvh->ECMpids[n].CA_PID); if (dvh->ECMpids[n].CA_System_ID==ncc->card_caid) //Preselect on the encryption technology used { //Search through all providerids that the card has provided and try to match the one found in the ECM for (m=0; m < ncc->card_provider_id_count; m++) if (provid == ncc->card_provider_id[m]) { ncc->send_ecm(dvh->ECMbuffer, dvh->ECMbufsize, 0); if (!ncc->status) { dvh->lock = dvh->ECMpids[n].CA_PID; //confirm locked-status, so for next ECMs we do not have to check CAIDs and provids over and over again //the value of dvb->lock is the pointer into the ECMpids table printf("Locked with cardserver on provider %04x, CAid %04x - uses PID %04x\n", provid, dvh->ECMpids[n].CA_System_ID, dvh->lock); cph->write_control_words(ca, ncc->cw_0, ncc->cw_1,0); n=dvh->ECMpidcount; //end the for-n loop immediately } } } //switch } //for n } if (dvh->lock) //shortcut, loop to pass any ECM directly to the cardserver and write CWs as soon as we found some do { if (dbg) printf("LOCK_LOOP\n"); provid = dvh->Parse_ECM(dvh->lock); //yep, immediately select the ECM pointed to by the value of dvh->lock ncc->send_ecm(dvh->ECMbuffer, dvh->ECMbufsize, 0); if (!ncc->status) cph->write_control_words(ca, ncc->cw_0, ncc->cw_1,0); } while (cph->Read_CAPMT()==prognr); //keep decoding as long as the program does not change delete (dvh); //kill the DVB object to be able to create a fresh one for the new channel } //infinite loop} //main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -