SASC-NG
DVBSoftCAM

plugin_ffdecsa.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <pthread.h>
00004 #include <string.h>
00005 #include <unistd.h>
00006 #include <fcntl.h>
00007 #include <assert.h>
00008 #include <sys/ioctl.h>
00009 #include "plugin_ringbuf.h"
00010 #include "plugin_getsid.h"
00011 
00012 #include "../FFdecsa/FFdecsa.h"
00013 
00014 #define PLUGIN_ID 30
00015 #define DBG_NAME "CSA"
00016 #include "debug.h" //This is required to happen AFTER PLUGIN_ID is defined
00017 
00018 #define FF_MAX_IDX 16
00019 #define FF_MAX_PID 8
00020 
00021 #define push_empty_queue(_item, _queue) {      \
00022           pthread_mutex_lock(&list_lock);    \
00023           list_add(_item, _queue);             \
00024           pthread_mutex_unlock(&list_lock);  \
00025 }
00026 
00027 struct keyindex {
00028   int valid;
00029   unsigned char even[8];
00030   unsigned char odd[8];
00031   void *keys;
00032   int queued;
00033   int status;
00034 };
00035 
00036 struct csastruct {
00037   list_head list;
00038   int adapter;
00039   ringbuffer *rb;
00040   unsigned char *csaPtr;
00041   struct list_head pid_map;
00042   struct keyindex keyindex[FF_MAX_IDX];
00043   int nexus_fixup;
00044   unsigned int avg;
00045   int avgcnt;
00046   struct parser_cmds *dvr;
00047   int state;
00048   pthread_mutex_t keylock;
00049   pthread_mutex_t state_lock;
00050   pthread_cond_t csa_cond;
00051 };
00052 
00053 static unsigned char **range;
00054 static int cluster_size;
00055 static uint cluster_size_bytes;
00056 
00057 static LIST_HEAD(csalist);
00058 static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
00059 
00060 
00061 enum {
00062   NOT_ENCRYPTED = 0,
00063   ENCRYPTED_NOT_READY = 1,
00064   ENCRYPTED_READY = 2,
00065 };
00066 
00067 struct pid {
00068   struct list_head list;
00069   int pid;
00070   int index;
00071 };
00072 static LIST_HEAD(pidmap_empty_queue);
00073 
00074 static inline struct csastruct *find_csa_from_adpt(int adapt)
00075 {
00076   struct csastruct *csa;
00077   ll_find_elem(csa, csalist, adapter, adapt, struct csastruct);
00078   return csa;
00079 }
00080 
00081 void update_keys(int adpt, unsigned char keytype, int index, unsigned char *key, int pid)
00082 {
00083     int i;
00084     struct pid *pid_ll;
00085     struct csastruct *csa = find_csa_from_adpt(adpt);
00086 
00087     if(key == NULL) {
00088       dprintf0("Got command(%d): %c idx: %d pid: %d\n", adpt, keytype, index,
00089                pid);
00090     } else {
00091       dprintf0("Got command(%d): %c idx: %d pid: %d key: "
00092              "%02x%02x...%02x\n", adpt, keytype, index, pid,
00093              key[0], key[1], key[7]);
00094     }
00095     assert(csa);
00096     if(! csa)
00097       return;
00098     if(index < 0 || index >= FF_MAX_IDX)
00099       return;
00100 
00101     pthread_mutex_lock(&csa->state_lock);
00102     if (keytype == 'I') //Invalidate
00103     {
00104         csa->state = NOT_ENCRYPTED;
00105         dprintf1("Setting state: NOT_ENCRYPTED\n");
00106         pthread_mutex_lock(&csa->keylock);
00107         for(i=0; i < FF_MAX_IDX; i++)
00108           csa->keyindex[i].valid = 0;
00109         //csa_ready = 0;
00110         pthread_mutex_unlock(&csa->keylock);
00111         while(! list_empty(&csa->pid_map)) {
00112           pid_ll = list_entry(csa->pid_map.next, struct pid);
00113           list_del(&pid_ll->list);
00114           push_empty_queue(&pid_ll->list, &pidmap_empty_queue);
00115         }
00116         pthread_mutex_unlock(&csa->state_lock);
00117         return;
00118     }
00119     if (keytype == 'P') //PID
00120     {
00121         ll_find_elem(pid_ll, csa->pid_map, pid, pid, struct pid);
00122         if(pid_ll) {
00123           pthread_mutex_unlock(&csa->state_lock);
00124           return;
00125         }
00126         if(! csa->keyindex[index].valid) {
00127           csa->keyindex[index].valid = 1;
00128           csa->keyindex[index].status = 0;
00129           csa->keyindex[index].queued = 0;
00130         }
00131         pop_entry_from_queue_l(pid_ll, &pidmap_empty_queue, struct pid, &list_lock);
00132         pid_ll->pid = pid;
00133         pid_ll->index = index;
00134         list_add(&pid_ll->list, &csa->pid_map);
00135         pthread_mutex_unlock(&csa->state_lock);
00136         dprintf1("Adding pid %d to list\n", pid);
00137         return;
00138     }
00139     if (keytype == 'C') //Close PID
00140     {
00141         ll_find_elem(pid_ll, csa->pid_map, pid, pid, struct pid);
00142         if(pid_ll) {
00143           index = pid_ll->index;
00144           list_del(&pid_ll->list);
00145           push_empty_queue(&pid_ll->list, &pidmap_empty_queue);
00146           ll_find_elem(pid_ll, csa->pid_map, index, index, struct pid);
00147           if(pid_ll == NULL) {
00148             //no valid pids on this index
00149             csa->keyindex[index].status = 0;
00150             if(list_empty(&csa->pid_map)) {
00151               //state = ENCRYPTED_NOT_READY;
00152               csa->state = NOT_ENCRYPTED;
00153               dprintf1("Setting state: NOT_ENCRYPTED\n");
00154             }
00155           }
00156         }
00157         pthread_mutex_unlock(&csa->state_lock);
00158         dprintf1("Removing pid %d to list state = %d\n", pid, csa->state);
00159         return;
00160     }
00161     ll_find_elem(pid_ll, csa->pid_map, index, index, struct pid);
00162     if(pid_ll == NULL) {
00163         pthread_mutex_unlock(&csa->state_lock);
00164         return;
00165     }
00166     pthread_mutex_lock(&csa->keylock);
00167     if (keytype == 'E') //Even
00168     {
00169         memcpy( csa->keyindex[index].even, key, 8);
00170         csa->keyindex[index].queued |= 0x02;
00171         csa->keyindex[index].status |= 0x02;
00172         if(csa->state == NOT_ENCRYPTED && csa->keyindex[index].status == 3) {
00173           csa->state = ENCRYPTED_NOT_READY;
00174           dprintf1("Setting state: ENCRYPTED_NOT_READY\n");
00175         }
00176         dprintf1("Processed Even Key (idx=%d): State = %d, ready = %d\n",
00177                  index, csa->state, csa->keyindex[index].status);
00178     }
00179     else if (keytype == 'O') //Odd
00180     {
00181         memcpy( csa->keyindex[index].odd, key, 8);
00182         csa->keyindex[index].queued |= 0x01;
00183         csa->keyindex[index].status |= 0x01;
00184         if(csa->state == NOT_ENCRYPTED && csa->keyindex[index].status == 3) {
00185           csa->state = ENCRYPTED_NOT_READY;
00186           dprintf1("Setting state: ENCRYPTED_NOT_READY\n");
00187         }
00188         dprintf1("Processed Odd Key (idx=%d): State = %d, ready = %d\n",
00189                  index, csa->state, csa->keyindex[index].status);
00190     }
00191     else if (keytype == 'N') //Nexus
00192     {
00193         csa->nexus_fixup = 1;
00194         if(csa->state == NOT_ENCRYPTED) {
00195           csa->state = ENCRYPTED_NOT_READY;
00196           dprintf1("Setting state: ENCRYPTED_NOT_READY\n");
00197         }
00198     }
00199     pthread_mutex_unlock(&csa->keylock);
00200     pthread_mutex_unlock(&csa->state_lock);
00201     return;
00202 }
00203 
00204 static int process_ts(struct csastruct *csa, unsigned char *buffer, uint end,
00205                       int force)
00206 {
00207     unsigned char tmp;
00208     struct pid *pid_ll;
00209     int ret = 0, rangeptr = 0, dec = 0;
00210     uint pos = 0;
00211     uint start_enc, end_enc;
00212     int index = -1;
00213     int odd_even;
00214     int pkt_count = 0;
00215     if(csa->nexus_fixup) {
00216       while(pos < end) {
00217         buffer[pos+3] &= 0x3F;
00218         pos += TSPacketSIZE;
00219       }
00220       return end;
00221     }
00222     //old way
00223     //if(! end || ! force && end < 6000)
00224     //  return 0;
00225 
00226     while (pos < end)
00227     {
00228         tmp=buffer[pos+3] & 0xC0;
00229         if(tmp == 0xc0 || tmp == 0x80)
00230             break;
00231         pos += TSPacketSIZE;
00232     }
00233     //new way
00234     if(! force && end - pos < cluster_size_bytes)
00235       return  pos;
00236     ret = pos;
00237     start_enc = end_enc = pos;
00238     pthread_mutex_lock(&csa->state_lock);
00239     while(end - end_enc >= TSPacketSIZE && pkt_count < cluster_size) {
00240         odd_even = buffer[end_enc+3] & 0xC0;
00241         if(odd_even) {
00242             int pid = ((buffer[end_enc + 1] << 8) + buffer[end_enc + 2])
00243                       & 0x1FFF;
00244             ll_find_elem(pid_ll, csa->pid_map, pid, pid, struct pid);
00245             if(pid_ll == NULL) {
00246                 //What to do with an unknown pid?
00247                 //Let's try to decode it anyway
00248                 dprintf3("Didn't find pid %d\n", pid);
00249                 end_enc+=TSPacketSIZE;
00250                 continue;
00251             }
00252             if(index == -1) {
00253                 //First encrypted packet (with a valid pid)
00254                 index = pid_ll->index;
00255                 tmp=odd_even;
00256                 pkt_count++;
00257             }
00258             else if(index != pid_ll->index) {
00259                 //Encrypted packet with a different index
00260                 if(start_enc != end_enc) {
00261                     //there are previous packets that can be decoded
00262                     range[rangeptr++] = buffer + start_enc;
00263                     range[rangeptr++] = buffer + end_enc;
00264                     range[rangeptr] = 0;
00265                 }
00266                 //skip this packet
00267                 start_enc = end_enc + TSPacketSIZE;
00268             } else {
00269               pkt_count++;
00270             }
00271         }
00272         end_enc+=TSPacketSIZE;
00273     }
00274     pthread_mutex_unlock(&csa->state_lock);
00275     if (index != -1 && start_enc != end_enc) {
00276         //add the last set of packets to the encryption queue
00277         range[rangeptr++] = buffer + start_enc;
00278         range[rangeptr++] = buffer + end_enc;
00279         range[rangeptr] = 0;
00280     }
00281     if (rangeptr > 0) {
00282         pthread_mutex_lock(&csa->keylock);
00283         if (! csa->keyindex[index].valid || csa->keyindex[index].status != 3) {
00284            pthread_mutex_unlock(&csa->keylock);
00285            return ret;
00286         }
00287         if (csa->keyindex[index].queued == 3)
00288         {
00289             csa->keyindex[index].queued = 0;
00290             set_even_control_word(csa->keyindex[index].keys, csa->keyindex[index].even);
00291             set_odd_control_word(csa->keyindex[index].keys, csa->keyindex[index].odd);
00292         }
00293 
00294         if (csa->keyindex[index].queued & 0x02 && tmp != 0x80)
00295         {
00296             csa->keyindex[index].queued &= 0x01;
00297             set_even_control_word(csa->keyindex[index].keys, csa->keyindex[index].even);
00298         }
00299         if (csa->keyindex[index].queued & 0x01 && tmp != 0xC0)
00300         {
00301             csa->keyindex[index].queued &= 0x02;
00302             set_odd_control_word(csa->keyindex[index].keys, csa->keyindex[index].odd);
00303         }
00304         pthread_mutex_unlock(&csa->keylock);
00305 
00306         if((_dbglvl >> PLUGIN_ID) & 3) {
00307           csa->avg = (csa->avg * 99 + pkt_count*100) / 100;
00308           if(csa->avg == 0)
00309             csa->avg = 1;
00310           csa->avgcnt++;
00311           if(csa->avgcnt == 100) {
00312             csa->avgcnt = 0;
00313             dprintf0("decrypted packets max:%d now:%u of %u avg:%f\n",
00314                 cluster_size, pkt_count, end / TSPacketSIZE, csa->avg / 100.0);
00315           }
00316         }
00317         dec = decrypt_packets(csa->keyindex[index].keys, range) * TSPacketSIZE;
00318         if(ret + buffer == range[0])
00319           ret+=dec;
00320         //printf("decrypted now=%d, decrypted=%d, total=%d\n", pkt, pkt_done, pkt_cnt);
00321     }
00322     return ret;
00323 }
00324 
00325 static struct csastruct *find_csa_from_rb(struct ringbuffer *rb, int init) {
00326   struct csastruct *entry;
00327   int notalign;
00328 
00329   if(rb->state != RB_OPEN)
00330     return NULL;
00331   pthread_mutex_lock(&list_lock);
00332   ll_find_elem(entry, csalist, rb, rb, struct csastruct);
00333   if (! init) {
00334     pthread_mutex_unlock(&list_lock);
00335     return entry;
00336   }
00337   if(! entry) {
00338     dprintf0("Creating csa for rb: %d\n", rb->num);
00339     entry = find_csa_from_adpt(rb->num);
00340     assert(entry);
00341   } else {
00342     dprintf0("Resetting csa for rb: %d\n", rb->num);
00343   }
00344   pthread_mutex_lock(&rb->rw_lock);
00345   //things may have changed since above
00346   if(rb->state != RB_OPEN) {
00347     pthread_mutex_unlock(&rb->rw_lock);
00348     pthread_mutex_unlock(&list_lock);
00349     return NULL;
00350   }
00351   entry->rb = rb;
00352   entry->csaPtr = rb->rdPtr;
00353   entry->avg = cluster_size * 100;
00354   entry->avgcnt = 0;
00355   notalign = (entry->csaPtr - rb->buffer) % TSPacketSIZE;
00356   if(notalign) {
00357     //The read pointer is not aligned, but the wrptr is required to be
00358     entry->csaPtr += TSPacketSIZE - notalign;
00359     if(entry->csaPtr > rb->end)
00360       entry->csaPtr = rb->buffer + (entry->csaPtr - rb->end);
00361     if((rb->rdPtr > rb->wrPtr && entry->csaPtr > rb->wrPtr && entry->csaPtr < rb->rdPtr) || (rb->rdPtr <= rb->wrPtr && entry->csaPtr > rb->wrPtr)) { 
00362       dprintf0("INIT buf: %p rd: %p csa: %p wr: %p end: %p\n",
00363           rb->buffer, rb->rdPtr, entry->csaPtr, rb->wrPtr, rb->end);
00364       assert(0);
00365     }
00366   }
00367   dprintf1("INIT buf: %p rd: %p csa: %p wr: %p end: %p\n",
00368          rb->buffer, rb->rdPtr, entry->csaPtr, rb->wrPtr, rb->end);
00369   pthread_mutex_unlock(&rb->rw_lock);
00370   pthread_mutex_unlock(&list_lock);
00371   return entry;
00372 }
00373 
00374 /*Check and/or set state */
00375 /*MUST lock state_lock before calling!*/
00376 int check_state(struct csastruct *csa, struct ringbuffer *rb) {
00377   if(csa->state == NOT_ENCRYPTED)
00378     return NOT_ENCRYPTED;
00379   if(csa->state == ENCRYPTED_READY)
00380     return ENCRYPTED_READY;
00381   if(csa->state == ENCRYPTED_NOT_READY) {
00382     if(list_empty(&csa->pid_map))
00383       return NOT_ENCRYPTED;
00384     find_csa_from_rb(rb, 1);
00385     csa->state = ENCRYPTED_READY;
00386     dprintf1("Setting state: ENCRYPTED_READY\n");
00387     return ENCRYPTED_READY;
00388   }
00389   return NOT_ENCRYPTED;
00390 }
00391  
00392 /*If need_bytes >0 we must block until some bytes can be read */
00393 int check_encrypted(struct ringbuffer *rb, int need_bytes)
00394 {
00395   int processed_bytes = 0;
00396   int avail_bytes;
00397   int state;
00398   struct csastruct *csa = find_csa_from_adpt(rb->num);
00399 
00400   assert(csa);
00401   if(csa) {
00402     pthread_mutex_lock(&csa->state_lock);
00403     state = check_state(csa, rb);
00404   } else {
00405     state = NOT_ENCRYPTED;
00406   }
00407 
00408   if(state == NOT_ENCRYPTED) {
00409 #if 0
00410     unsigned char *ptr = rb->buffer;
00411     while(ptr < rb->end) {
00412       ptr[3] &= 0x3f;
00413       ptr += TSPacketSIZE;
00414     }
00415 #endif
00416     if(rb->rdPtr > rb->wrPtr)
00417       avail_bytes = rb->end - rb->rdPtr + rb->wrPtr - rb->buffer - TSPacketSIZE;
00418     else
00419       avail_bytes = rb->wrPtr - rb->rdPtr - TSPacketSIZE;
00420     if(csa) {
00421       pthread_mutex_unlock(&csa->state_lock);
00422     }
00423     //printf("Unencrypted.  Returning %d bytes\n", avail_bytes);
00424     return avail_bytes;
00425   }
00426   pthread_mutex_lock(&rb->rw_lock); // protect csaPtr
00427   pthread_mutex_unlock(&csa->state_lock);
00428 
00429   //There should be no way for csa not to be set here
00430   assert(csa->rb);
00431 
00432   if((rb->rdPtr <= csa->csaPtr  && csa->csaPtr <= rb->wrPtr) ||
00433      (rb->wrPtr < rb->rdPtr && rb->rdPtr <= csa->csaPtr)) {
00434     processed_bytes = csa->csaPtr -  rb->rdPtr;
00435   } else if(csa->csaPtr <= rb->wrPtr && rb->wrPtr < rb->rdPtr) {
00436     processed_bytes = rb->end - rb->rdPtr + csa->csaPtr - rb->buffer ;
00437   } else {
00438     //rd == wr && csa != rd
00439     //     OR
00440     //wr < csa < rd
00441     //We used to get here when switching between encrypted and clear
00442     //But no more!
00443     //csa->csaPtr = rb->rdPtr;
00444     //processed_bytes = 0;
00445     dprintf0("buf: %p rd: %p csa: %p wr: %p end: %p\n",
00446            rb->buffer, rb->rdPtr, csa->csaPtr, rb->wrPtr, rb->end);
00447     assert(0);
00448   }
00449   if(need_bytes > 0 && processed_bytes < need_bytes) {
00450     //ring-read is waiting for decrypted data.  we will stall until we get some
00451     //NOTE: We don't care about the return in this case as we need to call again
00452     //      to compute processed_bytes
00453     dprintf0("buf: %p rd: %p csa: %p wr: %p end: %p\n",
00454            rb->buffer, rb->rdPtr, csa->csaPtr, rb->wrPtr, rb->end);
00455     msg_replace(MSG_HIGH_PRIORITY, MSG_RINGBUF, rb->num, rb);
00456     pthread_cond_wait(&csa->csa_cond, &rb->rw_lock);
00457   }
00458   //printf("buf: %p rd: %p csa: %p wr: %p end: %p processed: %d\n",
00459   //       rb->buffer, rb->rdPtr, csa->csaPtr, rb->wrPtr, rb->end,
00460   //       processed_bytes);
00461   pthread_mutex_unlock(&rb->rw_lock);
00462   return processed_bytes;
00463 }
00464 
00465 static void process_ffd(struct msg *msg, unsigned int priority)
00466 {
00467   struct csastruct *csa;
00468   int ret;
00469   int end = 0;
00470   unsigned char *wrPtr;
00471   if(msg->type == MSG_RINGBUF) {
00472     struct ringbuffer *rb = (struct ringbuffer *)msg->data;
00473     int bytes;
00474     msg->type = MSG_PROCESSED;
00475 #ifdef NO_RINGBUF
00476     return;
00477 #endif
00478     csa = find_csa_from_adpt(rb->num);
00479     assert(csa);
00480     if(! csa)
00481       return;
00482 
00483     pthread_mutex_lock(&csa->state_lock);
00484     if(check_state(csa, rb) == NOT_ENCRYPTED) {
00485       pthread_mutex_unlock(&csa->state_lock);
00486       return;
00487     }
00488 
00489     assert(csa->rb);
00490 
00491     pthread_mutex_lock(&rb->rw_lock);
00492     pthread_mutex_unlock(&csa->state_lock);
00493 
00494     wrPtr = rb->wrPtr;
00495 
00496     if (csa->csaPtr > wrPtr) {
00497       bytes = rb->end - csa->csaPtr;
00498       end = 1;
00499     } else
00500       bytes = wrPtr - csa->csaPtr;
00501     pthread_mutex_unlock(&rb->rw_lock);
00502     ret = process_ts(csa, csa->csaPtr, bytes, end);
00503     pthread_mutex_lock(&rb->rw_lock);
00504     if (csa->csaPtr + ret > rb->end) {
00505       dprintf0("rdPtr: %lu csaPtr: %lu wrPtr: %lu end: %lu bytes: %d end: %d\n",
00506              (unsigned long) (rb->rdPtr - rb->buffer),
00507              (unsigned long)(csa->csaPtr - rb->buffer),
00508              (unsigned long)(rb->wrPtr - rb->buffer),
00509              (unsigned long)(rb->end - rb->buffer), bytes, ret);
00510       assert(csa->csaPtr + ret <= rb->end);
00511     }
00512     csa->csaPtr += ret;
00513     if(csa->csaPtr == rb->end)
00514       csa->csaPtr = rb->buffer;
00515 
00516     if(ret) {
00517       if (rb->flags & O_NONBLOCK) {
00518         struct dvblb_pollmsg msg;
00519         msg.count = 0;
00520         //Is this thread safe?
00521         pthread_mutex_lock(&csa->dvr->poll_mutex);
00522         ioctl(csa->dvr->virtfd, DVBLB_CMD_ASYNC, &msg);
00523         pthread_mutex_unlock(&csa->dvr->poll_mutex);
00524       } else
00525         pthread_cond_signal(&csa->csa_cond);
00526     }
00527     pthread_mutex_unlock(&rb->rw_lock);
00528 //    dprintf0("decoded: %d - %d\n", ret, bytes);
00529     if(ret) {
00530 //      dprintf0("Sending RB1: %p\n", rb);
00531       msg_replace(MSG_HIGH_PRIORITY, MSG_RINGBUF, rb->num, rb);
00532     }
00533     sched_yield();
00534   }
00535   else if(msg->type == MSG_RINGCLOSE) {
00536     msg->type = MSG_PROCESSED;
00537     struct ringbuffer *rb = (struct ringbuffer *)msg->data;
00538     csa = find_csa_from_adpt(rb->num);
00539     msg_remove_type_from_list(MSG_HIGH_PRIORITY, MSG_RINGBUF, rb->num, NULL);
00540     msg_remove_type_from_list(MSG_HIGH_PRIORITY, MSG_RINGCLOSE, rb->num, NULL);
00541     assert(csa);
00542     if(! csa)
00543       return;
00544     dprintf0("Removing csa for rb: %d\n", rb->num);
00545     pthread_mutex_lock(&csa->state_lock);
00546     rb->release(rb);
00547     pthread_mutex_lock(&list_lock);
00548     csa->rb = NULL;
00549     pthread_mutex_unlock(&list_lock);
00550     if(csa->state == ENCRYPTED_READY) {
00551       csa->state = ENCRYPTED_NOT_READY;
00552       dprintf1("Setting state: ENCRYPTED_NOT_READY\n");
00553     }
00554     pthread_mutex_unlock(&csa->state_lock);
00555   }
00556 }
00557 
00558 //static void launch_ffd() {
00559 //  pthread_create(&thread, NULL, ffd_loop, NULL);
00560 //}
00561 
00562 #ifdef NO_RINGBUF
00563 static void preread_call(struct parser_cmds *pc, struct poll_ll *fdptr,
00564                       cmdret_t *result, int *ret, 
00565                       unsigned long int cmd, unsigned char *data)
00566 {
00567   struct dvblb_custommsg *ci = (struct dvblb_custommsg *)data;
00568   ci->u.count -= ci->u.count % TSPacketSIZE;
00569 }
00570   
00571 static void read_call(struct parser_cmds *pc, struct poll_ll *fdptr,
00572                       cmdret_t *result, int *ret, 
00573                       unsigned long int cmd, unsigned char *data)
00574 {
00575 //  struct dvblb_custommsg *ci = (struct dvblb_custommsg *)data;
00576   int bytes_left = *ret, tmp;
00577   do {
00578 //    dprintf0("Decrypting %d bytes (%d done so far)\n", bytes_left, (*ret - bytes_left));
00579     tmp = process_ts(pc->mmap + (*ret - bytes_left), bytes_left);
00580     bytes_left -= tmp;
00581   } while(bytes_left);
00582   *result = CMD_SKIPCALL;
00583 }
00584 
00585 #endif
00586 
00587 static void connect_ffd(struct parser_adpt *pc_all)
00588 {
00589   struct list_head *ptr;
00590   struct csastruct *csa;
00591 #ifdef NO_RINGBUF
00592   struct cmd_list *dvr_preread = register_cmd(preread_call);
00593   struct cmd_list *dvr_postread = register_cmd(read_call);
00594   list_add(&dvr_preread.list, &pc_all->dvr->pre_read);
00595   list_add(&dvr_postread.list, &pc_all->dvr->post_read);
00596 #else
00597   
00598   range = (unsigned char **)malloc(pc_all->dvr->common->buffersize /
00599                                    TSPacketSIZE + 1);
00600   csa = (struct csastruct *)malloc(sizeof(struct csastruct));
00601   memset(csa, 0, sizeof(struct csastruct));
00602   pthread_mutex_init(&csa->keylock, NULL);
00603   pthread_mutex_init(&csa->state_lock, NULL);
00604   pthread_cond_init(&csa->csa_cond, NULL);
00605   INIT_LIST_HEAD(&csa->pid_map);
00606 
00607   csa->adapter = pc_all->dvr->common->virt_adapt;
00608   csa->dvr = pc_all->dvr;
00609   csa->state = NOT_ENCRYPTED;
00610   dprintf1("Setting state: NOT_ENCRYPTED\n");
00611   for(int i = 0; i < FF_MAX_IDX; i++) {
00612     csa->keyindex[i].valid = 0;
00613     csa->keyindex[i].keys =  get_key_struct();
00614   }
00615   list_add_tail(&csa->list, &csalist);
00616   cluster_size = get_suggested_cluster_size();
00617   cluster_size_bytes = (uint)cluster_size * TSPacketSIZE;
00618   ringbuf_register_callback(check_encrypted);
00619   list_for_each(ptr, &plugin_cmdlist) {
00620     struct plugin_cmd *cmd = list_entry(ptr, struct plugin_cmd);
00621     if(cmd->plugin == PLUGIN_RINGBUF) {
00622       cmd->send_msg(pc_all->dvr, 1);
00623       break;
00624     }
00625   }
00626 #endif
00627 }
00628 
00629 
00630 //list, plugin_id, name, parse_args, connect, launch, message, send_msg
00631 static struct plugin_cmd plugin_cmds = {{NULL, NULL}, PLUGIN_ID, "ffdecsa", 
00632                  NULL, connect_ffd, NULL, process_ffd, NULL, NULL};
00633 int __attribute__((constructor)) __ffdecsa_init(void)
00634 {
00635   list_add_tail(&plugin_cmds.list, &plugin_cmdlist);
00636   return 0;
00637 }
00638 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines