diff -Nru dvb-apps-cacd165cb058/util/scan/dump-vdr.c dvb-apps-caidpatch/util/scan/dump-vdr.c
--- dvb-apps-cacd165cb058/util/scan/dump-vdr.c	2008-01-06 01:09:32.000000000 +0100
+++ dvb-apps-caidpatch/util/scan/dump-vdr.c	2008-01-06 12:04:00.589698429 +0100
@@ -131,6 +131,8 @@
 				 int orbital_pos,
 				 int we_flag,
 				 int dump_provider,
+				 uint16_t *ca_id,
+				 int ca_num,
 				 int ca_select,
 				 int vdr_version,
 				 int dump_channum,
@@ -183,8 +185,15 @@
 			else
 				scrambled = ca_select;
 		}
-		fprintf (f, ":%d:%d:%d:%d:%d:0", teletext_pid, scrambled,
-				service_id, network_id, transport_stream_id);
+		fprintf (f, ":%d:", teletext_pid);
+		fprintf (f, "%x", ca_id[0]);
+	        for (i = 1; i < ca_num; i++) {
+			if (ca_id[i] == 0) continue;
+                        fprintf (f, ",%x", ca_id[i]);
+			}
+		fprintf (f, ":%d:%d:%d:0",
+ 			service_id, (transport_stream_id > 0)?network_id:0,
+ 			transport_stream_id);
 		fprintf (f, "\n");
 	}
 }
diff -Nru dvb-apps-cacd165cb058/util/scan/dump-vdr.h dvb-apps-caidpatch/util/scan/dump-vdr.h
--- dvb-apps-cacd165cb058/util/scan/dump-vdr.h	2008-01-06 01:09:32.000000000 +0100
+++ dvb-apps-caidpatch/util/scan/dump-vdr.h	2008-01-06 11:42:24.659847595 +0100
@@ -30,6 +30,8 @@
 				 int orbital_pos,
 				 int we_flag,
 				 int dump_provider,
+				 uint16_t *ca_id,
+				 int ca_num,
 				 int ca_select,
 				 int vdr_version,
 				 int dump_channum,
diff -Nru dvb-apps-cacd165cb058/util/scan/scan.c dvb-apps-caidpatch/util/scan/scan.c
--- dvb-apps-cacd165cb058/util/scan/scan.c	2008-01-06 01:09:32.000000000 +0100
+++ dvb-apps-caidpatch/util/scan/scan.c	2008-01-06 11:58:34.351107151 +0100
@@ -142,7 +142,7 @@
 	unsigned int other_frequency_flag : 1;	/* DVB-T */
 	unsigned int wrong_frequency	  : 1;	/* DVB-T with other_frequency_flag */
 	int n_other_f;
-	uint32_t *other_f;			/* DVB-T freqeuency-list descriptor */
+	uint32_t *other_f;			/* DVB-T frequency-list descriptor */
 };
 
 
@@ -296,12 +296,47 @@
 		len = sizeof(s->ca_id);
 		warning("too many CA system ids\n");
 	}
+	s->ca_num=0;
 	memcpy(s->ca_id, buf, len);
-	for (i = 0; i < len / sizeof(s->ca_id[0]); i++)
+	for (i = 0; i < len / sizeof(s->ca_id[0]); i++) {
+		int id = ((s->ca_id[i] & 0x00FF) << 8) + ((s->ca_id[i] & 0xFF00) >> 8);
+		s->ca_id[i] = id;
 		moreverbose("  CA ID 0x%04x\n", s->ca_id[i]);
+		s->ca_num++;
+	}
 }
 
 
+static void parse_ca_descriptor (const unsigned char *buf,
+				struct service *s) {
+
+	unsigned char descriptor_length = buf [1];
+	int CA_system_ID;
+	int found=0;
+	int i;
+
+	buf += 2;
+
+	if (descriptor_length < 4) return;
+
+	CA_system_ID = (buf[0] << 8) | buf[1];
+
+	for (i=0; i<s->ca_num; i++)
+		if (s->ca_id[i] == CA_system_ID)
+			found++;
+
+	if (!found) {
+		if (s->ca_num + 1 >= CA_SYSTEM_ID_MAX)
+			warning("TOO MANY CA SYSTEM IDs.\n");
+		else {
+			moreverbose("  CA ID     : PID 0x%04x\n", CA_system_ID);
+			s->ca_id[s->ca_num]=CA_system_ID;
+			s->ca_num++;
+		}
+	} 	
+} 
+
+
 static void parse_iso639_language_descriptor (const unsigned char *buf, struct service *s)
 {
 	unsigned char len = buf [1];
@@ -639,6 +674,10 @@
 		}
 
 		switch (descriptor_tag) {
+		case 0x09:		/* 0x09 ca_descriptor, caid patch 20080106 */
+			if (t == PMT)
+				parse_ca_descriptor (buf, data);	
+			break;
 		case 0x0a:
 			if (t == PMT)
 				parse_iso639_language_descriptor (buf, data);
@@ -739,7 +778,7 @@
 
 	s = find_service (current_tp, service_id);
 	if (!s) {
-		error("PMT for serivce_id 0x%04x was not in PAT\n", service_id);
+		error("PMT for service_id 0x%04x was not in PAT\n", service_id);
 		return;
 	}
 
@@ -747,8 +786,17 @@
 
 	program_info_len = ((buf[2] & 0x0f) << 8) | buf[3];
 
-	buf += program_info_len + 4;
-	section_length -= program_info_len + 4;
+	// caid patch 20080106, search PMT program info for CA Ids
+	buf +=4;
+	section_length -= 4;
+
+	while (program_info_len > 0) {
+		int descriptor_length = ((int)buf[1]) + 2;
+		parse_descriptors(PMT, buf, section_length, s);
+		buf += descriptor_length;
+		section_length   -= descriptor_length;
+		program_info_len -= descriptor_length;
+		}
 
 	while (section_length >= 5) {
 		int ES_info_len = ((buf[3] & 0x0f) << 8) | buf[4];
@@ -2021,6 +2069,8 @@
 						    t->orbital_pos,
 						    t->we_flag,
 						    vdr_dump_provider,
+						    s->ca_id,
+						    s->ca_num,
 						    ca_select,
 						    vdr_version,
 						    vdr_dump_channum,
@@ -2094,7 +2144,6 @@
 	"	-x N	Conditional Access, (default -1)\n"
 	"		N=0 gets only FTA channels\n"
 	"		N=-1 gets all channels\n"
-	"		N=xxx sets ca field in vdr output to :xxx:\n"
 	"	-t N	Service select, Combined bitfield parameter.\n"
 	"		1 = TV, 2 = Radio, 4 = Other, (default 7)\n"
 	"	-p	for vdr output format: dump provider name\n"
