[linux-dvb] Twinhan VP1030A CI/CAM problems and solutions

linuxtv at zacglen.com.au linuxtv at zacglen.com.au
Sun Apr 9 05:34:45 CEST 2006


There seem to be quite a few problems getting TwinHan VP1030 etc
Conditional Access Module working properly.

The LinuxTV wiki says they dont work (mostly) and so do various
other application writers (eg. mythtv, videolan, etc).

Well there is a very simple reason - the dst_ca module is buggy, as is
the ca_zap application and associated libraries.

Here are the fixes.  Somebody with CVS access might like to take the
time to translate them and create appropriate patches.

1. In drivers/media/dvb/bt8xx/dst_ca.c

   In function handle_dst_tag() a resource object is inserted
   into beginning of ca message, but no matter how long the
   user-supplied asn1 length is, the user-supplied content is
   always copied from byte 4 onwards.
   This means that if you have a ca message over 128 bytes
   then you get a garbled message sent.
   The solution is to pass the asn1 length length (sic) into the
   function so that it can properly determine where the data
   content really starts (ie sometimes at byte 5).

   The actual i2c transmission of the message is ok (after above fix)
   because it uses the contents of the message itself to determine
   the length to send.

2. In linuxtv-dvd-apps/lib/libdvben50221/en50221_encode.c

   In function en50221_encode_header() it is wrong to incorporate
   element reserved_2 into the message.
   This stops TwinHan CAM working properly in many instances.
   Personally I think all reserved (ie unknown) bits should be set
   to zero when constructing new messages - unless you actually
   know what they are - in which case they shouldn't be called reserved.

3. In linuxtv-dvd-apps/lib/libdvben50221/en50221_encode.c

   In function en50221_encode_descriptor().
   Allowance should be made for encoding descriptors such as
   TAG_SMOOTHING_BUFFER_DESCRIPTOR and TAG_SYSTEM_CLOCK_DESCRIPTOR when
   this function is called from higher level.
   It is ok to restrict descriptors to CA when handling streams
   but at higher level all PMT-supplied descriptors should be encoded.

   Also, the ca_pid upper bits should be masked with 0x1f when encoding.

3. In linuxtv-dvd-apps/lib/libdvben50221/en50221_encode.c

   In function en50221_encode_streams().
   Contrary to what I said previously about reversed element encoding,
   it would appear that in this case the reserved_1 element can
   be significant, and must be included in message.

   However, reserved_2 should be ommitted.

4. In linuxtv-dvd-apps/lib/libdvben50221/asn_1.c

   The asn_1_encode() function is indigestible.
   How about this?

    uint32_t asn_1_encode(int length, uint8_t *array, unsigned arraysize)
    {
	unsigned ai = 0;
        unsigned ii = 0;
        unsigned oi = 0;
        uint8_t buff[20];
   
        for (ai = 0; length; ai++, length >>= 8)
        {
              if (ai >= sizeof(buff)/sizeof(buff[0]) || ai > arraysize)
              {
                  // probably wont ever happen
                  return 0;
              }
              buff[ai] = length;
        }
	if (ai > 1)
	      array[oi++] = (0x80 | ai);
	for (ii = 0; ii < ai; ii++)
	      array[oi++] = buff[ai - ii - 1];
	return ai;
    }

5. In nearly every linux-dvd-apps library function.

   Bitsfields are used extensively, but they are largely pointless.
   Worse still, they effectively restrict EN50221 element sizes
   to PMT etc sizes - but they are supposed to be independent.

   And since the bitfield structures are populated by bit shifting bytes,
   there is no point storing the resultant data in bitfields anyhow.

   Get rid of all the the bitfields in the headers and things start to
   get better and less buggy (just "s/:[0-9]*;/;/g").
   
6. As a matter of course all programs should use calloc() instead
   of malloc().  That makes sure that allocated structures are nicely
   cleared to zero, so that buggy programs that forget to initialize
   structures work better.

7. In linuxtv-dvb-apps/lib/libdvbsi/pmt.c

   When parsing streams the function parse_streams() carelessly goes
   beyond the end of the section and picks up garbage and turns
   them into garbage streams.
   That breaks a lot of things.

Ok, so I have run out of paper so I have to stop at this point.
There are many more bugs - too numerous to mention.
So numerous, in fact, that I decided it was better to write
my own applications.

I now have: DVBserver, DVBtune, DVBscan, and DVBepg

The DVBserver can record in one-off mode, or it can act as a
server satisfying client recording/broadcast requests.  It handles
multiple recording requests for different streams off same transponder
without retuning, otherwise retunes if priority is sufficient.
It also does proper CAM enabling. And it also broadcasts RTP streams.

The DVBepg does Electronic Programming Guide retrieval.
It works with standard EIT tables, but also correctly handles OpenTV (OTV)
content. It doesn't do a full OpenTV simulation - that isn't necessary
because the epg content is in nicely structure (compressed) tables.

These programs aren't publicly available yet because I am too busy
making them better and more powerful to do what I want them to do
today (sorry about the MS-speak). Some day soon perhaps.

LinuxTV person.




More information about the linux-dvb mailing list