|
SASC
DVBSoftCAM
|
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