static void tvhcsa_csa_cbc_descramble ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int tsb_len ) { const uint8_t *tsb_end = tsb + tsb_len; assert(csa->csa_fill >= 0 && csa->csa_fill < csa->csa_cluster_size); #if ENABLE_DVBCSA uint8_t *pkt; int ev_od; int len; int offset; int n; for ( ; tsb < tsb_end; tsb += 188) { pkt = csa->csa_tsbcluster + csa->csa_fill * 188; memcpy(pkt, tsb, 188); csa->csa_fill++; do { // handle this packet if((pkt[3] & 0x80) == 0) // clear or reserved (0x40) break; ev_od = pkt[3] & 0x40; pkt[3] &= 0x3f; // consider it decrypted now if(pkt[3] & 0x20) { // incomplete packet offset = 4 + pkt[4] + 1; len = 188 - offset; n = len >> 3; // FIXME: //residue = len - (n << 3); if(n == 0) { // decrypted==encrypted! break; // this doesn't need more processing } } else { len = 184; offset = 4; // FIXME: //n = 23; // FIXME: //residue = 0; } if(ev_od == 0) { csa->csa_tsbbatch_even[csa->csa_fill_even].data = pkt + offset; csa->csa_tsbbatch_even[csa->csa_fill_even].len = len; csa->csa_fill_even++; } else { csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = pkt + offset; csa->csa_tsbbatch_odd[csa->csa_fill_odd].len = len; csa->csa_fill_odd++; } } while(0); if(csa->csa_fill == csa->csa_cluster_size) tvhcsa_csa_cbc_flush(csa, s); }
static void tvhcsa_csa_cbc_descramble ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int tsb_len ) { const uint8_t *tsb_end = tsb + tsb_len; assert(csa->csa_fill >= 0 && csa->csa_fill < csa->csa_fill_size); #if ENABLE_DVBCSA uint8_t *pkt; int_fast8_t ev_od; int_fast16_t len; int_fast16_t offset; for ( ; tsb < tsb_end; tsb += 188) { pkt = csa->csa_tsbcluster + csa->csa_fill * 188; memcpy(pkt, tsb, 188); csa->csa_fill++; do { // handle this packet if((pkt[3] & 0x80) == 0) // clear or reserved (0x40) break; ev_od = pkt[3] & 0x40; pkt[3] &= 0x3f; // consider it decrypted now if(pkt[3] & 0x20) { // incomplete packet if(!(pkt[3] & 0x10)) // no payload - but why scrambled??? break; offset = 4 + pkt[4] + 1; if (offset >= 188){ // invalid offset (residue handling?) if (tvhlog_limit(&csa->tvhcsa_loglimit, 30)) tvhtrace(LS_CSA, "invalid payload offset in packet for service \"%s\" (offset=%d pkt[3]=0x%02x pkt[4]=0x%02x)", ((mpegts_service_t *)s)->s_dvb_svcname, (int)offset, pkt[3], pkt[4]); break; // no more processing } len = 188 - offset; } else { len = 184; offset = 4; } if(ev_od == 0) { csa->csa_tsbbatch_even[csa->csa_fill_even].data = pkt + offset; csa->csa_tsbbatch_even[csa->csa_fill_even].len = len; csa->csa_fill_even++; if(csa->csa_fill_even == csa->csa_cluster_size) tvhcsa_csa_cbc_flush(csa, s); } else { csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = pkt + offset; csa->csa_tsbbatch_odd[csa->csa_fill_odd].len = len; csa->csa_fill_odd++; if(csa->csa_fill_odd == csa->csa_cluster_size) tvhcsa_csa_cbc_flush(csa, s); } } while(0); if(csa->csa_fill == csa->csa_fill_size ) tvhcsa_csa_cbc_flush(csa, s); } #else #error "Unknown CSA descrambler" #endif }