⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvbo.cpp

📁 Example Dreambox CAM source code
💻 CPP
字号:
//===========================================================// DVB object (C++)// Handles all DVB stream analysis, in particular PSI data// Code is independent of encryption scheme used// (c) Aug 2008 by Dirktator//===========================================================#include "dvbo.h"#include "/data/dreambox/tuxbox-bb/build/tmp/staging/powerpc-linux/include/ost/dmx.h"	#include <fcntl.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>//Constructor method, initializes the required variablesdvbo_handler::dvbo_handler(int progid, int dmx_fd, int debug){	int i;	fd 			= dmx_fd;						//just forward the demux file handle into an object-wide variable, saves a lot of passing of variables via function params!	dbg			= debug;						//idem for debug flag	ECMpidcount = 0;	lock		= 0;							//We start with a state where no valid cardserver/EMU was identified 	for (i=0;i<20;i++) 							//clean ECMpids array	{ 		ECMpids[i].CA_PID		= 0; 		ECMpids[i].CA_System_ID	= 0;	}}//Filter using the demux device; DVB API 1//return 0 on error, nonzero on okint dvbo_handler::Set_Filter(int pid, char filt, char mask){	struct dmxSctFilterParams sFP;	if (dbg) printf("Set filter pid:%d, value:%d...",pid, filt);	memset(&sFP,0,sizeof(sFP));  	sFP.pid     			= pid;  	sFP.timeout 			= 5000;		//wait max 5 seconds for ECM message  	sFP.flags   			= DMX_IMMEDIATE_START;  	sFP.filter.filter[0] 	= filt;  	sFP.filter.mask[0] 		= mask;      	if (ioctl(fd, DMX_SET_FILTER, &sFP) < 0)    	{    	perror(" Status");    	return 0;  	}	if (dbg) printf(" success!\n");	return 1;}//Stop filteringint dvbo_handler::Stop_Filter(void){	if (dbg) printf("Stopping filtering...");  	if (ioctl(fd,DMX_STOP)<0)	{		perror(" Stop filter");		return 0;	}	if (dbg) printf(" success!\n");	return 1;}//Read and analyze the Program Allocation Table (id=0)//input: 	program number and demux device handler//returns: 	Program Map Table (PMT) idint dvbo_handler::Parse_PAT(int prognr){	char 	buffer[4096];	int 	i, j, n, seclen;	char 	nib1, nib2;		//nibble1 and 2	int		pnr, pmtnr;	//General fields	printf("Parsing PAT, searching for PMT of SID %d\n",prognr);	n=read(fd,buffer,4096);		if (dbg) 	{		printf("\tRead %d bytes\n",n);		for (j=0;j<n;j+=16)							//dump PAT data		{			printf("\t%04x: ",j);			for (i=0;i<16;i++) printf("%02x ",buffer[j*16+i]);			printf("\n");		}		printf("\ttable_id:%d\n",buffer[0]);		//8bit	}	nib2=(buffer[1]&0xF)<<4;		seclen=nib2; seclen=(seclen<<4)+buffer[2];		//12bit	if (dbg) printf("\tsection_length:%d\n",seclen);		//PMT entries start as of byte 8	//Each entry consists of:	i=8; pnr=0; pmtnr=0;	while (i<seclen)								//section counter	{			pnr=buffer[i]<<8;		pnr+=buffer[i+1];		if (pnr==prognr) 							//Found it! Now read 13 PMT id bits		{			pmtnr=((buffer[i+2]<<8) + buffer[i+3])&0x1fff; //13 bits masking, skip first 3 bits			printf("\tPMTid: %04x(%04d)\n",pmtnr,pmtnr);				break;		}		i+=4;						//next section	}	if (pnr!=prognr)	{		perror("\tPMT id not found!");		return 0;	}	else return pmtnr;}//Read a CA descriptor section from the stream, buffer is the streambuffer, i is the index to start parsing//input:	pointer to data from the PMT containing CA data, length of the buffer//returns: 	nothingvoid dvbo_handler::Parse_CA_Descriptor_Section(char *buf, int cplen){	char cabuf[4096];	int  x, j, capid, ptr=0;		cabuf[0]=0;	for (x=0;x<cplen+2;x++) cabuf[x]=buf[x];	//just bluntly copy all data in buf to the local buffer....		if (dbg)	{		printf("\t\tCA Descr Section: ");		for (j=0;j<cplen;j++) printf("%02x ",cabuf[j]); 	}		int 	casys=(cabuf[2]<<8)+cabuf[3];	char 	caSys[255];	if (dbg) 		switch (casys&0xff00)		{			case 0x600: 	sprintf(caSys,"Irdeto"); break;			case 0x100: 	sprintf(caSys,"Seca"); break;			case 0x1700: 	sprintf(caSys,"Betacrypt"); break; 			case 0x1800: 	sprintf(caSys,"Nagra (Kudelski)"); break;			case 0x0900:	sprintf(caSys,"News Datacom - VideoGuard"); break;			case 0x0b00:	sprintf(caSys,"Conax"); break;			case 0x0d00: 	sprintf(caSys,"Philips Cryptoworks"); break;			default:		sprintf(caSys,"Unknown (%04x)", casys);		}	capid=((cabuf[4]<<8) + cabuf[5])&0x1fff; 	//13 bits masking, skip first 4 bits		//now update global ECMpids array		ECMpids[ECMpidcount].CA_PID=capid;			//add the PID	ECMpids[ECMpidcount].CA_System_ID=casys;	//add the system id	ECMpidcount++;	if (dbg) printf("\n\t\t\t=> CA PID[%d]: %04x (%d), type: %04x (%s)\n",ECMpidcount, capid, capid, casys,caSys);	}//Read the PMT and get the CA pid//	CA sections are indicated by a value of 0x09 in the program_info field or 0x09 in the ES_info field//  returns the amount of CA descriptors read;int dvbo_handler::Parse_PMT(int prognr){	char 	buffer[4096];	int 	i,j,n;	int 	capid, eslen, seclen, stype;	//Object property variable maintenance	ECMpidcount=0;		//when Parse_PMT is called we need to fill the ECMpids table from scratch!	printf("Parsing PMT to find CA pid\n");	n=read(fd,buffer,4096);		//read the data from the stream	if (dbg) 	{		printf("\tRead %d bytes\n",n);		//dump hex table		for (j=0;j<n;j+=16)			{			printf("\t%04x: ",j);			for (i=0;i<16;i++) printf("%02x ",buffer[j+i]);			printf("\n");		}	}		//section length	seclen=((buffer[1]<<8) + buffer[2])&0x0fff;	//12 bits masking	if (dbg) printf("\tSection length: %d\n", seclen);	//Program_Info_Length	int pil=0;		pil= ( (buffer[10]<<8) + buffer[11])&0x0fff; 		//12 bits masking, skip first 4 bits	if (dbg) printf("\tProgram Info Section (length: %d)\n",pil);	//program_info section	int cnt=12;  //start of pil subsections	while(cnt<pil+17)	{		int dtag=buffer[cnt]; 		//printf("\t\tDtag: %02x ",dtag);		int delen=buffer[cnt+1]; 	//printf("Des length: %d\n",delen);		if (delen==0)		{			printf("Error\n");							break;		} 		if (dtag==0x09) Parse_CA_Descriptor_Section(&buffer[cnt],delen);		cnt+=(delen+2);	}	//Video stream descriptor sections	if (dbg) printf("\tES Info Section\n");	int sec_start=12+pil;			//first section	while (sec_start<(seclen-4))   	//note 4 last bytes are CRC, so do not try to read these!	{		//streamtype		stype=buffer[sec_start];		//if (stype==0x02) printf("\tStreamtype: video (0x02)\n");				//if (stype==0x04) printf("\tStreamtype: audio (0x04)\n");		eslen=((buffer[sec_start+3]<<8)+buffer[sec_start+4])&0x0fff;	//12 bits		//printf("\tStreamtype: %02x; ES length: %d\n",stype, eslen);		//anaylyse ES info length section, can contain multiple subsections		int cnt=sec_start+5;		while(cnt<(eslen+sec_start+5))		{			int dtag=buffer[cnt]; 		//printf("\t\tDtag: %02x ",dtag);			int delen=buffer[cnt+1]; 	//printf("Des length: %d\n",delen);			if (delen==0)			{				printf("Error\n");				break;			} 			//dtag=0x09 is CA information, streamtype=0x02 is video			if ((stype==0x02)&&(dtag==0x09)) Parse_CA_Descriptor_Section(&buffer[cnt],delen);	//for now only consider VIDEO ECM messages!!!			cnt+=(delen+2);		}		sec_start+=(eslen+5); 	}	return(ECMpidcount);}//Parse the CA section, goal: to retrieve the buffer that contains the control words//Inputs:	demux file handler; the capid is just passed for debug reasons//Output:	sets the object property ECMbuffer which contains the encrypted ECM packet and returns the providerid found in the ECMint dvbo_handler::Parse_ECM(int capid){	char 	ch;	int 	n,j,i, calen, ecmlen, provid;		if (dbg) printf("Parsing CA pid %04x (%04d)\n",capid,capid);	for (i=0;i<4096;i++) 		ECMbuffer[i]=0;		ECMbufsize = read(fd,ECMbuffer,184);				//read the data from the stream, set the object property ECMbufsize	if (dbg) 	{			printf("\tRead %d bytes\n",ECMbufsize);		printf("\tTable-id: %02x\n",ECMbuffer[0]);	}	calen=((ECMbuffer[1]<<8)+ECMbuffer[2])&0x0fff;		//12 bits, useless data at the moment, maybe when we start building EMU's....	if (dbg) printf("\tCA section length: %d\n",calen);	//Now parse the SECA specific data	provid=(ECMbuffer[3]<<8)+ECMbuffer[4];	if (dbg) printf("\t\tProvider ID:%04x\n",provid);		return(provid);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -