def readBouquet(bouquet_id):
    print("[DvbScanner] Reading bouquet_id = 0x%x..." % bouquet_id)

    fd = dvbreader.open("/dev/dvb/adapter0/demux0", bat_pid, bat_table, mask,
                        frontend)
    if fd < 0:
        print("[DvbScanner] Cannot open the demuxer")
        return None

    bat_section_version = -1
    bat_sections_read = []
    bat_sections_count = 0
    bat_content = []

    timeout = datetime.datetime.now()
    timeout += datetime.timedelta(0, TIMEOUT_SEC)
    while True:
        if datetime.datetime.now() > timeout:
            print("[DvbScanner] Timed out")
            break

        section = dvbreader.read_bat(fd, bat_table)
        if section is None:
            time.sleep(0.1)  # no data.. so we wait a bit
            continue

        if section["header"]["table_id"] == bat_table:
            if section["header"]["bouquet_id"] != bouquet_id:
                continue

            if section["header"]["version_number"] != bat_section_version:
                bat_section_version = section["header"]["version_number"]
                bat_sections_read = []
                bat_content = []
                bat_sections_count = section["header"][
                    "last_section_number"] + 1

            if section["header"]["section_number"] not in bat_sections_read:
                bat_sections_read.append(section["header"]["section_number"])
                bat_content += section["content"]

                if len(bat_sections_read) == bat_sections_count:
                    break

    dvbreader.close(fd)

    bouquet_name = None
    for section in bat_content:
        if section["descriptor_tag"] == 0x47:
            bouquet_name = section["description"]
            break

    if bouquet_name is None:
        print("[DvbScanner] Cannot get bouquet name for bouquet_id = 0x%x" %
              bouquet_id)
        return

    for section in bat_content:
        if section["descriptor_tag"] == 0xd4:
            bouquet = {
                "name": bouquet_name + " - " + section["description"],
                "region": section["region_id"],
                "bouquet": bouquet_id
            }
            bouquets_list.append(bouquet)

    print("[DvbScanner] Done")
    def updateAndReadServicesFreeSat(self, bouquet_id, region_id, namespace, transponders, servicehacks):
        print >> log, "[DvbScanner] Reading services..."

        fd = dvbreader.open(self.demuxer_device, self.bat_pid, self.bat_table_id, 0xFF, self.frontend)
        if fd < 0:
            print >> log, "[DvbScanner] Cannot open the demuxer"
            return None

        bat_section_version = -1
        bat_sections_read = []
        bat_sections_count = 0
        bat_content = []

        timeout = datetime.datetime.now()
        timeout += datetime.timedelta(0, self.TIMEOUT_SEC)
        while True:
            if datetime.datetime.now() > timeout:
                print >> log, "[DvbScanner] Timed out"
                break

            section = dvbreader.read_bat(fd, self.bat_table_id)
            if section is None:
                time.sleep(0.1)  # no data.. so we wait a bit
                continue

            if section["header"]["table_id"] == self.bat_table_id:
                if section["header"]["bouquet_id"] != bouquet_id:
                    continue

                if section["header"]["version_number"] != bat_section_version:
                    bat_section_version = section["header"]["version_number"]
                    bat_sections_read = []
                    bat_content = []
                    bat_sections_count = section["header"]["last_section_number"] + 1

                if section["header"]["section_number"] not in bat_sections_read:
                    bat_sections_read.append(section["header"]["section_number"])
                    bat_content += section["content"]

                    if len(bat_sections_read) == bat_sections_count:
                        break

        dvbreader.close(fd)

        service_count = 0
        transport_stream_id_list = []
        tmp_services_dict = {}

        for service in bat_content:
            if service["descriptor_tag"] != 0xD3:
                continue

            if service["region_id"] != region_id and service["region_id"] != 0xFFFF:
                continue

            service["service_type"] = 1
            service["free_ca"] = 1
            service["service_name"] = "Unknown"
            service["provider_name"] = "Unknown"
            service["namespace"] = namespace
            service["flags"] = 0

            key = "%x:%x:%x" % (service["transport_stream_id"], service["original_network_id"], service["service_id"])
            if key in tmp_services_dict:
                tmp_services_dict[key]["numbers"].append(service["number"])
            else:
                service["numbers"] = [service["number"]]
                tmp_services_dict[key] = service

            service_count += 1

            if service["transport_stream_id"] not in transport_stream_id_list:
                transport_stream_id_list.append(service["transport_stream_id"])

        for service in bat_content:
            if service["descriptor_tag"] != 0x41:
                continue

            if (
                service["service_type"] not in DvbScanner.VIDEO_ALLOWED_TYPES
                and service["service_type"] not in DvbScanner.AUDIO_ALLOWED_TYPES
                and service["service_type"] not in DvbScanner.INTERACTIVE_ALLOWED_TYPES
            ):
                continue

            if service["service_type"] == 0x05:
                service["service_type"] = 0x01
                # enigma2 doesn't like 0x05 VOD

            key = "%x:%x:%x" % (service["transport_stream_id"], service["original_network_id"], service["service_id"])
            if key in tmp_services_dict:
                tmp_services_dict[key]["service_type"] = service["service_type"]

        print >> log, "[DvbScanner] Read %d services with bouquet_id = 0x%x" % (service_count, bouquet_id)

        print >> log, "[DvbScanner] Reading services extra info..."

        if self.sdt_other_table_id == 0x00:
            mask = 0xFF
        else:
            mask = self.sdt_current_table_id ^ self.sdt_other_table_id ^ 0xFF

        fd = dvbreader.open(self.demuxer_device, self.sdt_pid, self.sdt_current_table_id, mask, self.frontend)
        if fd < 0:
            print >> log, "[DvbScanner] Cannot open the demuxer"
            return None

        sdt_secions_status = {}
        for transport_stream_id in transport_stream_id_list:
            sdt_secions_status[transport_stream_id] = {}
            sdt_secions_status[transport_stream_id]["section_version"] = -1
            sdt_secions_status[transport_stream_id]["sections_read"] = []
            sdt_secions_status[transport_stream_id]["sections_count"] = 0
            sdt_secions_status[transport_stream_id]["content"] = []

        timeout = datetime.datetime.now()
        timeout += datetime.timedelta(0, self.TIMEOUT_SEC)
        while True:
            if datetime.datetime.now() > timeout:
                print >> log, "[DvbScanner] Timed out"
                break

            section = dvbreader.read_sdt(fd, self.sdt_current_table_id, self.sdt_other_table_id)
            if section is None:
                time.sleep(0.1)  # no data.. so we wait a bit
                continue

            if (
                section["header"]["table_id"] == self.sdt_current_table_id
                or section["header"]["table_id"] == self.sdt_other_table_id
            ):
                if section["header"]["transport_stream_id"] not in transport_stream_id_list:
                    continue

                transport_stream_id = section["header"]["transport_stream_id"]
                if section["header"]["version_number"] != sdt_secions_status[transport_stream_id]["section_version"]:
                    sdt_secions_status[transport_stream_id]["section_version"] = section["header"]["version_number"]
                    sdt_secions_status[transport_stream_id]["sections_read"] = []
                    sdt_secions_status[transport_stream_id]["content"] = []
                    sdt_secions_status[transport_stream_id]["sections_count"] = (
                        section["header"]["last_section_number"] + 1
                    )

                if section["header"]["section_number"] not in sdt_secions_status[transport_stream_id]["sections_read"]:
                    sdt_secions_status[transport_stream_id]["sections_read"].append(section["header"]["section_number"])
                    sdt_secions_status[transport_stream_id]["content"] += section["content"]

                    if (
                        len(sdt_secions_status[transport_stream_id]["sections_read"])
                        == sdt_secions_status[transport_stream_id]["sections_count"]
                    ):
                        transport_stream_id_list.remove(transport_stream_id)

            if len(transport_stream_id_list) == 0:
                break

        if len(transport_stream_id_list) > 0:
            print >> log, "[DvbScanner] Cannot fetch SDT for the following transport_stream_id list: ", transport_stream_id_list

        dvbreader.close(fd)

        for key in sdt_secions_status:
            for section in sdt_secions_status[key]["content"]:
                srvkey = "%x:%x:%x" % (
                    section["transport_stream_id"],
                    section["original_network_id"],
                    section["service_id"],
                )

                if srvkey not in tmp_services_dict:
                    continue

                service = tmp_services_dict[srvkey]

                service["free_ca"] = section["free_ca"]
                service["service_name"] = section["service_name"]
                service["provider_name"] = section["provider_name"]

        video_services = {}
        radio_services = {}

        service_extra_count = 0

        for key in tmp_services_dict:
            service = tmp_services_dict[key]

            if len(servicehacks) > 0:
                skip = False
                exec (servicehacks)

                if skip:
                    continue

            tpkey = "%x:%x:%x" % (service["namespace"], service["transport_stream_id"], service["original_network_id"])
            if tpkey not in transponders:
                continue

            transponders[tpkey]["services"][service["service_id"]] = service
            service_extra_count += 1

            if (
                service["service_type"] in DvbScanner.VIDEO_ALLOWED_TYPES
                or service["service_type"] in DvbScanner.INTERACTIVE_ALLOWED_TYPES
            ):
                for number in service["numbers"]:
                    if service["region_id"] == 0xFFFF:
                        if number not in video_services:
                            video_services[number] = service
                    else:
                        video_services[number] = service
            else:
                for number in service["numbers"]:
                    if number not in radio_services:
                        radio_services[number] = service

        print >> log, "[DvbScanner] Read extra info for %d services" % service_extra_count
        return {"video": video_services, "radio": radio_services}
def readBouquet(bouquet_id):
	print "[DvbScanner] Reading bouquet_id = 0x%x..." % bouquet_id

	fd = dvbreader.open("/dev/dvb/adapter0/demux0", bat_pid, bat_table, mask, frontend)
	if fd < 0:
		print "[DvbScanner] Cannot open the demuxer"
		return None

	bat_section_version = -1
	bat_sections_read = []
	bat_sections_count = 0
	bat_content = []

	timeout = datetime.datetime.now()
	timeout += datetime.timedelta(0, TIMEOUT_SEC)
	while True:
		if datetime.datetime.now() > timeout:
			print "[DvbScanner] Timed out"
			break

		section = dvbreader.read_bat(fd, bat_table)
		if section is None:
			time.sleep(0.1)	# no data.. so we wait a bit
			continue

		if section["header"]["table_id"] == bat_table:
			if section["header"]["bouquet_id"] != bouquet_id:
				continue

			if section["header"]["version_number"] != bat_section_version:
				bat_section_version = section["header"]["version_number"]
				bat_sections_read = []
				bat_content = []
				bat_sections_count = section["header"]["last_section_number"] + 1

			if section["header"]["section_number"] not in bat_sections_read:
				bat_sections_read.append(section["header"]["section_number"])
				bat_content += section["content"]

				if len(bat_sections_read) == bat_sections_count:
					break

	dvbreader.close(fd)

	bouquet_name = None
	for section in bat_content:
		if section["descriptor_tag"] == 0x47:
			bouquet_name = section["description"]
			break

	if bouquet_name is None:
		print "[DvbScanner] Canno get bouquet name for bouquet_id = 0x%x" % bouquet_id
		return

	for section in bat_content:
		if section["descriptor_tag"] == 0xd4:
			bouquet = {
				"name": bouquet_name + " - " + section["description"],
				"region": section["region_id"],
				"bouquet": bouquet_id
			}
			bouquets_list.append(bouquet)

	print "[DvbScanner] Done"
示例#4
0
	def updateAndReadServicesFreeSat(self, bouquet_id, region_id, namespace, transponders, servicehacks):
		print>>log, "[DvbScanner] Reading services..."

		fd = dvbreader.open(self.demuxer_device, self.bat_pid, self.bat_table_id, 0xff, self.frontend)
		if fd < 0:
			print>>log, "[DvbScanner] Cannot open the demuxer"
			return None

		bat_section_version = -1
		bat_sections_read = []
		bat_sections_count = 0
		bat_content = []

		timeout = datetime.datetime.now()
		timeout += datetime.timedelta(0, self.TIMEOUT_SEC)
		while True:
			if datetime.datetime.now() > timeout:
				print>>log, "[DvbScanner] Timed out"
				break

			section = dvbreader.read_bat(fd, self.bat_table_id)
			if section is None:
				time.sleep(0.1)	# no data.. so we wait a bit
				continue

			if section["header"]["table_id"] == self.bat_table_id:
				if section["header"]["bouquet_id"] != bouquet_id:
					continue

				if section["header"]["version_number"] != bat_section_version:
					bat_section_version = section["header"]["version_number"]
					bat_sections_read = []
					bat_content = []
					bat_sections_count = section["header"]["last_section_number"] + 1

				if section["header"]["section_number"] not in bat_sections_read:
					bat_sections_read.append(section["header"]["section_number"])
					bat_content += section["content"]

					if len(bat_sections_read) == bat_sections_count:
						break

		dvbreader.close(fd)

		service_count = 0
		transport_stream_id_list = []
		tmp_services_dict = {}
		
		for service in bat_content:
			if service["descriptor_tag"] != 0xd3:
				continue
				
			if service["region_id"] != region_id and service["region_id"] != 0xffff:
				continue

			service["service_type"] = 1
			service["free_ca"] = 1
			service["service_name"] = "Unknown"
			service["provider_name"] = "Unknown"
			service["namespace"] = namespace
			service["flags"] = 0
			
			key = "%x:%x:%x" % (service["transport_stream_id"], service["original_network_id"], service["service_id"])
			if key in tmp_services_dict:
				tmp_services_dict[key]["numbers"].append(service["number"])
			else:
				service["numbers"] = [service["number"]]
				tmp_services_dict[key] = service

			service_count += 1

			if service["transport_stream_id"] not in transport_stream_id_list:
				transport_stream_id_list.append(service["transport_stream_id"])

		for service in bat_content:
			if service["descriptor_tag"] != 0x41:
				continue
				
			if service["service_type"] not in DvbScanner.VIDEO_ALLOWED_TYPES and service["service_type"] not in DvbScanner.AUDIO_ALLOWED_TYPES and service["service_type"] not in DvbScanner.INTERACTIVE_ALLOWED_TYPES:
				continue

			if service["service_type"] == 0x05:
				service["service_type"] = 0x01;		# enigma2 doesn't like 0x05 VOD

			key = "%x:%x:%x" % (service["transport_stream_id"], service["original_network_id"], service["service_id"])
			if key in tmp_services_dict:
				tmp_services_dict[key]["service_type"] = service["service_type"]
		
		print>>log, "[DvbScanner] Read %d services with bouquet_id = 0x%x" % (service_count, bouquet_id)
		
		print>>log, "[DvbScanner] Reading services extra info..."

		#Clear double LCN values
		tmp_numbers =[]
		tmp_double_numbers = []
		for key in tmp_services_dict:
			if len(tmp_services_dict[key]["numbers"]) > 1:
				if tmp_services_dict[key]["numbers"][0] not in tmp_numbers:
					tmp_numbers.append (tmp_services_dict[key]["numbers"][0])
				else:
					tmp_double_numbers.append (tmp_services_dict[key]["numbers"][0])
				if tmp_services_dict[key]["numbers"][1] not in tmp_numbers:
					tmp_numbers.append (tmp_services_dict[key]["numbers"][1])
				else:
					tmp_double_numbers.append (tmp_services_dict[key]["numbers"][1])
		for key in tmp_services_dict:
			if len(tmp_services_dict[key]["numbers"]) > 1:	
				if tmp_services_dict[key]["numbers"][0] in tmp_double_numbers:
					print>>log, "[DvbScanner] Deleted double LCN: %d" % (tmp_services_dict[key]["numbers"][0])
					del tmp_services_dict[key]["numbers"][0]
				
		if self.sdt_other_table_id == 0x00:
			mask = 0xff
		else:
			mask = self.sdt_current_table_id ^ self.sdt_other_table_id ^ 0xff

		fd = dvbreader.open(self.demuxer_device, self.sdt_pid, self.sdt_current_table_id, mask, self.frontend)
		if fd < 0:
			print>>log, "[DvbScanner] Cannot open the demuxer"
			return None

		sdt_secions_status = {}
		for transport_stream_id in transport_stream_id_list:
			sdt_secions_status[transport_stream_id] = {}
			sdt_secions_status[transport_stream_id]["section_version"] = -1
			sdt_secions_status[transport_stream_id]["sections_read"] = []
			sdt_secions_status[transport_stream_id]["sections_count"] = 0
			sdt_secions_status[transport_stream_id]["content"] = []

		timeout = datetime.datetime.now()
		timeout += datetime.timedelta(0, self.TIMEOUT_SEC)
		while True:
			if datetime.datetime.now() > timeout:
				print>>log, "[DvbScanner] Timed out"
				break

			section = dvbreader.read_sdt(fd, self.sdt_current_table_id, self.sdt_other_table_id)
			if section is None:
				time.sleep(0.1)	# no data.. so we wait a bit
				continue

			if section["header"]["table_id"] == self.sdt_current_table_id or section["header"]["table_id"] == self.sdt_other_table_id:
				if section["header"]["transport_stream_id"] not in transport_stream_id_list:
					continue

				transport_stream_id = section["header"]["transport_stream_id"]
				if section["header"]["version_number"] != sdt_secions_status[transport_stream_id]["section_version"]:
					sdt_secions_status[transport_stream_id]["section_version"] = section["header"]["version_number"]
					sdt_secions_status[transport_stream_id]["sections_read"] = []
					sdt_secions_status[transport_stream_id]["content"] = []
					sdt_secions_status[transport_stream_id]["sections_count"] = section["header"]["last_section_number"] + 1

				if section["header"]["section_number"] not in sdt_secions_status[transport_stream_id]["sections_read"]:
					sdt_secions_status[transport_stream_id]["sections_read"].append(section["header"]["section_number"])
					sdt_secions_status[transport_stream_id]["content"] += section["content"]

					if len(sdt_secions_status[transport_stream_id]["sections_read"]) == sdt_secions_status[transport_stream_id]["sections_count"]:
						transport_stream_id_list.remove(transport_stream_id)

			if len(transport_stream_id_list) == 0:
				break

		if len(transport_stream_id_list) > 0:
			print>>log, "[DvbScanner] Cannot fetch SDT for the following transport_stream_id list: ", transport_stream_id_list

		dvbreader.close(fd)

		for key in sdt_secions_status:
			for section in sdt_secions_status[key]["content"]:
				srvkey = "%x:%x:%x" % (section["transport_stream_id"], section["original_network_id"], section["service_id"])

				if srvkey not in tmp_services_dict:
					continue

				service = tmp_services_dict[srvkey]

				service["free_ca"] = section["free_ca"]
				service["service_name"] = section["service_name"]
				service["provider_name"] = section["provider_name"]

		video_services = {}
		radio_services = {}

		service_extra_count = 0

		for key in tmp_services_dict:
			service = tmp_services_dict[key]

			if len(servicehacks) > 0:
				skip = False
				exec(servicehacks)

				if skip:
					continue

			tpkey = "%x:%x:%x" % (service["namespace"], service["transport_stream_id"], service["original_network_id"])
			if tpkey not in transponders:
				continue


			transponders[tpkey]["services"][service["service_id"]] = service
			service_extra_count += 1

			if service["service_type"] in DvbScanner.VIDEO_ALLOWED_TYPES or service["service_type"] in DvbScanner.INTERACTIVE_ALLOWED_TYPES:
				for number in service["numbers"]:
					if service["region_id"] == 0xffff:
						if number not in video_services:
							video_services[number] = service
					else:
						video_services[number] = service
			else:
				for number in service["numbers"]:
					if number not in radio_services:
						radio_services[number] = service


		print>>log, "[DvbScanner] Read extra info for %d services" % service_extra_count
		return {
			"video": video_services,
			"radio": radio_services
		}
示例#5
0
	def updateAndReadServicesFreeSat(self, bouquet_id, region_id, namespace, bouquet_key, transponders, servicehacks):
		print>>log, "[DvbScanner] Reading services..."

		fd = dvbreader.open(self.demuxer_device, self.bat_pid, self.bat_table_id, 0xff, self.frontend)
		if fd < 0:
			print>>log, "[DvbScanner] Cannot open the demuxer"
			return None

		bat_section_version = -1
		bat_sections_read = []
		bat_sections_count = 0
		bat_content = []

		timeout = datetime.datetime.now()
		timeout += datetime.timedelta(0, self.TIMEOUT_SEC)
		transport_stream_id_list = []
		while True:
			if datetime.datetime.now() > timeout:
				print>>log, "[DvbScanner] Timed out"
				break

			section = dvbreader.read_bat(fd, self.bat_table_id)
			if section is None:
				time.sleep(0.1)	# no data.. so we wait a bit
				continue

			if section["header"]["table_id"] == self.bat_table_id:
				if section["header"]["bouquet_id"] != bouquet_id:
					if config.autobouquetsmaker.showextraservices.value:
						for content_tmp in section["content"]:
							if content_tmp["descriptor_tag"] == 0xd3 and content_tmp["transport_stream_id"] not in transport_stream_id_list:
								transport_stream_id_list.append(content_tmp["transport_stream_id"])
					continue

				if section["header"]["version_number"] != bat_section_version:
					bat_section_version = section["header"]["version_number"]
					bat_sections_read = []
					bat_content = []
					bat_sections_count = section["header"]["last_section_number"] + 1

				if section["header"]["section_number"] not in bat_sections_read:
					bat_sections_read.append(section["header"]["section_number"])
					bat_content += section["content"]

					if len(bat_sections_read) == bat_sections_count:
						break

		dvbreader.close(fd)

		service_count = 0
		tmp_services_dict = {}

		for service in bat_content:
			if service["descriptor_tag"] != 0xd3:
				continue

			if service["transport_stream_id"] not in transport_stream_id_list:
				transport_stream_id_list.append(service["transport_stream_id"])

			if service["region_id"] != region_id and service["region_id"] != 0xffff:
				continue

			service["service_type"] = 1
			service["free_ca"] = 1
			service["service_name"] = "Unknown"
			service["provider_name"] = "Unknown"
			service["namespace"] = namespace
			service["flags"] = 0

			key = "%x:%x:%x" % (service["transport_stream_id"], service["original_network_id"], service["service_id"])
			if key in tmp_services_dict:
				tmp_services_dict[key]["numbers"].append(service["number"])
			else:
				service["numbers"] = [service["number"]]
				tmp_services_dict[key] = service

			service_count += 1

		for service in bat_content:
			if service["descriptor_tag"] != 0x41:
				continue

			if service["service_type"] not in DvbScanner.VIDEO_ALLOWED_TYPES and service["service_type"] not in DvbScanner.AUDIO_ALLOWED_TYPES and service["service_type"] not in DvbScanner.INTERACTIVE_ALLOWED_TYPES:
				continue

			if service["service_type"] == 0x05:
				service["service_type"] = 0x01;		# enigma2 doesn't like 0x05 VOD

			key = "%x:%x:%x" % (service["transport_stream_id"], service["original_network_id"], service["service_id"])
			if key in tmp_services_dict:
				tmp_services_dict[key]["service_type"] = service["service_type"]

		print>>log, "[DvbScanner] Read %d services with bouquet_id = 0x%x" % (service_count, bouquet_id)

		print>>log, "[DvbScanner] Reading services extra info..."

		#Clear double LCN values
		tmp_numbers =[]
		tmp_double_numbers = []
		for key in tmp_services_dict:
			if len(tmp_services_dict[key]["numbers"]) > 1:
				if tmp_services_dict[key]["numbers"][0] not in tmp_numbers:
					tmp_numbers.append (tmp_services_dict[key]["numbers"][0])
				else:
					tmp_double_numbers.append (tmp_services_dict[key]["numbers"][0])
				if tmp_services_dict[key]["numbers"][1] not in tmp_numbers:
					tmp_numbers.append (tmp_services_dict[key]["numbers"][1])
				else:
					tmp_double_numbers.append (tmp_services_dict[key]["numbers"][1])
		for key in tmp_services_dict:
			if len(tmp_services_dict[key]["numbers"]) > 1:
				if tmp_services_dict[key]["numbers"][0] in tmp_double_numbers:
					print>>log, "[DvbScanner] Deleted double LCN: %d" % (tmp_services_dict[key]["numbers"][0])
					del tmp_services_dict[key]["numbers"][0]

		#remove other duplicates (single and dual LCN values)
		tmp_numbers =[]
		for key in tmp_services_dict:
			if tmp_services_dict[key]["region_id"] != 0xffff:
				for number in tmp_services_dict[key]["numbers"]:
					tmp_numbers.append(number)
		for key in tmp_services_dict.keys():
			if tmp_services_dict[key]["region_id"] == 0xffff:
				for number in tmp_services_dict[key]["numbers"]:
					if number in tmp_numbers:
						del tmp_services_dict[key]["numbers"][tmp_services_dict[key]["numbers"].index(number)]
				if len(tmp_services_dict[key]["numbers"]) == 0:
					del tmp_services_dict[key]

		if self.sdt_other_table_id == 0x00:
			mask = 0xff
		else:
			mask = self.sdt_current_table_id ^ self.sdt_other_table_id ^ 0xff

		fd = dvbreader.open(self.demuxer_device, self.sdt_pid, self.sdt_current_table_id, mask, self.frontend)
		if fd < 0:
			print>>log, "[DvbScanner] Cannot open the demuxer"
			return None

		sdt_secions_status = {}
		for transport_stream_id in transport_stream_id_list:
			sdt_secions_status[transport_stream_id] = {}
			sdt_secions_status[transport_stream_id]["section_version"] = -1
			sdt_secions_status[transport_stream_id]["sections_read"] = []
			sdt_secions_status[transport_stream_id]["sections_count"] = 0
			sdt_secions_status[transport_stream_id]["content"] = []

		timeout = datetime.datetime.now()
		timeout += datetime.timedelta(0, self.SDT_TIMEOUT)
		while True:
			if datetime.datetime.now() > timeout:
				print>>log, "[DvbScanner] Timed out"
				break

			section = dvbreader.read_sdt(fd, self.sdt_current_table_id, self.sdt_other_table_id)
			if section is None:
				time.sleep(0.1)	# no data.. so we wait a bit
				continue

			if section["header"]["table_id"] == self.sdt_current_table_id or section["header"]["table_id"] == self.sdt_other_table_id:
				if section["header"]["transport_stream_id"] not in transport_stream_id_list:
					continue

				transport_stream_id = section["header"]["transport_stream_id"]
				if section["header"]["version_number"] != sdt_secions_status[transport_stream_id]["section_version"]:
					sdt_secions_status[transport_stream_id]["section_version"] = section["header"]["version_number"]
					sdt_secions_status[transport_stream_id]["sections_read"] = []
					sdt_secions_status[transport_stream_id]["content"] = []
					sdt_secions_status[transport_stream_id]["sections_count"] = section["header"]["last_section_number"] + 1

				if section["header"]["section_number"] not in sdt_secions_status[transport_stream_id]["sections_read"]:
					sdt_secions_status[transport_stream_id]["sections_read"].append(section["header"]["section_number"])
					sdt_secions_status[transport_stream_id]["content"] += section["content"]

					if len(sdt_secions_status[transport_stream_id]["sections_read"]) == sdt_secions_status[transport_stream_id]["sections_count"]:
						transport_stream_id_list.remove(transport_stream_id)

			if len(transport_stream_id_list) == 0:
				break

		if len(transport_stream_id_list) > 0:
			print>>log, "[DvbScanner] Cannot fetch SDT for the following transport_stream_id list: ", transport_stream_id_list

		dvbreader.close(fd)

		extras = []

		for key in sdt_secions_status:
			for section in sdt_secions_status[key]["content"]:
				srvkey = "%x:%x:%x" % (section["transport_stream_id"], section["original_network_id"], section["service_id"])

				if srvkey not in tmp_services_dict:
					if config.autobouquetsmaker.showextraservices.value:
						extras.append(section)
					continue

				service = tmp_services_dict[srvkey]

				service["free_ca"] = section["free_ca"]
				service["service_name"] = section["service_name"]
				service["provider_name"] = section["provider_name"]

		video_services = {}
		radio_services = {}

		service_extra_count = 0

		tmp_services_dict, LCNs_in_use = self.extrasHelper(tmp_services_dict, extras, namespace, False)

		for key in self.LCN_order(tmp_services_dict):
			service = tmp_services_dict[key]

			if len(servicehacks) > 0:
				skip = False
				exec(servicehacks)

				if skip:
					continue

			tpkey = "%x:%x:%x" % (service["namespace"], service["transport_stream_id"], service["original_network_id"])
			if tpkey not in transponders:
				continue


			transponders[tpkey]["services"][service["service_id"]] = service
			service_extra_count += 1

			if service["service_type"] in DvbScanner.VIDEO_ALLOWED_TYPES or service["service_type"] in DvbScanner.INTERACTIVE_ALLOWED_TYPES:
				for number in service["numbers"]:
					if service["region_id"] == 0xffff:
						if number not in video_services:
							video_services[number] = service
					else:
						video_services[number] = service
			else:
				for number in service["numbers"]:
					if number not in radio_services:
						radio_services[number] = service


		print>>log, "[DvbScanner] Read extra info for %d services" % service_extra_count
		return {
			"video": video_services,
			"radio": radio_services
		}