SASC-NG
DVBSoftCAM

device-tmpl.c

Go to the documentation of this file.
00001 /*
00002  * Softcam plugin to VDR (C++)
00003  *
00004  * This code is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This code is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
00018  */
00019 
00020 // -- cScDevice ----------------------------------------------------------------
00021 
00022 class SCDEVICE : public DVBDEVICE {
00023 private:
00024 #ifndef SASC
00025   cDeCsaTSBuffer *tsBuffer;
00026   cMutex tsMutex;
00027 #endif //!SASC
00028   cCam *cam;
00029   cScDevicePlugin *devplugin;
00030 #ifndef SASC
00031   cCiAdapter *hwciadapter;
00032   cTimeMs lastDump;
00033 #endif //!SASC
00034   int fd_dvr, fd_ca, fd_ca2;
00035   cMutex cafdMutex;
00036   bool softcsa, fullts;
00037   char devId[8];
00038   //
00039 #ifndef SASC
00040   bool ScActive(void);
00041 #endif //!SASC
00042 protected:
00043 #ifndef SASC
00044   virtual bool Ready(void);
00045   virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
00046   virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
00047   virtual bool OpenDvr(void);
00048   virtual void CloseDvr(void);
00049   virtual bool GetTSPacket(uchar *&Data);
00050 #endif //!SASC
00051 public:
00052   SCDEVICE(cScDevicePlugin *DevPlugin, int Adapter, int Frontend, int cafd);
00053   ~SCDEVICE();
00054   bool SetCaDescr(ca_descr_t *ca_descr, bool initial);
00055   bool SetCaPid(ca_pid_t *ca_pid);
00056   void DumpAV(void);
00057 #ifndef SASC
00058   virtual bool HasCi(void);
00059   void LateInit(void);
00060   void EarlyShutdown(void);
00061   bool CheckFullTs(void);
00062 #else
00063   cCam *Cam(void) { return cam; }
00064 #endif //!SASC
00065   };
00066 
00067 SCDEVICE::SCDEVICE(cScDevicePlugin *DevPlugin, int Adapter, int Frontend, int cafd)
00068 #if APIVERSNUM >= 10711
00069 #ifdef OWN_DEVPARAMS
00070 :DVBDEVICE(Adapter,Frontend,OWN_DEVPARAMS)
00071 #else
00072 :DVBDEVICE(Adapter,Frontend)
00073 #endif //OWN_DEVPARAMS
00074 #else
00075 :DVBDEVICE(Adapter)
00076 #endif //APIVERSNUM >= 10711
00077 {
00078 #ifndef SASC
00079   tsBuffer=0; hwciadapter=0;
00080 #endif
00081   cam=0; devplugin=DevPlugin; softcsa=fullts=false;
00082   fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1;
00083 #if APIVERSNUM >= 10711
00084   snprintf(devId,sizeof(devId),"%d/%d",Adapter,Frontend);
00085 #else
00086   snprintf(devId,sizeof(devId),"%d",Adapter);
00087 #endif
00088 #ifdef SASC
00089   cam=new cCam(this,Adapter,0,devId,devplugin,softcsa,fullts);
00090 #endif // !SASC
00091 }
00092 
00093 SCDEVICE::~SCDEVICE()
00094 {
00095 #ifndef SASC
00096   DetachAllReceivers();
00097   Cancel(3);
00098   EarlyShutdown();
00099 #endif
00100   if(fd_ca>=0) close(fd_ca);
00101   if(fd_ca2>=0) close(fd_ca2);
00102 #ifdef SASC
00103   delete cam;
00104 #endif
00105 }
00106 
00107 #ifndef OWN_SETCA
00108 bool SCDEVICE::SetCaDescr(ca_descr_t *ca_descr, bool initial)
00109 {
00110   return false;
00111 }
00112 
00113 bool SCDEVICE::SetCaPid(ca_pid_t *ca_pid)
00114 {
00115   return false;
00116 }
00117 #endif //!OWN_SETCA
00118 
00119 #ifndef OWN_DUMPAV
00120 void SCDEVICE::DumpAV(void)
00121 {}
00122 #endif
00123 
00124 #ifndef SASC
00125 
00126 void SCDEVICE::EarlyShutdown(void)
00127 {
00128   SetCamSlot(0);
00129   delete cam; cam=0;
00130   delete hwciadapter; hwciadapter=0;
00131 }
00132 
00133 #ifndef OWN_FULLTS
00134 bool SCDEVICE::CheckFullTs(void)
00135 {
00136   return false;
00137 }
00138 #endif //!OWN_FULLTS
00139 
00140 void SCDEVICE::LateInit(void)
00141 {
00142   int n=CardIndex();
00143   if(DeviceNumber()!=n)
00144     PRINTF(L_GEN_ERROR,"CardIndex - DeviceNumber mismatch! Put SC plugin first on VDR commandline!");
00145   softcsa=(fd_ca<0);
00146   if(softcsa) {
00147     if(HasDecoder()) PRINTF(L_GEN_ERROR,"Card %s is a full-featured card but no ca device found!",devId);
00148     }
00149   else if(cScDevices::ForceBudget(n)) {
00150     PRINTF(L_GEN_INFO,"Budget mode forced on card %s",devId);
00151     softcsa=true;
00152     }
00153   if(softcsa) {
00154     fullts=CheckFullTs();
00155     if(fullts) PRINTF(L_GEN_INFO,"Enabling hybrid full-ts mode on card %s",devId);
00156     else PRINTF(L_GEN_INFO,"Using software decryption on card %s",devId);
00157     }
00158   if(fd_ca2>=0) hwciadapter=cDvbCiAdapter::CreateCiAdapter(this,fd_ca2);
00159   cam=new cCam(this,DVB_DEV_SPEC,devId,devplugin,softcsa,fullts);
00160 }
00161 
00162 bool SCDEVICE::HasCi(void)
00163 {
00164   return cam || hwciadapter;
00165 }
00166 
00167 bool SCDEVICE::Ready(void)
00168 {
00169   return (cam         ? cam->Ready():true) &&
00170          (hwciadapter ? hwciadapter->Ready():true);
00171 }
00172 
00173 bool SCDEVICE::SetPid(cPidHandle *Handle, int Type, bool On)
00174 {
00175   if(cam) cam->SetPid(Type,Handle->pid,On);
00176   tsMutex.Lock();
00177   if(tsBuffer) tsBuffer->SetActive(ScActive());
00178   tsMutex.Unlock();
00179   return DVBDEVICE::SetPid(Handle,Type,On);
00180 }
00181 
00182 bool SCDEVICE::SetChannelDevice(const cChannel *Channel, bool LiveView)
00183 {
00184   if(cam) cam->Tune(Channel);
00185   bool ret=DVBDEVICE::SetChannelDevice(Channel,LiveView);
00186   if(LiveView && IsPrimaryDevice() && Channel->Ca()>=CA_ENCRYPTED_MIN &&
00187      !Transferring() &&
00188      softcsa && !fullts) {
00189     PRINTF(L_GEN_INFO,"Forcing transfermode on card %s",devId);
00190     DVBDEVICE::SetChannelDevice(Channel,false); // force transfermode
00191     }
00192   if(ret && cam) cam->PostTune();
00193   return ret;
00194 }
00195 
00196 bool SCDEVICE::ScActive(void)
00197 {
00198   return cam && cam->OwnSlot(CamSlot());
00199 }
00200 
00201 bool SCDEVICE::OpenDvr(void)
00202 {
00203   CloseDvr();
00204   fd_dvr=cScDevices::DvbOpen(DEV_DVB_DVR,DVB_DEV_SPEC,O_RDONLY|O_NONBLOCK,true);
00205   if(fd_dvr>=0) {
00206     cDeCSA *decsa=cam ? cam->DeCSA() : 0;
00207     tsMutex.Lock();
00208     tsBuffer=new cDeCsaTSBuffer(fd_dvr,MEGABYTE(ScSetup.DeCsaTsBuffSize),CardIndex()+1,decsa,ScActive());
00209     tsMutex.Unlock();
00210     }
00211   return fd_dvr>=0;
00212 }
00213 
00214 void SCDEVICE::CloseDvr(void)
00215 {
00216   tsMutex.Lock();
00217   delete tsBuffer; tsBuffer=0;
00218   tsMutex.Unlock();
00219   if(fd_dvr>=0) { close(fd_dvr); fd_dvr=-1; }
00220 }
00221 
00222 bool SCDEVICE::GetTSPacket(uchar *&Data)
00223 {
00224   if(tsBuffer) { Data=tsBuffer->Get(); return true; }
00225   return false;
00226 }
00227 
00228 #endif // !SASC
00229 
00230 #undef SCDEVICE
00231 #undef DVBDEVICE
00232 #undef OWN_SETCA
00233 #undef OWN_DUMPAV
00234 #undef OWN_FULLTS
00235 #undef OWN_DEVPARAMS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines