SASC-NG
DVBSoftCAM

compat.c

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines