|
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 #include <stdlib.h> 00021 #include <stdio.h> 00022 #include <sys/ioctl.h> 00023 00024 #ifndef SASC 00025 00026 #include <vdr/channels.h> 00027 #include <vdr/ci.h> 00028 #include <vdr/dvbci.h> 00029 00030 #include "device.h" 00031 #include "cam.h" 00032 #include "scsetup.h" 00033 #include "log-core.h" 00034 #include "version.h" 00035 00036 SCAPIVERSTAG(); 00037 00038 #if APIVERSNUM >= 10711 00039 #ifdef WITH_SDDVB 00040 00041 // -- cScDvbSdFfDevice --------------------------------------------------------- 00042 00043 #include "../dvbsddevice/dvbsdffdevice.h" 00044 #define SCDEVICE cScDvbSdFfDevice 00045 #define DVBDEVICE cDvbSdFfDevice 00046 #define OWN_FULLTS 00047 #define OWN_SETCA 00048 #define OWN_DUMPAV 00049 #if APIVERSNUM >= 10721 00050 #define OWN_DEVPARAMS false 00051 #endif 00052 #include "device-tmpl.c" 00053 00054 bool cScDvbSdFfDevice::CheckFullTs(void) 00055 { 00056 return IsPrimaryDevice() && HasDecoder(); 00057 } 00058 00059 bool cScDvbSdFfDevice::SetCaDescr(ca_descr_t *ca_descr, bool initial) 00060 { 00061 cMutexLock lock(&cafdMutex); 00062 return ioctl(fd_ca,CA_SET_DESCR,ca_descr)>=0; 00063 } 00064 00065 bool cScDvbSdFfDevice::SetCaPid(ca_pid_t *ca_pid) 00066 { 00067 cMutexLock lock(&cafdMutex); 00068 return ioctl(fd_ca,CA_SET_PID,ca_pid)>=0; 00069 } 00070 00071 static unsigned int av7110_read(int fd, unsigned int addr) 00072 { 00073 ca_pid_t arg; 00074 arg.pid=addr; 00075 ioctl(fd,CA_GET_MSG,&arg); 00076 return arg.index; 00077 } 00078 00079 #if 0 00080 static void av7110_write(int fd, unsigned int addr, unsigned int val) 00081 { 00082 ca_pid_t arg; 00083 arg.pid=addr; 00084 arg.index=val; 00085 ioctl(fd,CA_SEND_MSG,&arg); 00086 } 00087 #endif 00088 00089 void cScDvbSdFfDevice::DumpAV(void) 00090 { 00091 if(LOG(L_CORE_AV7110)) { 00092 #define CODEBASE (0x2e000404+0x1ce00) 00093 cMutexLock lock(&cafdMutex); 00094 if(HasDecoder() && lastDump.Elapsed()>20000) { 00095 lastDump.Set(); 00096 static unsigned int handles=0, hw_handles=0; 00097 static const unsigned int code[] = { 00098 0xb5100040,0x4a095a12,0x48094282,0xd00b4b09,0x20000044, 00099 0x5b1c4294,0xd0033001,0x281cdbf8,0xe001f7fe,0xfd14bc10 00100 }; 00101 static const unsigned int mask[] = { 00102 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff, 00103 0xffffffff,0xffffffff,0xffffffff,0xfffff800,0xf800ffff 00104 }; 00105 if(!handles) { 00106 handles=1; 00107 PRINTF(L_CORE_AV7110,"searching handle tables"); 00108 for(int i=0; i<0x2000; i+=4) { 00109 int j; 00110 for(j=0; j<20; j+=4) { 00111 int r=av7110_read(fd_ca,CODEBASE+i+j); 00112 if((r&mask[j/4])!=(code[j/4]&mask[j/4])) break; 00113 } 00114 if(j==20) { 00115 handles=av7110_read(fd_ca,CODEBASE+i+44); 00116 hw_handles=av7110_read(fd_ca,CODEBASE+i+52); 00117 PRINTF(L_CORE_AV7110,"found handles=%08x hw_handles=%08x at 0x%08x",handles,hw_handles,CODEBASE+i); 00118 if((handles>>16)!=0x2e08 || (hw_handles>>16)!=0x2e08) { 00119 PRINTF(L_CORE_AV7110,"seems to be invalid"); 00120 } 00121 break; 00122 } 00123 } 00124 } 00125 00126 unsigned int hdl=0, hwhdl=0; 00127 PRINTF(L_CORE_AV7110," : 64000080 64000400"); 00128 for(int i=0; i<=31; i++) { 00129 unsigned int off80 =av7110_read(fd_ca,0x64000080+i*4); 00130 unsigned int off400=av7110_read(fd_ca,0x64000400+i*8); 00131 LBSTART(L_CORE_AV7110); 00132 LBPUT("handle %2d: %08x %08x %s pid=%04x idx=%d", 00133 i,off80,off400,off80&0x2000?"ACT":"---",off80&0x1fff,(off400&0x1e)>>1); 00134 if(handles>1 && i<=27) { 00135 if((i&1)==0) { 00136 hdl=av7110_read(fd_ca,handles+i*2); 00137 hwhdl=av7110_read(fd_ca,hw_handles+i*2); 00138 } 00139 unsigned int s=((~i)&1)<<4; 00140 LBPUT(" | %02d hdl=%04x hwfilt=%04x",i,(hdl>>s)&0xffff,(hwhdl>>s)&0xffff); 00141 } 00142 LBEND(); 00143 } 00144 } 00145 } 00146 } 00147 00148 // -- cScSdDevicePlugin -------------------------------------------------------- 00149 00150 class cScSdDevicePlugin : public cScDevicePlugin { 00151 public: 00152 virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId); 00153 virtual bool LateInit(cDevice *dev); 00154 virtual bool EarlyShutdown(cDevice *dev); 00155 virtual bool SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial); 00156 virtual bool SetCaPid(cDevice *dev, ca_pid_t *ca_pid); 00157 virtual bool DumpAV(cDevice *dev); 00158 }; 00159 00160 static cScSdDevicePlugin _sddevplugin; 00161 00162 cDevice *cScSdDevicePlugin::Probe(int Adapter, int Frontend, uint32_t SubSystemId) 00163 { 00164 static uint32_t SubsystemIds[] = { 00165 0x110A0000, // Fujitsu Siemens DVB-C 00166 0x13C20000, // Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C 00167 0x13C20001, // Technotrend/Hauppauge WinTV DVB-T rev1.X 00168 0x13C20002, // Technotrend/Hauppauge WinTV DVB-C rev2.X 00169 0x13C20003, // Technotrend/Hauppauge WinTV Nexus-S rev2.X 00170 0x13C20004, // Galaxis DVB-S rev1.3 00171 0x13C20006, // Fujitsu Siemens DVB-S rev1.6 00172 0x13C20008, // Technotrend/Hauppauge DVB-T 00173 0x13C2000A, // Technotrend/Hauppauge WinTV Nexus-CA rev1.X 00174 0x13C2000E, // Technotrend/Hauppauge WinTV Nexus-S rev2.3 00175 0x13C21002, // Technotrend/Hauppauge WinTV DVB-S rev1.3 SE 00176 0x00000000 00177 }; 00178 for(uint32_t *sid=SubsystemIds; *sid; sid++) { 00179 if(*sid==SubSystemId) { 00180 PRINTF(L_GEN_DEBUG,"creating SD-FF device %d/%d",Adapter,Frontend); 00181 return new cScDvbSdFfDevice(this,Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); 00182 } 00183 } 00184 return 0; 00185 } 00186 00187 bool cScSdDevicePlugin::LateInit(cDevice *dev) 00188 { 00189 cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev); 00190 if(d) d->LateInit(); 00191 return d!=0; 00192 } 00193 00194 bool cScSdDevicePlugin::EarlyShutdown(cDevice *dev) 00195 { 00196 cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev); 00197 if(d) d->EarlyShutdown(); 00198 return d!=0; 00199 } 00200 00201 bool cScSdDevicePlugin::SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial) 00202 { 00203 cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev); 00204 if(d) return d->SetCaDescr(ca_descr,initial); 00205 return false; 00206 } 00207 00208 bool cScSdDevicePlugin::SetCaPid(cDevice *dev, ca_pid_t *ca_pid) 00209 { 00210 cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev); 00211 if(d) return d->SetCaPid(ca_pid); 00212 return d!=0; 00213 } 00214 00215 bool cScSdDevicePlugin::DumpAV(cDevice *dev) 00216 { 00217 cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev); 00218 if(d) d->DumpAV(); 00219 return d!=0; 00220 } 00221 00222 #endif //WITH_SDDVB 00223 #endif //APIVERSNUM >= 10711 00224 #endif //SASC