VDR Plugin 'sc' Revision History
--------------------------------
+06.07.2007: Version 0.8.1
+- Added Nagra2 7101 3DES support.
+- Added a setup option to force tranfermode with digital audio. Another common
+ used patched for the vdr-core is made unnecessary by this option.
+- Fixed camd33 EMM packet processing.
+- Fixed recording device allocation (1.4.x). You have to update the VDR core
+ patch. Thanks to dingo35.
+- Fixed compiling with VDR 1.5.0.
+
22.06.2007: Version 0.8.0
+- Added Nagra2 0501 MECM support.
- Added support for Nagra smartcards. Code is not well tested. Volunteers
welcome. Timing is tricky, so you have to get cardreader clock AND -C
parameter right.
LBSTARTF(L_CORE_CSA);
LBPUT("decrypting %3d packets (ccs=%3d cs=%3d %s)",ccs,ccs,cs,ccs>=cs?"OK ":"INC");
int n=decrypt_packets(keys[currIdx],range);
- LBPUT(" -> %3d packets decrypted\n",n);
+ LBPUT(" -> %3d packets decrypted",n);
if(n>0) return true;
LBEND();
}
void cScDvbDevice::Startup(void)
{
+ if(ScSetup.ForceTransfer)
+ SetTransferModeForDolbyDigital(2);
for(int n=cDevice::NumDevices(); --n>=0;) {
cScDvbDevice *dev=dynamic_cast<cScDvbDevice *>(cDevice::GetDevice(n));
if(dev) dev->LateInit();
~cScDvbDevice();
#if APIVERSNUM >= 10501
virtual bool HasCi(void);
-#else
+#endif
+#if APIVERSNUM < 10500
virtual int ProvidesCa(const cChannel *Channel) const;
#endif
static void Capture(void);
}
diff -urN -X ex.vdr-sc7 vdr-1.4.7-orig/ci.h vdr-1.4.7-sc7/ci.h
--- vdr-1.4.7-orig/ci.h 2006-08-12 11:43:31.000000000 +0200
-+++ vdr-1.4.7-sc7/ci.h 2007-05-13 18:41:42.000000000 +0200
++++ vdr-1.4.7-sc7/ci.h 2007-06-24 19:46:39.000000000 +0200
@@ -85,10 +85,12 @@
class cCiCaProgramData : public cListObject {
public:
class cCiTransportLayer;
class cCiTransportConnection;
-+#define VDR_IS_SC_PATCHED 401
++#define VDR_IS_SC_PATCHED 402
+
class cCiHandler {
private:
diff -urN -X ex.vdr-sc7 vdr-1.4.7-orig/dvbdevice.c vdr-1.4.7-sc7/dvbdevice.c
--- vdr-1.4.7-orig/dvbdevice.c 2007-02-24 12:10:14.000000000 +0100
-+++ vdr-1.4.7-sc7/dvbdevice.c 2007-05-13 18:04:04.000000000 +0200
++++ vdr-1.4.7-sc7/dvbdevice.c 2007-06-24 19:42:24.000000000 +0200
@@ -419,7 +419,11 @@
dvb_frontend_info feinfo;
if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
- needsDetachReceivers = Ca() != Channel->Ca();
+ if (Ca() >= CA_ENCRYPTED_MIN || Channel->Ca() >= CA_ENCRYPTED_MIN) {
+ if(Channel->Ca()<CA_ENCRYPTED_MIN || CiAllowConcurrent())
-+ return true;
++ result = true;
+ else
+ needsDetachReceivers = Ca() != Channel->Ca();
+ }
#if !defined(VDR_IS_SC_PATCHED)
#error You MUST patch the VDR core with the supplied patch. Next time read the README first.
#endif
-#if VDR_IS_SC_PATCHED<401
+#if VDR_IS_SC_PATCHED<402
#error Your VDR core is patched with an outdated patch version. Please upgrade to the supplied version.
#endif
#endif //APIVERSNUM >= 10500
ConcurrentFF = 0;
memset(CaIgnore,0,sizeof(CaIgnore));
LocalPriority = 0;
+ ForceTransfer = 1;
}
void cScSetup::Check(void)
PRINTF(L_CORE_LOAD,"** Key updates (AU) are %s",AutoUpdate?(AutoUpdate==1?"enabled (active CAIDs)":"enabled (all CAIDs)"):"DISABLED");
PRINTF(L_CORE_LOAD,"** Local systems %stake priority over cached remote",LocalPriority?"":"DON'T ");
PRINTF(L_CORE_LOAD,"** Concurrent FF recordings are %sallowed",ConcurrentFF?"":"NOT ");
+ PRINTF(L_CORE_LOAD,"** %sorce transfermode with digital auido",ForceTransfer?"F":"DON'T f");
LBSTART(L_CORE_LOAD);
LBPUT("** ScCaps are"); for(int i=0; i<MAXSCCAPS ; i++) LBPUT(" %d",ScCaps[i]);
LBFLUSH();
cScPlugin::cScPlugin(void)
{
static const char *logg[] = { "off","active CAIDs","all CAIDs" };
- ScOpts=new cOpts(0,5);
+ ScOpts=new cOpts(0,6);
ScOpts->Add(new cOptSel ("AutoUpdate" ,"Update keys (AU)" ,&ScSetup.AutoUpdate,3,logg));
ScOpts->Add(new cOptBool ("ConcurrentFF" ,"Concurrent FF streams",&ScSetup.ConcurrentFF));
+ ScOpts->Add(new cOptBool ("ForceTranfer" ,"Force TransferMode" ,&ScSetup.ForceTransfer));
ScOpts->Add(new cOptBool ("LocalPriority","Prefer local systems" ,&ScSetup.LocalPriority));
ScOpts->Add(new cOptMInt ("ScCaps" ,"Active on DVB card" , ScSetup.ScCaps,MAXSCCAPS,0));
ScOpts->Add(new cOptMInt ("CaIgnore" ,"Ignore CAID" , ScSetup.CaIgnore,MAXCAIGN,2));
int ConcurrentFF;
int CaIgnore[MAXCAIGN];
int LocalPriority;
+ int ForceTransfer;
public:
cScSetup(void);
void Check(void);
cNetSocket so;
bool emmProcessing;
char username[11], password[11];
- int CAID;
- unsigned char lastEmmReq[32];
//
virtual bool Login(void);
bool ParseKeyConfig(const char *config, int *num);
bool ParseUserConfig(const char *config, int *num);
virtual bool SendMsg(cNetSocket *so, const unsigned char *data, int len);
virtual int RecvMsg(cNetSocket *so, unsigned char *data, int len, int to=-1);
- void HandleEMMRequest(const unsigned char *buff, int len);
+ virtual void HandleEMMRequest(const unsigned char *buff, int len) {}
+ virtual bool CanHandleEMM(int SysId) { return false; }
public:
cCardClientCommon(const char *Name, bool ConReply, bool LogReply, bool DoAES, int MinMsgLen);
- virtual bool CanHandle(unsigned short SysId);
virtual bool Init(const char *config);
virtual bool ProcessECM(const cEcmInfo *ecm, const unsigned char *source, unsigned char *cw);
virtual bool ProcessEMM(int caSys, const unsigned char *source);
{
conReply=ConReply; logReply=LogReply; doAES=DoAES; minMsgLen=MinMsgLen;
emmProcessing=exclusive=false;
- CAID=0;
- memset(lastEmmReq,0,sizeof(lastEmmReq));
}
bool cCardClientCommon::ParseUserConfig(const char *config, int *num)
return n;
}
-bool cCardClientCommon::CanHandle(unsigned short SysId)
-{
- return (emmProcessing && SysId==CAID) || cCardClient::CanHandle(SysId);
-}
-
bool cCardClientCommon::Init(const char *config)
{
cMutexLock lock(this);
return true;
}
-void cCardClientCommon::HandleEMMRequest(const unsigned char *buff, int len)
-{
- if(len>=13 && buff[0]==0 && !CheckNull(buff,len) && memcmp(buff,lastEmmReq,13)) {
- CAID=buff[1]*256+buff[2];
- ResetIdSet();
- SetCard(new cCardIrdeto(buff[6],&buff[3]));
- AddProv(new cProviderIrdeto(0,&buff[7]));
- AddProv(new cProviderIrdeto(2,&buff[10]));
- memcpy(lastEmmReq,buff,13);
- PRINTF(L_CC_LOGIN,"%s: CAID: %04x HexSerial: %02X%02X%02X, HexBase: %02X",name,CAID,buff[3],buff[4],buff[5],buff[6]);
- PRINTF(L_CC_LOGIN,"%s: Provider00: %02X%02X%02X, Provider10: %02X%02X%02X",name,buff[7],buff[8],buff[9],buff[10],buff[11],buff[12]);
- if(!emmAllowed) PRINTF(L_CC_EMM,"%s: EMM disabled from config",name);
- emmProcessing=true;
- }
-}
-
bool cCardClientCommon::ProcessEMM(int caSys, const unsigned char *source)
{
- if(emmProcessing && emmAllowed) {
+ if(emmAllowed && CanHandleEMM(caSys)) {
cMutexLock lock(this);
if(MatchEMM(source)) {
const int length=SCT_LEN(source);
// -- cCardClientCamd33 --------------------------------------------------------
class cCardClientCamd33 : public cCardClientCommon {
+private:
+ int CAID;
+ unsigned char lastEmmReq[32];
+protected:
+ virtual void HandleEMMRequest(const unsigned char *buff, int len);
+ virtual bool CanHandleEMM(int SysId);
public:
cCardClientCamd33(const char *Name);
+ virtual bool CanHandle(unsigned short SysId);
};
static cCardClientLinkReg<cCardClientCamd33> __camd33("Camd33");
cCardClientCamd33::cCardClientCamd33(const char *Name)
:cCardClientCommon(Name,true,true,true,0)
-{}
+{
+ CAID=0;
+ memset(lastEmmReq,0,sizeof(lastEmmReq));
+}
+
+bool cCardClientCamd33::CanHandle(unsigned short SysId)
+{
+ return CanHandleEMM(SysId) || cCardClient::CanHandle(SysId);
+}
+
+bool cCardClientCamd33::CanHandleEMM(int SysId)
+{
+ return (emmProcessing && SysId==CAID);
+}
+
+void cCardClientCamd33::HandleEMMRequest(const unsigned char *buff, int len)
+{
+ if(len>=13 && buff[0]==0 && !CheckNull(buff,len) && memcmp(buff,lastEmmReq,13)) {
+ emmProcessing=false;
+ CAID=buff[1]*256+buff[2];
+ ResetIdSet();
+ switch(CAID>>8) {
+ case 0x17:
+ case 0x06:
+ SetCard(new cCardIrdeto(buff[6],&buff[3]));
+ AddProv(new cProviderIrdeto(0,&buff[7]));
+ AddProv(new cProviderIrdeto(2,&buff[10]));
+ memcpy(lastEmmReq,buff,13);
+ PRINTF(L_CC_LOGIN,"%s: CAID: %04x HexSerial: %02X%02X%02X, HexBase: %02X",name,CAID,buff[3],buff[4],buff[5],buff[6]);
+ PRINTF(L_CC_LOGIN,"%s: Provider00: %02X%02X%02X, Provider10: %02X%02X%02X",name,buff[7],buff[8],buff[9],buff[10],buff[11],buff[12]);
+ if(!emmAllowed) PRINTF(L_CC_EMM,"%s: EMM disabled from config",name);
+ emmProcessing=true;
+ break;
+ }
+ }
+}
// -- cCardClientCardd ---------------------------------------------------------
--- /dev/null
+/*
+ * 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
+ */
+
+// -- cN2Prov7101 ----------------------------------------------------------------
+
+class cN2Prov7101 : public cN2Prov {
+public:
+ cN2Prov7101(int Id, int Flags):cN2Prov(Id,Flags) {}
+ virtual bool PostProcAU(int id, unsigned char *data);
+ };
+
+static cN2ProvLinkReg<cN2Prov7101,0x7101,N2FLAG_POSTAU> staticPL7101;
+
+bool cN2Prov7101::PostProcAU(int id, unsigned char *data)
+{
+ if(data[1]==0x01) {
+ cPlainKey *pk;
+ if(!(pk=keys.FindKey('N',id,MBC(N2_MAGIC,0x30),16))) {
+ PRINTF(L_SYS_EMM,"missing %04x NN 30 3DES key (16 bytes)",id);
+ return false;
+ }
+ unsigned char dkey[16];
+ pk->Get(dkey);
+ DES_key_schedule ks1, ks2;
+ DES_key_sched((DES_cblock *)&dkey[0],&ks1);
+ DES_key_sched((DES_cblock *)&dkey[8],&ks2);
+ DES_ecb2_encrypt(DES_CAST(&data[7]),DES_CAST(&data[7]),&ks1,&ks2,DES_DECRYPT);
+ DES_ecb2_encrypt(DES_CAST(&data[7+8]),DES_CAST(&data[7+8]),&ks1,&ks2,DES_DECRYPT);
+ }
+ return true;
+}
#define ___VERSION_H
// all release versions must end with 0xFF !!
-#define SCVERSNUM 0x000800FF
-#define SCVERSION "0.8.0"
+#define SCVERSNUM 0x000801FF
+#define SCVERSION "0.8.1"
extern const char *ScVersion;