improve testing code
authorleslie <unknown>
Sat, 5 Jan 2008 10:52:15 +0000 (11:52 +0100)
committerleslie <unknown>
Sat, 5 Jan 2008 10:52:15 +0000 (11:52 +0100)
testing/Makefile
testing/compat.c
testing/testN2Emu.c

index 3118328312718b065b14f6ed101ed9958ffe832e..8ef82ce8ae0c69afb4423621a54734741e822e04 100644 (file)
@@ -54,7 +54,7 @@ testN1Emu.o: testN1Emu.c ../systems/nagra/nagra.c ../systems/nagra/nagra1.c ../s
 testN1Emu: testN1Emu.o $(SHAREDOBJS) $(NOBJS)
        $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
 
-testN2Emu.o: testN2Emu.c
+testN2Emu.o: testN2Emu.c compat.h
 testN2Emu: testN2Emu.o $(SHAREDOBJS) $(NOBJS)
        $(CXX) $(CXXFLAGS) $^ $(LIBS) -L../systems/nagra -lsc-nagra -o $@
 
index ef9d7cea84010b9bbf513a3135d327f7bd2c5112..373cc15dfff2caca836a52fbb95c271a222d3d7b 100644 (file)
@@ -82,6 +82,13 @@ int ReadRaw(const char *name, unsigned char *buff, int maxlen)
       if(strstr(line,"dump: n=")) continue;
       char *p=index(line,'#');
       if(p) *p=0;
+      p=index(line,'[');
+      if(p) {
+        p=index(p,']');
+        if(p) {
+          strcpy(line,p+1);
+          }
+        }
       p=index(line,':');
       if(p) p++; else p=line;
       while(1) {
index f5ea4d43f915d6ae83603a422870cc50e85a5c34..5e85ce6581440112342b8a1dff42e9efbc149779 100644 (file)
 
 static const unsigned char key3des[16] = {  };
 
+static cN2Prov *emmP=0;
+
 void Emm(unsigned char *emmdata, int cmdLen, int id)
 {
-  cN2Prov *emmP=cN2Providers::GetProv(id,N2FLAG_NONE);
-  if(emmP) printf("provider %04x capabilities%s%s%s%s\n",id,
-                    emmP->HasFlags(N2FLAG_MECM)    ?" MECM":"",
-                    emmP->HasFlags(N2FLAG_Bx)      ?" Bx":"",
-                    emmP->HasFlags(N2FLAG_POSTAU)  ?" POSTPROCAU":"",
-                    emmP->HasFlags(N2FLAG_INV)     ?" INVCW":"");
+  if(!emmP || (emmP && !emmP->CanHandle(id))) {
+    delete emmP;
+    emmP=cN2Providers::GetProv(id,N2FLAG_NONE);
+    if(emmP) emmP->PrintCaps(L_SYS_EMM);
+    }
 
+  HEXDUMP(L_SYS_RAWEMM,emmdata,cmdLen,"Nagra2 RAWEMM");
+  id=(emmdata[8]<<8)+emmdata[9];
+  LBSTARTF(L_SYS_EMM);
+  bool contFail=false;
   for(int i=8+2+4+4; i<cmdLen-22; ) {
-printf("%02x: nano %02x\n",i,emmdata[i]);
     switch(emmdata[i]) {
       case 0x42: // plain Key update
-        if(emmdata[i+2]==0x10 && (emmdata[i+3]&0xBF)==0x06 &&
-           (emmdata[i+4]&0xF8)==0x08 && emmdata[i+5]==0x00 && emmdata[i+6]==0x10) {
-          if(!emmP || emmP->PostProcAU(id,&emmdata[i])) {
-            printf("key%02x: ",(emmdata[i+3]&0x40)>>6);
-            SDump(&emmdata[i+7],16);
+        if((((emmdata[i+3]|0xF3)+1)&0xFF) != 0) {
+          int len=emmdata[i+2];
+          int off=emmdata[i+5];
+          int ulen=emmdata[i+6];
+          if(len>0 && ulen>0 && off+ulen<=len) {
+            int ks=emmdata[i+3], kn;
+            if(ks==0x06 || ks==0x46) kn=(ks>>6)&1; else kn=MBC(N2_MAGIC,ks);
+            unsigned char key[256];
+            memset(key,0,sizeof(key));
+            bool ok=false;
+            if((emmdata[i+1]&0x7F)==0) ok=true;
+            else {
+              if(emmP && emmP->HasFlags(N2FLAG_POSTAU)) {
+                if(emmP->PostProcAU(id,&emmdata[i])) ok=true;
+                }
+              else PRINTF(L_SYS_EMM,"POSTAU for provider %04x not supported",id);
+              }
+            if(ok) {
+              printf("key %x: off=%x ulen=%x ",kn,off,ulen);
+              SDump(&emmdata[i+7],ulen);
+              }
+            i+=ulen;
             }
+          else PRINTF(L_SYS_EMM,"nano42 key size mismatch len=%d off=%d ulen=%d",len,off,ulen);
           }
-        i+=23;
+        else PRINTF(L_SYS_EMM,"nano42 0xf3 status exceeded");
+        i+=7;
         break;
       case 0xE0: // DN key update
         if(emmdata[i+1]==0x25) {
           printf("key%02x: ",(emmdata[i+16]&0x40)>>6);
           SDump(&emmdata[i+23],16);
           }
-        i+=39;
+        i+=emmdata[i+1]+2;
         break;
       case 0x83: // change data prov. id
         id=(emmdata[i+1]<<8)|emmdata[i+2];
-        printf("keyid: %04x\n",id);
         i+=3;
         break;
-      case 0xA4: // conditional (always no match assumed for now)
-        i+=emmdata[i+1]+2+4;
-        break;
-      case 0xA6:
-        i+=emmdata[i+1]+1;
-        break;
-      case 0x13:
-      case 0x14:
-      case 0x15:
-        i+=4;
-        break;
-      case 0xB0 ... 0xBF: // Update with ROM CPU code
+      case 0xB0: case 0xB1: case 0xB2: case 0xB3: // Update with ROM CPU code
+      case 0xB4: case 0xB5: case 0xB6: case 0xB7:
+      case 0xB8: case 0xB9: case 0xBA: case 0xBB:
+      case 0xBC: case 0xBD: case 0xBE: case 0xBF:
         {
         int bx=emmdata[i]&15;
         if(!emmP || !emmP->HasFlags(N2FLAG_Bx)) {
-          printf("B%X for provider %04x not supported\n",bx,id);
+          PRINTF(L_SYS_EMM,"B%X for provider %04x not supported",bx,id);
           i=cmdLen;
           break;
           }
@@ -68,24 +82,50 @@ printf("%02x: nano %02x\n",i,emmdata[i]);
         if((r=emmP->ProcessBx(emmdata,cmdLen,i+1))>0)
           i+=r;
         else {
-          printf("B%X executing failed for %04x\n",bx,id);
+          PRINTF(L_SYS_EMM,"B%X executing failed for %04x",bx,id);
           i=cmdLen;
           }
         break;
         }
-      case 0xE3: // Eeprom update
-        i+=emmdata[i+4]+4;
+      case 0xA4: i+=emmdata[i+1]+2+4; break;   // conditional (always no match assumed for now)
+      case 0xA6: i+=15; break;
+      case 0xAA: i+=emmdata[i+1]+5; break;
+      case 0xAD: i+=emmdata[i+1]+2; break;
+      case 0xA2:
+      case 0xAE: i+=11;break;
+      case 0x12: i+=emmdata[i+1]+2; break;      // create tier
+      case 0x20: i+=19; break;                  // modify tier
+      case 0x9F: i+=6; break;
+      case 0xE3:                                // Eeprom update
+        {
+        int ex=emmdata[i]&15;
+        if(!emmP || !emmP->HasFlags(N2FLAG_Ex)) {
+          i+=emmdata[i+4]+5;
+          PRINTF(L_SYS_EMM,"E%X for provider %04x not supported",ex,id);
+          break;
+          }
+        int r;
+        if((r=emmP->ProcessEx(emmdata,cmdLen,i+1))>0)
+          i+=r;
+        else {
+          PRINTF(L_SYS_EMM,"E%X executing failed for %04x",ex,id);
+          i=cmdLen;
+          }
         break;
+        }
       case 0xE1:
       case 0xE2:
-      case 0x00: // end of processing
-        i=cmdLen;
-        break;
+      case 0x00: i=cmdLen; break;              // end of processing
       default:
+        if(!contFail) LBPUT("unknown EMM nano");
+        LBPUT(" %02x",emmdata[i]);
+        contFail=true;
         i++;
         continue;
       }
+    LBFLUSH(); contFail=false;
     }
+  LBEND();
 }
 
 bool Ecm(unsigned char *buff, int cmdLen, int id)
@@ -140,8 +180,8 @@ static unsigned char odata[15] = { 0x80,0x30,0x47,0x07,0x45,0xec,0xc1,0xee,0xc5,
 
 int main(int argc, char *argv[])
 {
-  if(argc<4) {
-    printf("usage: %s <plugin-dir> <id> <ECM/EMM> <raw-file>\n",argv[0]);
+  if(argc<5) {
+    printf("usage: %s <plugin-dir> <id> <ECM/EMM> <raw-file> [<raw-file> [..]]\n",argv[0]);
     return 1;
     }
 
@@ -156,14 +196,17 @@ int main(int argc, char *argv[])
   InitAll(argv[1]);
   LogAll();
   cLogging::SetModuleOption(LCLASS(L_SYS,L_SYS_DISASM),false);
-  unsigned char data[256];
-  int len=ReadRaw(argv[4],data,sizeof(data));
-  if((mode==1 && len!=64) || (mode==2 && len!=96)) {
-    printf("bad raw file format\n");
-    return 1;
-    }
 
   int id=strtol(argv[2],0,0);
-  if(mode==1) Ecm(data,len,id);
-  else if(mode==2) Emm(data,len,id);
+  int dlen=(mode==1) ? 64 : 96;
+  unsigned char data[4096];
+  for(int pos=4; pos<argc; pos++) {
+    int len=ReadRaw(argv[pos],data,sizeof(data));
+    if(len%dlen != 0) { printf("bad raw file format\n"); exit(1); }
+
+    for(int alen=0; alen<len; alen+=dlen) {
+      if(mode==1) Ecm(&data[alen],dlen,id);
+      else if(mode==2) Emm(&data[alen],dlen,id);
+      }
+    }
 }