|
SASC-NG
DVBSoftCAM
|
00001 00002 #include <stdio.h> 00003 #include <stdlib.h> 00004 #include <ctype.h> 00005 #include <dlfcn.h> 00006 #include <dirent.h> 00007 #include <fnmatch.h> 00008 00009 #include "data.h" 00010 #include "sc.h" 00011 #include "scsetup.h" 00012 #include "opts.h" 00013 #include "misc.h" 00014 #include "system.h" 00015 #include "smartcard.h" 00016 #include "cam.h" 00017 #include "log-core.h" 00018 #include "version.h" 00019 00020 #define LIBSC_PREFIX "libsc-" 00021 #define SO_INDICATOR ".so." 00022 00023 static bool DllLoad(const char *fileName) 00024 { 00025 const char *base=rindex(fileName,'/'); 00026 if(base) base++; else base=fileName; 00027 void *handle=dlopen(fileName,RTLD_NOW|RTLD_LOCAL); 00028 if(handle) { 00029 dlerror(); 00030 int *libapivers=(int *)dlsym(handle,"ScLibApiVersion"); 00031 const char *error=dlerror(); 00032 if(!error && *libapivers==SCAPIVERS) 00033 return true; 00034 else printf("dload: %s: SCAPI version doesn't match (plugin=%d, library=%d)\n",base,SCAPIVERS,!error?*libapivers:0); 00035 } 00036 else printf("dload: %s: %s\n",base,dlerror()); 00037 return false; 00038 } 00039 00040 bool DllsLoad(const char *libdir) 00041 { 00042 char pat[32]; 00043 snprintf(pat,sizeof(pat),"%s*-%d%s%s",LIBSC_PREFIX,SCAPIVERS,SO_INDICATOR,APIVERSION); 00044 bool res=true; 00045 cReadDir dir(libdir); 00046 struct dirent *e; 00047 while((e=dir.Next())) { 00048 if(!fnmatch(pat,e->d_name,FNM_PATHNAME|FNM_NOESCAPE)) { 00049 if(!DllLoad(AddDirectory(libdir,e->d_name))) res=false; 00050 } 00051 } 00052 return res; 00053 } 00054 00055 void InitAll(const char *cfgdir) 00056 { 00057 logcfg.logCon=1; 00058 logcfg.noTimestamp=1; 00059 cSystems::ConfigParse("Cardclient.Immediate","0"); 00060 cSystems::ConfigParse("Viaccess.TpsAU","1"); 00061 00062 filemaps.SetCfgDir(cfgdir); 00063 cStructLoaders::SetCfgDir(cfgdir); 00064 00065 if(!Feature.KeyFile()) keys.Disable(); 00066 if(!Feature.SmartCard()) smartcards.Disable(); 00067 cStructLoaders::Load(false); 00068 if(Feature.KeyFile() && keys.Count()<1) 00069 PRINTF(L_GEN_ERROR,"no keys loaded for softcam!"); 00070 if(!cSystems::Init(cfgdir)) exit(2); 00071 } 00072 00073 void LogAll(void) 00074 { 00075 for(int i=0; i<32; i++) 00076 cLogging::SetModuleOptions(LCLASS(i,0xFFFFFFFF)); 00077 } 00078 00079 void LogNone(void) 00080 { 00081 for(int i=0; i<32; i++) 00082 cLogging::SetModuleOptions(LCLASS(i,0)); 00083 } 00084 00085 void SDump(const unsigned char *buffer, int n) 00086 { 00087 for(int l=0 ; l<n ; l++) printf("%02x ",buffer[l]); 00088 printf("\n"); 00089 } 00090 00091 int ReadRaw(const char *name, unsigned char *buff, int maxlen) 00092 { 00093 FILE *f=fopen(name,"r"); 00094 if(f) { 00095 char line[512]; 00096 int len=0; 00097 while(len<maxlen && fgets(line,sizeof(line),f)) { 00098 if(strstr(line,"dump: n=")) continue; 00099 char *p=index(line,'#'); 00100 if(p) *p=0; 00101 p=index(line,'['); 00102 if(p) { 00103 p=index(p,']'); 00104 if(p) { 00105 strcpy(line,p+1); 00106 } 00107 } 00108 p=index(line,':'); 00109 if(p) p++; else p=line; 00110 while(1) { 00111 char *np; 00112 int val=strtol(p,&np,16); 00113 if(p!=np) { 00114 buff[len++]=val; 00115 p=np; 00116 } 00117 else break; 00118 } 00119 } 00120 fclose(f); 00121 // printf("using raw from %s:\n",name); 00122 // HexDump(buff,len); 00123 return len; 00124 } 00125 printf("failed to open raw file %s: %s\n",name,strerror(errno)); 00126 exit(1); 00127 } 00128 00129 // 00130 // 00131 00132 extern const char *I18nTranslate(const char *s, const char *Plugin) 00133 { 00134 return s; 00135 } 00136 00137 // 00138 // 00139 00140 static const struct LogModule lm_core = { 00141 (LMOD_ENABLE|L_CORE_ALL)&LOPT_MASK, 00142 (LMOD_ENABLE|L_CORE_LOAD|L_CORE_ECM|L_CORE_PIDS|L_CORE_AU|L_CORE_AUSTATS|L_CORE_CAIDS|L_CORE_NET|L_CORE_CI|L_CORE_SC|L_CORE_HOOK|L_CORE_OVER)&LOPT_MASK, 00143 "core", 00144 { "load","action","ecm","ecmProc","pids","au","auStats","auExtra","auExtern", 00145 "caids","keys","dynamic","csa","ci","av7110","net","netData","msgcache", 00146 "serial","smartcard","hook","ciFull","csaVerb","override" } 00147 }; 00148 ADD_MODULE(L_CORE,lm_core) 00149 00150 // 00151 // 00152 00153 cScSetup ScSetup; 00154 00155 cScSetup::cScSetup(void) 00156 { 00157 AutoUpdate = 1; 00158 memset(ScCaps,0,sizeof(ScCaps)); 00159 ScCaps[0] = 1; 00160 ScCaps[1] = 2; 00161 ConcurrentFF = 0; 00162 LocalPriority = 0; 00163 ForceTransfer = 1; 00164 PrestartAU = 0; 00165 SuperKeys=0; 00166 EcmCache=0; 00167 } 00168 00169 void cScSetup::Check(void) {} 00170 00171 // 00172 // 00173 00174 void cSoftCAM::SetLogStatus(int CardNum, const cEcmInfo *ecm, bool on) {} 00175 void cSoftCAM::AddHook(int CardNum, cLogHook *hook) {} 00176 bool cSoftCAM::TriggerHook(int CardNum, int id) { return true; } 00177 void cSoftCAM::CaidsChanged(void) {} 00178 int cSoftCAM::FilterHandle(int CardNum) { return -1; } 00179 00180 // 00181 // 00182 00183 // --- cOpt -------------------------------------------------------------------- 00184 00185 cOpt::cOpt(const char *Name, const char *Title) 00186 { 00187 name=Name; title=Title; 00188 fullname=0; persistant=true; 00189 } 00190 00191 cOpt::~cOpt() 00192 { 00193 free(fullname); 00194 } 00195 00196 const char *cOpt::FullName(const char *PreStr) 00197 { 00198 if(PreStr) { 00199 free(fullname); 00200 fullname=bprintf("%s.%s",PreStr,name); 00201 return fullname; 00202 } 00203 else return name; 00204 } 00205 00206 // --- cOptInt ----------------------------------------------------------------- 00207 00208 cOptInt::cOptInt(const char *Name, const char *Title, int *Storage, int Min, int Max) 00209 :cOpt(Name,Title) 00210 { 00211 storage=Storage; min=Min; max=Max; 00212 } 00213 00214 void cOptInt::Parse(const char *Value) 00215 { 00216 *storage=atoi(Value); 00217 } 00218 00219 void cOptInt::Backup(void) 00220 { 00221 } 00222 00223 bool cOptInt::Set(void) 00224 { 00225 if(value!=*storage) { *storage=value; return true; } 00226 return false; 00227 } 00228 00229 void cOptInt::Store(const char *PreStr) 00230 { 00231 } 00232 00233 void cOptInt::Create(cOsdMenu *menu) 00234 { 00235 } 00236 00237 // --- cOptSel ----------------------------------------------------------------- 00238 00239 cOptSel::cOptSel(const char *Name, const char *Title, int *Storage, int NumStr, const char * const *Strings) 00240 :cOptInt(Name,Title,Storage,0,NumStr) 00241 { 00242 strings=Strings; 00243 trStrings=0; 00244 } 00245 00246 cOptSel::~cOptSel() 00247 { 00248 free(trStrings); 00249 } 00250 00251 void cOptSel::Create(cOsdMenu *menu) 00252 { 00253 } 00254 00255 // --- cOptBool ----------------------------------------------------------------- 00256 00257 cOptBool::cOptBool(const char *Name, const char *Title, int *Storage) 00258 :cOptInt(Name,Title,Storage,0,1) 00259 {} 00260 00261 void cOptBool::Create(cOsdMenu *menu) 00262 { 00263 } 00264 00265 // --- cOptStr ----------------------------------------------------------------- 00266 00267 cOptStr::cOptStr(const char *Name, const char *Title, char *Storage, int Size, const char *Allowed) 00268 :cOpt(Name,Title) 00269 { 00270 storage=Storage; size=Size; allowed=Allowed; 00271 value=MALLOC(char,size); 00272 } 00273 00274 cOptStr::~cOptStr() 00275 { 00276 free(value); 00277 } 00278 00279 void cOptStr::Parse(const char *Value) 00280 { 00281 strn0cpy(storage,Value,size); 00282 } 00283 00284 void cOptStr::Backup(void) 00285 { 00286 } 00287 00288 bool cOptStr::Set(void) 00289 { 00290 if(strcmp(value,storage)) { strn0cpy(storage,value,size); return true; } 00291 return false; 00292 } 00293 00294 void cOptStr::Store(const char *PreStr) 00295 { 00296 } 00297 00298 void cOptStr::Create(cOsdMenu *menu) 00299 { 00300 } 00301 00302 // --- cOptCap ----------------------------------------------------------------- 00303 00304 class cOptCap : public cOpt { 00305 protected: 00306 int *storage, *value; 00307 int size, disp, len; 00308 public: 00309 cOptCap(const char *Name, const char *Title, int *Storage, int Size, int Disp); 00310 virtual ~cOptCap(); 00311 virtual void Parse(const char *Value); 00312 virtual void Backup(void); 00313 virtual bool Set(void); 00314 virtual void Store(const char *PreStr); 00315 virtual void Create(cOsdMenu *menu); 00316 }; 00317 00318 cOptCap::cOptCap(const char *Name, const char *Title, int *Storage, int Size, int Disp) 00319 :cOpt(Name,Title) 00320 { 00321 storage=Storage; size=Size; disp=Disp; len=sizeof(int)*size; 00322 value=MALLOC(int,size); 00323 } 00324 00325 cOptCap::~cOptCap() 00326 { 00327 free(value); 00328 } 00329 00330 void cOptCap::Parse(const char *Value) 00331 { 00332 memset(storage,0,len); 00333 int i=0; 00334 while(1) { 00335 char *p; 00336 const int c=strtol(Value,&p,10); 00337 if(c<=0 || p==Value || i>=size) return; 00338 storage[i++]=c; 00339 Value=p; 00340 } 00341 } 00342 00343 void cOptCap::Backup(void) 00344 { 00345 } 00346 00347 bool cOptCap::Set(void) 00348 { 00349 if(memcmp(value,storage,len)) { memcpy(storage,value,len); return true; } 00350 return false; 00351 } 00352 00353 void cOptCap::Store(const char *PreStr) 00354 { 00355 } 00356 00357 void cOptCap::Create(cOsdMenu *menu) 00358 { 00359 } 00360 00361 // --- cOpts ------------------------------------------------------------------- 00362 00363 cOpts::cOpts(const char *PreStr, int NumOpts) 00364 { 00365 preStr=PreStr; 00366 numOpts=NumOpts; numAdd=0; 00367 if((opts=MALLOC(cOpt *,numOpts))) memset(opts,0,sizeof(cOpt *)*numOpts); 00368 } 00369 00370 cOpts::~cOpts() 00371 { 00372 if(opts) { 00373 for(int i=0; i<numOpts; i++) delete opts[i]; 00374 free(opts); 00375 } 00376 } 00377 00378 void cOpts::Add(cOpt *opt) 00379 { 00380 if(opts && numAdd<numOpts) opts[numAdd++]=opt; 00381 } 00382 00383 bool cOpts::Parse(const char *Name, const char *Value) 00384 { 00385 if(opts) { 00386 for(int i=0; i<numAdd; i++) 00387 if(opts[i] && opts[i]->Persistant() && !strcasecmp(Name,opts[i]->Name())) { 00388 opts[i]->Parse(Value); 00389 return true; 00390 } 00391 } 00392 return false; 00393 } 00394 00395 bool cOpts::Store(bool AsIs) 00396 { 00397 return false; 00398 } 00399 00400 void cOpts::Backup(void) 00401 { 00402 } 00403 00404 void cOpts::Create(cOsdMenu *menu) 00405 { 00406 } 00407 00408 // 00409 // 00410 // VDR 00411 // 00412 // 00413 00414 #include <vdr/sources.h> 00415 00416 cString cSource::ToString(int Code) 00417 { 00418 char buffer[16]; 00419 char *q = buffer; 00420 switch (Code & st_Mask) { 00421 case stCable: *q++ = 'C'; break; 00422 case stSat: *q++ = 'S'; 00423 { 00424 int pos = Code & ~st_Mask; 00425 q += snprintf(q, sizeof(buffer) - 2, "%u.%u", (pos & ~st_Neg) / 10, (pos & ~st_Neg) % 10); // can't simply use "%g" here since the silly 'locale' messes up the decimal point 00426 *q++ = (Code & st_Neg) ? 'E' : 'W'; 00427 } 00428 break; 00429 case stTerr: *q++ = 'T'; break; 00430 default: *q++ = Code + '0'; // backward compatibility 00431 } 00432 *q = 0; 00433 return buffer; 00434 } 00435 00436 int cSource::FromString(const char *s) 00437 { 00438 int type = stNone; 00439 switch (toupper(*s)) { 00440 case 'C': type = stCable; break; 00441 case 'S': type = stSat; break; 00442 case 'T': type = stTerr; break; 00443 case '0' ... '9': type = *s - '0'; break; // backward compatibility 00444 default: esyslog("ERROR: unknown source key '%c'", *s); 00445 return stNone; 00446 } 00447 int code = type; 00448 if (type == stSat) { 00449 int pos = 0; 00450 bool dot = false; 00451 bool neg = false; 00452 while (*++s) { 00453 switch (toupper(*s)) { 00454 case '0' ... '9': pos *= 10; 00455 pos += *s - '0'; 00456 break; 00457 case '.': dot = true; 00458 break; 00459 case 'E': neg = true; // fall through to 'W' 00460 case 'W': if (!dot) 00461 pos *= 10; 00462 break; 00463 default: esyslog("ERROR: unknown source character '%c'", *s); 00464 return stNone; 00465 } 00466 } 00467 if (neg) 00468 pos |= st_Neg; 00469 code |= pos; 00470 } 00471 return code; 00472 } 00473 00474 // 00475 // 00476 00477 #include <vdr/channels.h> 00478 00479 int cChannel::Transponder(int Frequency, char Polarization) 00480 { 00481 // some satellites have transponders at the same frequency, just with different polarization: 00482 switch (tolower(Polarization)) { 00483 case 'h': Frequency += 100000; break; 00484 case 'v': Frequency += 200000; break; 00485 case 'l': Frequency += 300000; break; 00486 case 'r': Frequency += 400000; break; 00487 } 00488 return Frequency; 00489 } 00490 00491 // 00492 // 00493 00494 int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag) 00495 { 00496 return 0; 00497 }