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

📄 sc-seca.cpp

📁 DVB-S的softcam源代码
💻 CPP
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdlib.h>#include <string.h>#include "common.h"#include "system.h"#include "system-common.h"#include "smartcard.h"#include "opts.h"#include "parse.h"#define SYSTEM_SECA          0x0100#define SYSTEM_NAME          "SC-Seca"#define SYSTEM_PRI           -5#define SYSTEM_CAN_HANDLE(x) ((x)==SYSTEM_SECA)#define SC_NAME "Seca"#define SC_ID   MAKE_SC_ID('S','e','c','a')#define SECADATE(buff,len,odate) { \                                 const unsigned char *dd=(odate); \                                 _snprintf(buff,len,"%04d/%02d/%02d", \                                   ((dd[0]&0xFE)>>1)+1990, \                                   ((dd[0]&0x01)<<3) + ((dd[1]&0xE0)>>5), \                                   dd[1]&0x1F); \                                 }static int blocker=0;static int ppv=false;// -- cSystemScSeca ---------------------------------------------------------------class cSystemScSeca : public cSystemScCore {public:	cSystemScSeca(void);};cSystemScSeca::cSystemScSeca(void):cSystemScCore(SYSTEM_NAME,SYSTEM_PRI,SC_ID,"SC Seca"){	hasLogger=true;	needsDescrData=true;}// -- cSystemLinkScSeca --------------------------------------------------------static const char *block[] = {	"allow ALL",	"block UNIQUE",	"block SHARED",	"block ALL"};class cSystemLinkScSeca : public cSystemLink {public:	cSystemLinkScSeca(void);	virtual bool CanHandle(unsigned short SysId);	virtual cSystem *Create(void) { return new cSystemScSeca; }};static cSystemLinkScSeca staticInit;cSystemLinkScSeca::cSystemLinkScSeca(void):cSystemLink(SYSTEM_NAME,SYSTEM_PRI){	opts=new cOpts(SYSTEM_NAME,2);	opts->Add(new cOptSel("Blocker","SC-Seca: EMM updates",&blocker,sizeof(block)/sizeof(char *),block));	cOpt *opt=new cOptBool("Ppv","SC-Seca: activate PPV",&ppv);	if(opt) opt->Persistant(false);	opts->Add(opt);	Feature.NeedsSmartCard();}bool cSystemLinkScSeca::CanHandle(unsigned short SysId){	SysId&=SYSTEM_MASK;	return smartcards.HaveCard(SC_ID) && SYSTEM_CAN_HANDLE(SysId);}// -- cProviderScSeca ----------------------------------------------------------class cProviderScSeca : public cProviderSeca {public:	int index;	unsigned char date[2], pbm[8];	char name[17];	//	cProviderScSeca(const unsigned char *pi, const unsigned char *s):cProviderSeca(pi,s) {}};// -- cSmartCardSeca -----------------------------------------------------------struct SecaProvInfo {	unsigned char prov[2];	char name[16];	unsigned char sa[3];	unsigned char cb;	unsigned char date[2];	unsigned char rr;	unsigned char rstart;	unsigned char pbm[8];	unsigned char rend;};class cSmartCardSeca : public cSmartCard, private cIdSet {private:	char datebuff[16];	//	const char *Date(const unsigned char *date);	bool CheckAccess(const unsigned char *data, const cProviderScSeca *p);public:	cSmartCardSeca(void);	virtual bool Init(void);	virtual bool Decode(const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw);};static const struct StatusMsg msgs[] = {	// ECM status messages	{ { 0x90,0x00 }, "Instruction executed without errors", true },	{ { 0x90,0x02 }, "Signature failed", false },	{ { 0x90,0x27 }, "Decoding the preview (non-error)", true },	{ { 0x93,0x01 }, "Expiration date crossed, check your subscription", false },	{ { 0x93,0x02 }, "No access, check your subscription", false },	{ { 0x96,0x00 }, "Chain of nonvalid entrance or null event or all the nanos process, none decoding", false },	// EMM update status messages	{ { 0x90,0x09 }, "Card update was not meant for this card", false },	{ { 0x90,0x19 }, "Card update successfull, PPUA updated", true },	{ { 0x97,0x00 }, "Card update was successful", true },	{ { 0x97,0x40 }, "Card update was successful", true },	{ { 0x97,0x50 }, "Card update was successful", true },	{ { 0x97,0x78 }, "Card update was not necessary", false },	{ { 0x97,0xe0 }, "EEPROM update was not necessary", false },	// unknown message	{ { 0xFF,0xFF }, 0, false }};static const struct CardConfig cardCfg = {	SM_8E2,2000,300};cSmartCardSeca::cSmartCardSeca(void):cSmartCard(&cardCfg,msgs){}bool cSmartCardSeca::Init(void){	static unsigned char ins0e[] = { 0xC1,0x0e,0x00,0x00,0x08 }; // get serial nr. (UA)	static unsigned char ins16[] = { 0xC1,0x16,0x00,0x00,0x07 }; // get nr. of providers	static unsigned char ins12[] = { 0xC1,0x12,0x00,0x00,0x19 }; // get provider info	static unsigned char ins34[] = { 0xC1,0x34,0x00,0x00,0x03 }; // request provider pbm (data=0x00 0x00 0x00)	static unsigned char ins32[] = { 0xC1,0x32,0x00,0x00,0x0A }; // get the pbm data (p1=provider)	static const unsigned char atrTester[] = { 0x0E,0x6C,0xB6,0xD6 };	if(atr->T!=0 || atr->histLen<7 || memcmp(&atr->hist[3],atrTester,4)) {		di(printf("smartcardseca: doesn't looks like a Seca card\n"))		return false;	}	infoStr.Begin();	infoStr.Strcat("Seca smartcard\n");	char *type;	switch(atr->hist[0]*256+atr->hist[1]) {		case 0x7070: type="Canal+"; break;		default:     type="Unknown"; break;	}	_snprintf(idStr,sizeof(idStr),"%s (%s %d.%d)",SC_NAME,type,atr->hist[2]&0x0F,atr->hist[2]>>4);	di(printf("smartcardseca: cardtype: %s %d.%d\n",type,atr->hist[2]&0x0F,atr->hist[2]>>4))	ResetIdSet();	unsigned char buff[MAX_LEN];	if(!IsoRead(ins0e,buff) || !Status()) {		di(printf("smartcardseca: reading card serial failed\n"))		return false;	}	SetCard(new cCardSeca(&buff[2]));	di(printf("smartcardseca: card serial number: %llu\n",Bin2LongLong(&buff[2],6)))	infoStr.Printf("Type: %s %d.%d  Serial: %llu\n",type,atr->hist[2]&0x0F,atr->hist[2]>>4,Bin2LongLong(&buff[2],6));	if(!IsoRead(ins16,buff) || !Status()) {		di(printf("smartcardseca: reading provider map failed\n"))		return false;	}	int provMap=buff[2]*256+buff[3];#ifdef DEBUG_ISO	{		int n=0, i=provMap;		do { n+=i&1; i>>=1; } while(i);		printf("smartcardseca: card has %d providers (0x%04x)\n",n,provMap);	}#endif	for(int i=0 ; i<16 ; i++) {		if(provMap&(1<<i)) {			di(printf("smartcardseca: reading info for provider index %d\n",i))			ins12[2]=i;			if(!IsoRead(ins12,buff) || !Status()) {				di(printf("smartcardseca: reading provider info failed\n"))				return false;			}			ins32[2]=i;			static const unsigned char ins34data[] = { 0x00,0x00,0x00 };			if(!IsoWrite(ins34,ins34data) || !Status() ||					!IsoRead(ins32,&buff[ins12[4]]) || !Status())				memset(&buff[ins12[4]],0xFF,ins32[4]); // fake PBM response if card doesn't support command			struct SecaProvInfo *spi=(struct SecaProvInfo *)buff;			cProviderScSeca *p=new cProviderScSeca(spi->prov,spi->sa);			if(p) {				AddProv(p);				p->index=i;				strn0cpy(p->name,spi->name,sizeof(p->name));				memcpy(p->date,spi->date,sizeof(p->date));				memcpy(p->pbm,spi->pbm,sizeof(p->pbm));			}			infoStr.Printf("Prov %x (%.16s) until %s\n",p->provId[0]*256+p->provId[1],p->name,Date(p->date));#ifdef DEBUG_ISO			char str[20];			printf("smartcardseca: provider 0x%02x%02x '%.16s' expires %s pbm %s\n",			p->provId[0],p->provId[1],p->name,Date(p->date),HexStr(str,p->pbm,sizeof(p->pbm)));#endif		}	}	infoStr.Finish();	return true;}const char *cSmartCardSeca::Date(const unsigned char *date){	SECADATE(datebuff,sizeof(datebuff),date);	return datebuff;}bool cSmartCardSeca::CheckAccess(const unsigned char *data, const cProviderScSeca *p){	int result=1;	return (result!=0);}bool cSmartCardSeca::Decode(const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw){	static unsigned char ins3c[] = { 0xC1,0x3c,0x00,0x00,0x00 }; // coding cw	static unsigned char ins3a[] = { 0xC1,0x3a,0x00,0x00,0x10 }; // decoding cw	static unsigned char ins30[] = { 0xC1,0x30,0x00,0x02,0x09 }; // view ppv (active bx record)	static unsigned char ins30data[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF };	cProviderScSeca *p=(cProviderScSeca *)FindProv(data);	if(p) { // && ecm->Data()) {		di(printf("smartcardseca: provider 0x%04x index %d '%.16s' (expires %s)\n",cParseSeca::ProvId(data),p->index,p->name,Date(p->date)))		if(CheckAccess(ecm->Data(),p)) {			if(ppv) {				di(printf("smartcardseca: activating PPV\n"))				if(IsoWrite(ins30,ins30data)) Status();				ppv=false;			}			const unsigned char *payload;			ins3c[2]=p->index | (cParseSeca::SysMode(data) & 0xF0);			ins3c[3]=cParseSeca::KeyNr(data);			ins3c[4]=cParseSeca::Payload(data,&payload);			if(IsoWrite(ins3c,payload) && Status() &&				IsoRead(ins3a,cw) && Status()) return true;		}		else di(printf("smartcardseca: update your subscription to view this channel\n"))	}	return false;}// -- cSmartCardLinkSeca -------------------------------------------------------class cSmartCardLinkSeca : public cSmartCardLink {public:  cSmartCardLinkSeca(void):cSmartCardLink(SC_NAME,SC_ID) {}  virtual cSmartCard *Create(void) { return new cSmartCardSeca(); }  };static cSmartCardLinkSeca staticScInit;

⌨️ 快捷键说明

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